Skip to content

Commit 252f61a

Browse files
t-a-kkhwilliamson
authored andcommitted
Perl_scan_num: use ldexp() instead of multiplying pow(2.0, ...)
For most NV format, ldexp() could be a rather simple operation such as modifying exponential part of the floating point number, so that ldexp() will be hopefully faster than pow(2.0, ...).
1 parent 3b66c6e commit 252f61a

File tree

1 file changed

+13
-5
lines changed

1 file changed

+13
-5
lines changed

toke.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11930,13 +11930,18 @@ Perl_scan_num(pTHX_ const char *start, YYSTYPE* lvalp)
1193011930
# define HEXFP_NV
1193111931
NV hexfp_nv = 0.0;
1193211932
#endif
11933-
NV hexfp_mult = 1.0;
11933+
int hexfp_exp = 0;
1193411934
UV high_non_zero = 0; /* highest digit */
1193511935
int non_zero_integer_digits = 0;
1193611936
bool new_octal = FALSE; /* octal with "0o" prefix */
1193711937

1193811938
PERL_ARGS_ASSERT_SCAN_NUM;
1193911939

11940+
/* Make sure "int" is wide enough to hold exponent of NV.
11941+
We use "int" (rather than I32 etc.) to be compatible with ldexp() */
11942+
STATIC_ASSERT_STMT((INT_MIN / 10) < NV_MIN_EXP);
11943+
STATIC_ASSERT_STMT(NV_MAX_EXP < (INT_MAX / 10));
11944+
1194011945
/* We use the first character to decide what type of number this is */
1194111946

1194211947
switch (*s) {
@@ -12223,7 +12228,6 @@ Perl_scan_num(pTHX_ const char *start, YYSTYPE* lvalp)
1222312228
h++;
1222412229
}
1222512230
if (isDIGIT(*h)) {
12226-
I32 hexfp_exp = 0;
1222712231
while (isDIGIT(*h) || *h == '_') {
1222812232
if (isDIGIT(*h)) {
1222912233
hexfp_exp *= 10;
@@ -12260,7 +12264,6 @@ Perl_scan_num(pTHX_ const char *start, YYSTYPE* lvalp)
1226012264
#ifdef HEXFP_UQUAD
1226112265
hexfp_exp -= hexfp_frac_bits;
1226212266
#endif
12263-
hexfp_mult = Perl_pow(2.0, hexfp_exp);
1226412267
hexfp = TRUE;
1226512268
goto decimal;
1226612269
}
@@ -12510,9 +12513,14 @@ Perl_scan_num(pTHX_ const char *start, YYSTYPE* lvalp)
1251012513
"Hexadecimal float: mantissa overflow");
1251112514
# endif
1251212515
#ifdef HEXFP_UQUAD
12513-
nv = hexfp_uquad * hexfp_mult;
12516+
nv = (NV)hexfp_uquad;
1251412517
#else /* HEXFP_NV */
12515-
nv = hexfp_nv * hexfp_mult;
12518+
nv = hexfp_nv;
12519+
#endif
12520+
#ifdef Perl_ldexp
12521+
nv = Perl_ldexp(nv, hexfp_exp);
12522+
#else
12523+
nv *= Perl_pow(2.0, hexfp_exp);
1251612524
#endif
1251712525
} else {
1251812526
nv = Atof(PL_tokenbuf);

0 commit comments

Comments
 (0)