diff options
author | Johannes Weißl <[email protected]> | 2013-06-14 15:23:59 +0200 |
---|---|---|
committer | Johannes Weißl <[email protected]> | 2013-06-14 15:25:12 +0200 |
commit | 5adbd7d22bccc57e17ed00cac09fe8a336bb39c7 (patch) | |
tree | bd7bd69c78661b96840b97e9b03febfb9e555325 | |
parent | 29465408c90b2271b68e9559b5482fc6c4fcdde5 (diff) | |
download | otp-5adbd7d22bccc57e17ed00cac09fe8a336bb39c7.tar.gz otp-5adbd7d22bccc57e17ed00cac09fe8a336bb39c7.tar.bz2 otp-5adbd7d22bccc57e17ed00cac09fe8a336bb39c7.zip |
Fix binary matching on floating point middle-endian machines
This complements 933e701 (OTP-10209). Without this patch the test case
"bs_match_misc_SUITE:t_float/1" fails.
Simple error example:
1> <<_,_,_,_,_,_,_,_>> = <<1.25/float>>.
<<63,244,0,0,0,0,0,0>>
2> <<1.25/float>> = <<63,244,0,0,0,0,0,0>>.
** exception error: no match of right hand side value <<63,244,0,0,0,0,0,0>>
The additional test case is added because in a former version of this
patch the ERTS_FP_ERROR_THOROUGH check for NaN/infinity was mistakenly
applied on the still word-switched double.
-rw-r--r-- | erts/emulator/beam/erl_bits.c | 8 | ||||
-rw-r--r-- | erts/emulator/test/bs_match_misc_SUITE.erl | 12 | ||||
-rw-r--r-- | lib/debugger/test/bs_match_misc_SUITE.erl | 11 |
3 files changed, 27 insertions, 4 deletions
diff --git a/erts/emulator/beam/erl_bits.c b/erts/emulator/beam/erl_bits.c index 3753b618e1..06d53efb5e 100644 --- a/erts/emulator/beam/erl_bits.c +++ b/erts/emulator/beam/erl_bits.c @@ -484,8 +484,16 @@ erts_bs_get_float_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuffer ERTS_FP_ERROR_THOROUGH(p, f32, return THE_NON_VALUE); f.fd = f32; } else { +#ifdef DOUBLE_MIDDLE_ENDIAN + FloatDef ftmp; + ftmp.fd = f64; + f.fw[0] = ftmp.fw[1]; + f.fw[1] = ftmp.fw[0]; + ERTS_FP_ERROR_THOROUGH(p, f.fd, return THE_NON_VALUE); +#else ERTS_FP_ERROR_THOROUGH(p, f64, return THE_NON_VALUE); f.fd = f64; +#endif } mb->offset += num_bits; hp = HeapOnlyAlloc(p, FLOAT_SIZE_OBJECT); diff --git a/erts/emulator/test/bs_match_misc_SUITE.erl b/erts/emulator/test/bs_match_misc_SUITE.erl index 15427661f3..b0904acbe9 100644 --- a/erts/emulator/test/bs_match_misc_SUITE.erl +++ b/erts/emulator/test/bs_match_misc_SUITE.erl @@ -23,7 +23,8 @@ bound_var/1,bound_tail/1,t_float/1,little_float/1,sean/1, kenneth/1,encode_binary/1,native/1,happi/1, size_var/1,wiger/1,x0_context/1,huge_float_field/1, - writable_binary_matched/1,otp_7198/1,unordered_bindings/1]). + writable_binary_matched/1,otp_7198/1,unordered_bindings/1, + float_middle_endian/1]). -include_lib("test_server/include/test_server.hrl"). @@ -33,7 +34,7 @@ all() -> [bound_var, bound_tail, t_float, little_float, sean, kenneth, encode_binary, native, happi, size_var, wiger, x0_context, huge_float_field, writable_binary_matched, - otp_7198, unordered_bindings]. + otp_7198, unordered_bindings, float_middle_endian]. groups() -> []. @@ -92,6 +93,13 @@ t_float(Config) when is_list(Config) -> ok. +float_middle_endian(Config) when is_list(Config) -> + F = 9007199254740990.0, % turns to -NaN when word-swapped + ?line fcmp(F, match_float(<<F:64/float>>, 64, 0)), + ?line fcmp(F, match_float(<<1:1,F:64/float,127:7>>, 64, 1)), + ?line fcmp(F, match_float(<<1:13,F:64/float,127:3>>, 64, 13)), + ok. + fcmp(F1, F2) when (F1 - F2) / F2 < 0.0000001 -> ok. diff --git a/lib/debugger/test/bs_match_misc_SUITE.erl b/lib/debugger/test/bs_match_misc_SUITE.erl index 6b66c45448..54fa9a59df 100644 --- a/lib/debugger/test/bs_match_misc_SUITE.erl +++ b/lib/debugger/test/bs_match_misc_SUITE.erl @@ -26,7 +26,7 @@ kenneth/1,encode_binary/1,native/1,happi/1, size_var/1,wiger/1,x0_context/1,huge_float_field/1, writable_binary_matched/1,otp_7198/1, - unordered_bindings/1]). + unordered_bindings/1,float_middle_endian/1]). -include_lib("test_server/include/test_server.hrl"). @@ -36,7 +36,7 @@ all() -> [bound_var, bound_tail, t_float, little_float, sean, kenneth, encode_binary, native, happi, size_var, wiger, x0_context, huge_float_field, writable_binary_matched, - otp_7198, unordered_bindings]. + otp_7198, unordered_bindings, float_middle_endian]. groups() -> []. @@ -106,6 +106,13 @@ t_float(Config) when is_list(Config) -> ok. +float_middle_endian(Config) when is_list(Config) -> + F = 9007199254740990.0, % turns to -NaN when word-swapped + ?line fcmp(F, match_float(<<F:64/float>>, 64, 0)), + ?line fcmp(F, match_float(<<1:1,F:64/float,127:7>>, 64, 1)), + ?line fcmp(F, match_float(<<1:13,F:64/float,127:3>>, 64, 13)), + ok. + fcmp(F1, F2) when (F1 - F2) / F2 < 0.0000001 -> ok. |