[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: gawk number to string bug
From: |
Aharon Robbins |
Subject: |
Re: gawk number to string bug |
Date: |
Mon, 19 Dec 2005 05:39:25 +0200 |
Greetings. Re this:
> Date: Wed, 14 Dec 2005 18:29:38 -0800
> From: David Ellsworth <address@hidden>
> Subject: gawk number to string bug
> To: address@hidden
> Cc: address@hidden
>
> I ran into a bug in how gawk converts numbers into strings.
>
> Running the program
> BEGIN { print 9223372036854775808 }
> prints
> -9223372036854775808
> on a 64-bit machine. On a 32-bit machine, the same program prints out
> 9.22337e+18
> which is correct.
>
> Note that 9223372036854775808 == 2^63. Printing out other powers of 2
> is OK.
>
> Version details:
> gawk version 3.1.5, freshly downloaded from gnu.org
> gcc (GCC) 3.4.4 (Gentoo 3.4.4-r1, ssp-3.4.4-1.0, pie-8.7.8)
> uname -a output:
> Linux pixie 2.6.12-gentoo-r10 #2 SMP Tue Nov 1 03:42:22 PST 2005
> x86_64 Dual Core AMD Opteron(tm) Processor 275 AuthenticAMD GNU/Linux
>
> (the 32-bit example used gawk version 3.1.3)
>
> - David
Thanks for the bug report. I was able to reproduce it on a 64-bit RHEL system.
The patch below fixes the problem. I may ultimately fix it differently; on
the test program I get different behaviors from the Bell Labs awk and from
mawk, so I haven't 100% decided how I want gawk to behave.
Thanks!
Arnold
---------------------------
--- node.c.save 2005-07-26 21:07:43.000000000 +0300
+++ node.c 2005-12-18 10:25:40.530448768 +0200
@@ -151,6 +151,7 @@
register char *sp = buf;
double val;
char *orig, *trans, save;
+ register long num;
if (! do_traditional && (s->flags & INTLSTR) != 0) {
save = s->stptr[s->stlen];
@@ -163,9 +164,12 @@
return tmp_string(trans, strlen(trans));
}
- /* not an integral value, or out of range */
- if ((val = double_to_int(s->numbr)) != s->numbr
- || val < LONG_MIN || val > LONG_MAX) {
+ /* conversion to long overflows, or out of range, or not integral */
+ val = double_to_int(s->numbr);
+ num = (long) val;
+ if ( (s->numbr > 0 && num < 0)
+ || (s->numbr < 0 && num > 0)
+ || val < LONG_MIN || val > LONG_MAX || val != s->numbr) {
/*
* Once upon a time, if GFMT_WORKAROUND wasn't defined,
* we just blindly did this:
@@ -199,9 +203,7 @@
goto no_malloc;
} else {
- /* integral value */
- /* force conversion to long only once */
- register long num = (long) val;
+ /* integral value, in range, too! */
if (num < NVAL && num >= 0) {
sp = (char *) values[num];
s->stlen = 1;
Re: gawk number to string bug, David Ellsworth, 2005/12/19