[kaffe] Re: The problem of "Double.c and buggy strtod" is settled
Ito Kazumitsu
ito.kazumitsu@hitachi-cable.co.jp
Fri Jun 6 03:58:01 2003
In message "Re: [kaffe] Re: The problem of "Double.c and buggy strtod" is settled"
on 03/06/06, Ito Kazumitsu <ito.kazumitsu@hitachi-cable.co.jp> writes:
> Seeing the source, I found that the libiberty-strtod.c used atof.
> The atof of Linux 2.0.38 uses its own __strtod_internal.
>
> As long as __strtod_internal is used, you cannot expect a good
> result.
I am afraid it is quite difficult to keep __strtod_internal
from being called.
So I tried the attached replace/strtod.c and changed Double.c
like this:
--- libraries/clib/native/Double.c.orig Fri Apr 12 21:56:11 2002
+++ libraries/clib/native/Double.c Fri Jun 6 18:41:03 2003
@@ -23,6 +23,7 @@
#include "files.h"
#include "java_lang_Double.h"
#include <native.h>
+extern double my_strtod();
/*
* Convert a "normal" double to a string with the supplied precision.
@@ -130,7 +131,7 @@
#endif
/* Parse value; check for empty parse */
- value = strtod(buf, &endbuf);
+ value = my_strtod(buf, &endbuf);
if (endbuf == buf) {
msg = startbuf; /* this is what JDK 1.1.6 does */
goto bail;
The result was satisfactory but "make test" showed "FAIL: DoublePrint.java".
But diff test/regression/DoublePrint.out test/regression/DoublePrint.fail
is only this:
10c10
< 4.9E-324
---
> 4.9406564584125E-324
I think this difference is ignoreable.
And my replace/strtod.c follows. It is based on the idea
that the need for parsing "4.9406564584124654418e-324"
except for the compiling of Double.java must be rare.
$ cat replace/strtod.c
#include <stdlib.h>
#define JAVA_DOUBLE_MIN_STR "4.9406564584124654418e-324"
#define JAVA_DOUBLE_MIN 4.9406564584124654418e-324
double
my_strtod (str, ptr)
char *str;
char **ptr;
{
char *q;
char *r;
int m;
int l;
double d;
if (*str == JAVA_DOUBLE_MIN_STR[0]) {
q = str;
r = JAVA_DOUBLE_MIN_STR;
m = 1;
l = 0;
while (*r) {
if (*q++ != *r++) {
m = 0;
break;
}
l++;
}
if (m) {
d = JAVA_DOUBLE_MIN;
if (ptr != NULL) {
*ptr = str + l;
}
}
else {
d = strtod (str, ptr);
}
}
else {
d = strtod (str, ptr);
}
return d;
}