diff --git a/tccpp.c b/tccpp.c index a24dd0e4..d5c01fe4 100644 --- a/tccpp.c +++ b/tccpp.c @@ -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> (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 */ diff --git a/tests/tests2/70_floating_point_literals.c b/tests/tests2/70_floating_point_literals.c index 012fb4fa..f89a7b28 100644 --- a/tests/tests2/70_floating_point_literals.c +++ b/tests/tests2/70_floating_point_literals.c @@ -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; diff --git a/tests/tests2/70_floating_point_literals.expect b/tests/tests2/70_floating_point_literals.expect index 7eb1efb9..3dc1f184 100644 --- a/tests/tests2/70_floating_point_literals.expect +++ b/tests/tests2/70_floating_point_literals.expect @@ -21,6 +21,8 @@ 428.000000 0.000026 428.000000 +4096.000000 +1099511627776.000000 1756112.000000 0.104672