Another hex float fix
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled

Hex floating point number did fail when a lot of digits are present.
See testcase 70.
This commit is contained in:
herman ten brugge 2025-05-28 21:33:30 +02:00
parent c6792dac03
commit 59aecdb539
3 changed files with 17 additions and 9 deletions

20
tccpp.c
View File

@ -2240,15 +2240,18 @@ static void parse_string(const char *s, int len)
#endif
/* bn = (bn << shift) | or_val */
static void bn_lshift(unsigned int *bn, int shift, int or_val)
static int bn_lshift(unsigned int *bn, int shift, int or_val)
{
int i;
unsigned int v;
if (bn[BN_SIZE - 1] >> (32 - shift))
return shift;
for(i=0;i<BN_SIZE;i++) {
v = bn[i];
bn[i] = (v << shift) | or_val;
or_val = v >> (32 - shift);
}
return 0;
}
static void bn_zero(unsigned int *bn)
@ -2321,6 +2324,7 @@ static void parse_number(const char *p)
it by hand */
/* hexadecimal or binary floats */
/* XXX: handle overflows */
frac_bits = 0;
*q = '\0';
if (b == 16)
shift = 4;
@ -2339,9 +2343,8 @@ static void parse_number(const char *p)
} else {
t = t - '0';
}
bn_lshift(bn, shift, t);
frac_bits -= bn_lshift(bn, shift, t);
}
frac_bits = 0;
if (ch == '.') {
ch = *p++;
while (1) {
@ -2357,7 +2360,7 @@ static void parse_number(const char *p)
}
if (t >= b)
tcc_error("invalid digit");
bn_lshift(bn, shift, t);
frac_bits -= bn_lshift(bn, shift, t);
frac_bits += shift;
ch = *p++;
}
@ -2376,7 +2379,9 @@ static void parse_number(const char *p)
if (ch < '0' || ch > '9')
expect("exponent digits");
while (ch >= '0' && ch <= '9') {
exp_val = exp_val * 10 + ch - '0';
/* If exp_val is this large ldexp will return HUGE_VAL */
if (exp_val < 100000000)
exp_val = exp_val * 10 + ch - '0';
ch = *p++;
}
exp_val = exp_val * s;
@ -2405,12 +2410,11 @@ static void parse_number(const char *p)
#ifdef TCC_USING_DOUBLE_FOR_LDOUBLE
tokc.d = d;
#else
/* XXX: not large enough */
tokc.ld = (long double)d;
tokc.ld = d;
#endif
} else {
tok = TOK_CDOUBLE;
tokc.d = d;
tokc.d = (double)d;
}
} else {
/* decimal floats */

View File

@ -31,7 +31,9 @@ int main()
double da0 = 0X.1ACP12;
double da1 = 0x.1acp-12;
double da2 = 0x.1acp+12;
printf("%f\n%f\n%f\n\n", da0, da1, da2);
double da3 = 0x1.00000000000000000000000000000000000000000000p+12;
double da4 = 0x1000000000000000000000000000000000000000000000p-140;
printf("%f\n%f\n%f\n%f\n%f\n\n", da0, da1, da2, da3, da4);
double db0 = 0X1AC.BDP12;
double db1 = 0x1ac.bdp-12;

View File

@ -21,6 +21,8 @@
428.000000
0.000026
428.000000
4096.000000
1099511627776.000000
1756112.000000
0.104672