diff options
author | Patrik Nyblom <[email protected]> | 2010-06-08 09:59:30 +0200 |
---|---|---|
committer | Patrik Nyblom <[email protected]> | 2010-06-23 14:50:10 +0200 |
commit | 01749000e1cdd379df0cbaefb5b49c27f2c496e9 (patch) | |
tree | 9702f0205261e62dd261ec17beb6b3363c8f424f /erts/emulator | |
parent | c1e94fa9a6fe4ae717d35dfbd1b628dc2e06d26a (diff) | |
download | otp-01749000e1cdd379df0cbaefb5b49c27f2c496e9.tar.gz otp-01749000e1cdd379df0cbaefb5b49c27f2c496e9.tar.bz2 otp-01749000e1cdd379df0cbaefb5b49c27f2c496e9.zip |
Teach Unix sys_float.c to ignore underflow in list_to_float and return 0.0
OTP-7178
Diffstat (limited to 'erts/emulator')
-rw-r--r-- | erts/emulator/sys/unix/sys_float.c | 13 | ||||
-rw-r--r-- | erts/emulator/test/float_SUITE.erl | 29 |
2 files changed, 38 insertions, 4 deletions
diff --git a/erts/emulator/sys/unix/sys_float.c b/erts/emulator/sys/unix/sys_float.c index c59c99f65e..0a27b4cafb 100644 --- a/erts/emulator/sys/unix/sys_float.c +++ b/erts/emulator/sys/unix/sys_float.c @@ -799,8 +799,17 @@ sys_chars_to_double(char* buf, double* fp) } #ifdef NO_FPE_SIGNALS - if (errno == ERANGE && (*fp == 0.0 || *fp == HUGE_VAL || *fp == -HUGE_VAL)) { - return -1; + if (errno == ERANGE) { + if (*fp == HUGE_VAL || *fp == -HUGE_VAL) { + /* overflow, should give error */ + return -1; + } else if (t == s && *fp == 0.0) { + /* This should give 0.0 - OTP-7178 */ + errno = 0; + + } else if (*fp == 0.0) { + return -1; + } } #endif return 0; diff --git a/erts/emulator/test/float_SUITE.erl b/erts/emulator/test/float_SUITE.erl index 102e472ea6..99e9457985 100644 --- a/erts/emulator/test/float_SUITE.erl +++ b/erts/emulator/test/float_SUITE.erl @@ -22,7 +22,10 @@ -include("test_server.hrl"). -export([all/1,init_per_testcase/2,fin_per_testcase/2, - fpe/1,fp_drv/1,fp_drv_thread/1,denormalized/1,match/1,bad_float_unpack/1]). + fpe/1,fp_drv/1,fp_drv_thread/1,denormalized/1,match/1, + bad_float_unpack/1]). +-export([otp_7178/1]). + init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) -> Dog = ?t:timetrap(?t:minutes(3)), @@ -33,7 +36,29 @@ fin_per_testcase(_Func, Config) -> ?t:timetrap_cancel(Dog). all(suite) -> - [fpe,fp_drv,fp_drv_thread,denormalized,match,bad_float_unpack]. + [fpe, + fp_drv, + fp_drv_thread, + otp_7178, + denormalized, + match, + bad_float_unpack]. + +%% +%% OTP-7178, list_to_float on very small numbers should give 0.0 +%% instead of exception, i.e. ignore underflow. +%% +otp_7178(suite) -> + []; +otp_7178(doc) -> + ["test that list_to_float on very small numbers give 0.0"]; +otp_7178(Config) when is_list(Config) -> + ?line X = list_to_float("1.0e-325"), + ?line true = (X < 0.00000001) and (X > -0.00000001), + ?line Y = list_to_float("1.0e-325325325"), + ?line true = (Y < 0.00000001) and (Y > -0.00000001), + ?line {'EXIT', {badarg,_}} = (catch list_to_float("1.0e83291083210")), + ok. %% Forces floating point exceptions and tests that subsequent, legal, %% operations are calculated correctly. Original version by Sebastian |