Skip to content

Commit e12f81b

Browse files
authored
Use :NaN for Decimal encoding (#136)
The Decimal module documents the use of :inf and :NaN but not :qNaN or :sNaN. It refers to :NaN as being a quiet NaN. Signalling NaNs are generally expected to trigger an error at the hardware level and then handled by being converted to a quite NaN if execution should continue.
1 parent 4080160 commit e12f81b

File tree

3 files changed

+7
-27
lines changed

3 files changed

+7
-27
lines changed

lib/bson/decimal128.ex

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ defmodule BSON.Decimal128 do
1313
@exponent_bias 6176
1414
@max_exponent 6111
1515
@min_exponent -6176
16-
@s_nan_mask 0x1 <<< 57
1716
@significand_mask (0x1 <<< 49) - 1
1817
@low_mask 0xFFFFFFFFFFFFFFFF
1918

@@ -22,14 +21,7 @@ defmodule BSON.Decimal128 do
2221
combination = high >>> 58 &&& @combination_mask
2322
two_highest_bits_set = combination >>> 3 == 3
2423
is_infinity = two_highest_bits_set && combination == @combintation_infinity
25-
26-
is_nan =
27-
case {(two_highest_bits_set && combination) == @combintation_nan, (high &&& @s_nan_mask) == @s_nan_mask} do
28-
{true, true} -> :sNan
29-
{true, false} -> :qNan
30-
_ -> false
31-
end
32-
24+
is_nan = two_highest_bits_set && combination == @combintation_nan
3325
exponent = exponent(high, two_highest_bits_set)
3426

3527
value(
@@ -56,18 +48,12 @@ defmodule BSON.Decimal128 do
5648
<<low::little-64, high::little-64>>
5749
end
5850

59-
def encode(%Decimal{coef: :qNaN}) do
51+
def encode(%Decimal{coef: :NaN}) do
6052
low = 0
6153
high = 0x1F <<< 58
6254
<<low::little-64, high::little-64>>
6355
end
6456

65-
def encode(%Decimal{coef: :sNaN}) do
66-
low = 0
67-
high = 0x3F <<< 57
68-
<<low::little-64, high::little-64>>
69-
end
70-
7157
def encode(%Decimal{sign: sign, coef: significand, exp: exponent}) when exponent >= @min_exponent and exponent <= @max_exponent do
7258
biased_exponent = exponent + @exponent_bias
7359
low = significand &&& @low_mask
@@ -107,12 +93,8 @@ defmodule BSON.Decimal128 do
10793
%Decimal{coef: :inf}
10894
end
10995

110-
defp value(%{is_nan: :qNan}, _, _) do
111-
%Decimal{coef: :qNaN}
112-
end
113-
114-
defp value(%{is_nan: :sNan}, _, _) do
115-
%Decimal{coef: :sNaN}
96+
defp value(%{is_nan: true}, _, _) do
97+
%Decimal{coef: :NaN}
11698
end
11799

118100
defp value(%{two_highest_bits_set: true}, _, _) do

test/bson/decimal128_test.exs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ defmodule BSON.Decimal128Test do
1818

1919
@tag :mongo_3_4
2020
test "BSON.Decimal128.decode/1" do
21-
assert_decimal(@nan_binaries, %Decimal{coef: :qNaN})
21+
assert_decimal(@nan_binaries, %Decimal{coef: :NaN})
2222
assert_decimal(@inf_binaries, %Decimal{coef: :inf})
2323
assert_decimal(@neg_inf_binaries, %Decimal{sign: -1, coef: :inf})
2424
assert_decimal(@binaries_0, %Decimal{coef: 0})
@@ -45,8 +45,7 @@ defmodule BSON.Decimal128Test do
4545

4646
@tag :mongo_3_4
4747
test "BSON.Decimal128.encode/1" do
48-
assert_decimal(%Decimal{coef: :qNaN})
49-
assert_decimal(%Decimal{coef: :sNaN})
48+
assert_decimal(%Decimal{coef: :NaN})
5049
assert_decimal(%Decimal{sign: -1, coef: :inf})
5150
assert_decimal(%Decimal{coef: :inf})
5251
assert_decimal(%Decimal{coef: 0, exp: -611})

test/mongo_test.exs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -537,8 +537,7 @@ defmodule Mongo.Test do
537537

538538
values =
539539
[
540-
%Decimal{coef: :qNaN},
541-
%Decimal{coef: :sNaN},
540+
%Decimal{coef: :NaN},
542541
%Decimal{sign: -1, coef: :inf},
543542
%Decimal{coef: :inf},
544543
%Decimal{coef: 0, exp: -611},

0 commit comments

Comments
 (0)