summaryrefslogtreecommitdiff
path: root/numeric.c
diff options
context:
space:
mode:
authorKarl Williamson <khw@cpan.org>2020-01-22 12:15:38 -0700
committerKarl Williamson <khw@cpan.org>2020-01-23 15:55:24 -0700
commitefc92487e399906bf9520deb444b349cbe03f4f0 (patch)
tree9924bd808fff80ef0957526039eb1bd27a52794c /numeric.c
parent1198415d086c4846ab55871102a42c93be57d86b (diff)
downloadperl-efc92487e399906bf9520deb444b349cbe03f4f0.tar.gz
grok_bin_oct_hex: Fix overflow approximation
The multiplcation factor was itself overflowing, so need to change it to an NV. Also, the first time through this factor is not needed as what it is multiplying is 0, so set it to 0.
Diffstat (limited to 'numeric.c')
-rw-r--r--numeric.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/numeric.c b/numeric.c
index 4c2f12b8cd..03bc3a34bc 100644
--- a/numeric.c
+++ b/numeric.c
@@ -379,7 +379,7 @@ Perl_grok_bin_oct_hex(pTHX_ const char *start,
/* In overflows, this keeps track of how much to multiply the overflowed NV
* by as we continue to parse the remaining digits */
- UV factor;
+ NV factor = 0;
/* This function unifies the core of grok_bin, grok_oct, and grok_hex. It
* is optimized for hex conversion. For example, it uses XDIGIT_VALUE to
@@ -492,7 +492,7 @@ Perl_grok_bin_oct_hex(pTHX_ const char *start,
/* Note XDIGIT_VALUE() is branchless, works on binary
* and octal as well, so can be used here, without
* slowing those down */
- factor <<= shift;
+ factor *= 1 << shift;
continue;
}
@@ -501,7 +501,7 @@ Perl_grok_bin_oct_hex(pTHX_ const char *start,
* value. Each time through the loop we have increased 'factor' so
* that it gives how much the current approximation needs to
* effectively be shifted to make room for this new value */
- value_nv *= (NV) factor;
+ value_nv *= factor;
value_nv += (NV) value;
/* Then we keep accumulating digits, until all are parsed. We
@@ -590,7 +590,7 @@ Perl_grok_bin_oct_hex(pTHX_ const char *start,
}
/* Overflowed: Calculate the final overflow approximation */
- value_nv *= (NV) factor;
+ value_nv *= factor;
value_nv += (NV) value;
output_non_portable(base);