[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [bug-gawk] gawk erroneous comparison with large negative exponents
From: |
Andrew J. Schorr |
Subject: |
Re: [bug-gawk] gawk erroneous comparison with large negative exponents |
Date: |
Mon, 13 Apr 2015 22:51:58 -0400 |
User-agent: |
Mutt/1.5.23 (2014-03-12) |
Hi,
On Mon, Apr 13, 2015 at 10:40:21AM +0300, Aharon Robbins wrote:
> Ultimately, gawk relies on the C library strtod() function to convert
> a string value to a number, and since an exponent of -308 is out of
> range, strtod() fails to do. Thus, gawk treats 1e-308 as a string and
> does a string comparison to 0.5. This fails.
It's interesting, and perhaps a bit confusing, that the strtod call
actually returns the subnormal value and sets errno to ERANGE. As a result,
gawk decides that the string is not numeric, but the NODE's numeric value is
actually populated with the subnormal value:
bash-4.2$ for i in `seq 305 330` ; do echo 1.0e-$i; done | gawk 'BEGIN {c =
0.5} {printf "%s < %g = %d; %s -> %.10g\n", $1, c, ($1 < c), $1, $1}'
1.0e-305 < 0.5 = 1; 1.0e-305 -> 1e-305
1.0e-306 < 0.5 = 1; 1.0e-306 -> 1e-306
1.0e-307 < 0.5 = 1; 1.0e-307 -> 1e-307
1.0e-308 < 0.5 = 0; 1.0e-308 -> 1e-308
1.0e-309 < 0.5 = 0; 1.0e-309 -> 1e-309
1.0e-310 < 0.5 = 0; 1.0e-310 -> 1e-310
1.0e-311 < 0.5 = 0; 1.0e-311 -> 1e-311
1.0e-312 < 0.5 = 0; 1.0e-312 -> 1e-312
1.0e-313 < 0.5 = 0; 1.0e-313 -> 1e-313
1.0e-314 < 0.5 = 0; 1.0e-314 -> 1e-314
1.0e-315 < 0.5 = 0; 1.0e-315 -> 9.999999985e-316
1.0e-316 < 0.5 = 0; 1.0e-316 -> 9.999999837e-317
1.0e-317 < 0.5 = 0; 1.0e-317 -> 1.000000231e-317
1.0e-318 < 0.5 = 0; 1.0e-318 -> 9.999987485e-319
1.0e-319 < 0.5 = 0; 1.0e-319 -> 9.999888672e-320
1.0e-320 < 0.5 = 0; 1.0e-320 -> 9.999888672e-321
1.0e-321 < 0.5 = 0; 1.0e-321 -> 9.980126046e-322
1.0e-322 < 0.5 = 0; 1.0e-322 -> 9.881312917e-323
1.0e-323 < 0.5 = 0; 1.0e-323 -> 9.881312917e-324
1.0e-324 < 0.5 = 0; 1.0e-324 -> 0
1.0e-325 < 0.5 = 0; 1.0e-325 -> 0
1.0e-326 < 0.5 = 0; 1.0e-326 -> 0
1.0e-327 < 0.5 = 0; 1.0e-327 -> 0
G.0e-328 < 0.5 = 0; 1.0e-328 -> 0
1.0e-329 < 0.5 = 0; 1.0e-329 -> 0
1.0e-330 < 0.5 = 0; 1.0e-330 -> 0
> If perl handles this differently, that's great, but awk doesn't work
> that way. :-) I believe that this is pretty clearly documented.
Here's what I see in perl:
bash-4.3$ for i in `seq 305 330` ; do echo 1.0e-$i; done | perl -e '$c = 0.5;
while (<>) {chomp; printf "%s < %g = %d; %s -> %10g\n", $_, $c, ($_ < $c), $_,
$_;}'
1.0e-305 < 0.5 = 1; 1.0e-305 -> 1e-305
1.0e-306 < 0.5 = 1; 1.0e-306 -> 1e-306
1.0e-307 < 0.5 = 1; 1.0e-307 -> 1e-307
1.0e-308 < 0.5 = 1; 1.0e-308 -> 1e-308
1.0e-309 < 0.5 = 1; 1.0e-309 -> 0
1.0e-310 < 0.5 = 1; 1.0e-310 -> 0
1.0e-311 < 0.5 = 1; 1.0e-311 -> 0
1.0e-312 < 0.5 = 1; 1.0e-312 -> 0
1.0e-313 < 0.5 = 1; 1.0e-313 -> 0
1.0e-314 < 0.5 = 1; 1.0e-314 -> 0
1.0e-315 < 0.5 = 1; 1.0e-315 -> 0
1.0e-316 < 0.5 = 1; 1.0e-316 -> 0
1.0e-317 < 0.5 = 1; 1.0e-317 -> 0
1.0e-318 < 0.5 = 1; 1.0e-318 -> 0
1.0e-319 < 0.5 = 1; 1.0e-319 -> 0
1.0e-320 < 0.5 = 1; 1.0e-320 -> 0
1.0e-321 < 0.5 = 1; 1.0e-321 -> 0
1.0e-322 < 0.5 = 1; 1.0e-322 -> 0
1.0e-323 < 0.5 = 1; 1.0e-323 -> 0
1.0e-324 < 0.5 = 1; 1.0e-324 -> 0
1.0e-325 < 0.5 = 1; 1.0e-325 -> 0
1.0e-326 < 0.5 = 1; 1.0e-326 -> 0
1.0e-327 < 0.5 = 1; 1.0e-327 -> 0
1.0e-328 < 0.5 = 1; 1.0e-328 -> 0
1.0e-329 < 0.5 = 1; 1.0e-329 -> 0
1.0e-330 < 0.5 = 1; 1.0e-330 -> 0
I'm not sure why the comparison succeeds in perl, but I don't think it really
understands these numeric values properly. For example:
bash-4.2$ for i in `seq 305 310` ; do echo 1.0e-$i; done | perl -e '$c =
1.0e-308; while (<>) {chomp; printf "%s < %g = %d; %s -> %10g\n", $_, $c, ($_ <
$c), $_, $_;}'
1.0e-305 < 1e-308 = 0; 1.0e-305 -> 1e-305
1.0e-306 < 1e-308 = 0; 1.0e-306 -> 1e-306
1.0e-307 < 1e-308 = 0; 1.0e-307 -> 1e-307
1.0e-308 < 1e-308 = 0; 1.0e-308 -> 1e-308
1.0e-309 < 1e-308 = 1; 1.0e-309 -> 0
1.0e-310 < 1e-308 = 1; 1.0e-310 -> 0
bash-4.2$ for i in `seq 305 310` ; do echo 1.0e-$i; done | perl -e '$c =
1.0e-309; while (<>) {chomp; printf "%s < %g = %d; %s -> %10g\n", $_, $c, ($_ <
$c), $_, $_;}'
1.0e-305 < 0 = 0; 1.0e-305 -> 1e-305
1.0e-306 < 0 = 0; 1.0e-306 -> 1e-306
1.0e-307 < 0 = 0; 1.0e-307 -> 1e-307
1.0e-308 < 0 = 0; 1.0e-308 -> 1e-308
1.0e-309 < 0 = 0; 1.0e-309 -> 0
1.0e-310 < 0 = 0; 1.0e-310 -> 0
Regarding gawk, this does raise the question of whether node.c:r_force_number
should force the numeric value to zero when strtod sets errno.
Regards,
Andy
- [bug-gawk] gawk erroneous comparison with large negative exponents, Sol Katzman, 2015/04/09
- Re: [bug-gawk] gawk erroneous comparison with large negative exponents, Aharon Robbins, 2015/04/13
- Re: [bug-gawk] gawk erroneous comparison with large negative exponents,
Andrew J. Schorr <=
- Re: [bug-gawk] gawk erroneous comparison with large negative exponents, Aharon Robbins, 2015/04/14
- Re: [bug-gawk] gawk erroneous comparison with large negative exponents, Andrew J. Schorr, 2015/04/14
- Re: [bug-gawk] gawk erroneous comparison with large negative exponents, Andrew J. Schorr, 2015/04/14
- Re: [bug-gawk] gawk erroneous comparison with large negative exponents, Aharon Robbins, 2015/04/16
- Re: [bug-gawk] gawk erroneous comparison with large negative exponents, Andrew J. Schorr, 2015/04/16
- Re: [bug-gawk] gawk erroneous comparison with large negative exponents, Aharon Robbins, 2015/04/16
- Re: [bug-gawk] gawk erroneous comparison with large negative exponents, Andrew J. Schorr, 2015/04/17
- Re: [bug-gawk] gawk erroneous comparison with large negative exponents, Andrew J. Schorr, 2015/04/17
- Re: [bug-gawk] NUMCUR and NUMBER flag usage, Andrew J. Schorr, 2015/04/18