History

Another hex float fix

Hex floating point number did fail when a lot of digits are present. See testcase 70.

herman ten brugge committed 1 year ago

Commit 59aecdb1 parent c6792da3 files · +17 −9Browse files

Unified · Split

3 files
  1. tccpp.c +12 −8
  2. tests/tests2/70_floating_point_literals.c +3 −1
  3. tests/tests2/70_floating_point_literals.expect +2 −0
tccpp.c+12−8
@@ -2240,15 +2240,18 @@ static void parse_string(const char *s, int len) · 2239 unmodified lines
22402240 #endif
22412241
22422242 /* bn = (bn << shift) | or_val */
2243−static void bn_lshift(unsigned int *bn, int shift, int or_val)
2243+static int bn_lshift(unsigned int *bn, int shift, int or_val)
22442244 {
22452245 int i;
22462246 unsigned int v;
2247+ if (bn[BN_SIZE - 1] >> (32 - shift))
2248+ return shift;
22472249 for(i=0;i<BN_SIZE;i++) {
22482250 v = bn[i];
22492251 bn[i] = (v << shift) | or_val;
22502252 or_val = v >> (32 - shift);
22512253 }
2254+ return 0;
22522255 }
22532256
22542257 static void bn_zero(unsigned int *bn)
@@ -2321,6 +2324,7 @@ static void parse_number(const char *p) · 66 unmodified lines
23212324 it by hand */
23222325 /* hexadecimal or binary floats */
23232326 /* XXX: handle overflows */
2327+ frac_bits = 0;
23242328 *q = '\0';
23252329 if (b == 16)
23262330 shift = 4;
@@ -2339,9 +2343,8 @@ static void parse_number(const char *p) · 12 unmodified lines
23392343 } else {
23402344 t = t - '0';
23412345 }
2342− bn_lshift(bn, shift, t);
2346+ frac_bits -= bn_lshift(bn, shift, t);
23432347 }
2344− frac_bits = 0;
23452348 if (ch == '.') {
23462349 ch = *p++;
23472350 while (1) {
@@ -2357,7 +2360,7 @@ static void parse_number(const char *p) · 9 unmodified lines
23572360 }
23582361 if (t >= b)
23592362 tcc_error("invalid digit");
2360− bn_lshift(bn, shift, t);
2363+ frac_bits -= bn_lshift(bn, shift, t);
23612364 frac_bits += shift;
23622365 ch = *p++;
23632366 }
@@ -2376,7 +2379,9 @@ static void parse_number(const char *p) · 12 unmodified lines
23762379 if (ch < '0' || ch > '9')
23772380 expect("exponent digits");
23782381 while (ch >= '0' && ch <= '9') {
2379− exp_val = exp_val * 10 + ch - '0';
2382+ /* If exp_val is this large ldexp will return HUGE_VAL */
2383+ if (exp_val < 100000000)
2384+ exp_val = exp_val * 10 + ch - '0';
23802385 ch = *p++;
23812386 }
23822387 exp_val = exp_val * s;
@@ -2405,12 +2410,11 @@ static void parse_number(const char *p) · 22 unmodified lines
24052410 #ifdef TCC_USING_DOUBLE_FOR_LDOUBLE
24062411 tokc.d = d;
24072412 #else
2408− /* XXX: not large enough */
2409− tokc.ld = (long double)d;
2413+ tokc.ld = d;
24102414 #endif
24112415 } else {
24122416 tok = TOK_CDOUBLE;
2413− tokc.d = d;
2417+ tokc.d = (double)d;
24142418 }
24152419 } else {
24162420 /* decimal floats */
tests/tests2/70_floating_point_literals.c+3−1
@@ -31,7 +31,9 @@ int main() · 30 unmodified lines
3131 double da0 = 0X.1ACP12;
3232 double da1 = 0x.1acp-12;
3333 double da2 = 0x.1acp+12;
34− printf("%f\n%f\n%f\n\n", da0, da1, da2);
34+ double da3 = 0x1.00000000000000000000000000000000000000000000p+12;
35+ double da4 = 0x1000000000000000000000000000000000000000000000p-140;
36+ printf("%f\n%f\n%f\n%f\n%f\n\n", da0, da1, da2, da3, da4);
3537
3638 double db0 = 0X1AC.BDP12;
3739 double db1 = 0x1ac.bdp-12;
tests/tests2/70_floating_point_literals.expect+2−0
@@ -21,6 +21,8 @@ · 20 unmodified lines
2121 428.000000
2222 0.000026
2323 428.000000
24+4096.000000
25+1099511627776.000000
2426
2527 1756112.000000
2628 0.104672

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t