summaryrefslogtreecommitdiff
path: root/t/opbasic
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2013-12-02 15:04:49 +0000
committerDavid Mitchell <davem@iabyn.com>2013-12-25 21:40:32 +0000
commitb27804d8b48d647c08dc853b49e5b311fe166616 (patch)
tree8ba60a501056223f70bc9dfffa54c8f8752750c4 /t/opbasic
parentba0f5503397ddc65667224047f121adc8b44784c (diff)
downloadperl-b27804d8b48d647c08dc853b49e5b311fe166616.tar.gz
[perl #120426] atof() small value rounding errors
For something like 0.153e-305, which is small, but not quite the smallest number (which is around 2.2e-308), adding extra digits to the fractional part could cause unnecessary rounding to zero. From the bug report: $ echo 0.1530e-305 | perl -e '$v = <STDIN>; print "v=", $v + 0, "\n";' v=0 $ echo 0.153e-305 | perl -e '$v = <STDIN>; print "v=", $v + 0, "\n";' v=1.53e-306 This was because 0.1234e-305 is calculated as 1234 / (10^309) and 10^309 becomes infinity. In these edge cases, repeatedly decrement the exponent and divide the mantissa by 10 until the exponent becomes in range; in this case we instead calculate 123 / (10^308)
Diffstat (limited to 't/opbasic')
-rw-r--r--t/opbasic/arith.t14
1 files changed, 13 insertions, 1 deletions
diff --git a/t/opbasic/arith.t b/t/opbasic/arith.t
index d85a9ba214..a90e84c071 100644
--- a/t/opbasic/arith.t
+++ b/t/opbasic/arith.t
@@ -9,7 +9,7 @@ BEGIN {
# functions imported from t/test.pl or Test::More, as those programs/libraries
# use operators which are what is being tested in this file.
-print "1..167\n";
+print "1..175\n";
sub try ($$$) {
print +($_[1] ? "ok" : "not ok"), " $_[0] - $_[2]\n";
@@ -456,3 +456,15 @@ else {
print "ok ", $T++, " - infinity\n";
}
+
+# [perl #120426]
+# small numbers shouldn't round to zero if they have extra floating digits
+
+try $T++, 0.153e-305 != 0.0, '0.153e-305';
+try $T++, 0.1530e-305 != 0.0, '0.1530e-305';
+try $T++, 0.15300e-305 != 0.0, '0.15300e-305';
+try $T++, 0.153000e-305 != 0.0, '0.153000e-305';
+try $T++, 0.1530000e-305 != 0.0, '0.1530000e-305';
+try $T++, 0.1530001e-305 != 0.0, '0.1530001e-305';
+try $T++, 1.17549435100e-38 != 0.0, 'min single';
+try $T++, 2.2250738585072014e-308 != 0.0, 'min double';