Skip to content

Commit 02f10fd

Browse files
committed
Removed the restriction on the integer part of the notation
1 parent 30e1f29 commit 02f10fd

File tree

1 file changed

+26
-29
lines changed

1 file changed

+26
-29
lines changed

ext/bcmath/libbcmath/src/str2num.c

+26-29
Original file line numberDiff line numberDiff line change
@@ -111,16 +111,6 @@ static bool bc_scientific_notation_str2num(
111111
{
112112
const char *fractional_end = exponent_ptr;
113113

114-
/* In scientific notation, the mantissa always has one integer digit. */
115-
if (UNEXPECTED(digits != 1)) {
116-
goto fail;
117-
}
118-
119-
/* Must be 1 <= mantissa < 10 */
120-
if (UNEXPECTED(*integer_ptr == 0)) {
121-
goto fail;
122-
}
123-
124114
if (UNEXPECTED(*exponent_ptr != 'e' && *exponent_ptr != 'E')) {
125115
goto fail;
126116
}
@@ -152,36 +142,43 @@ static bool bc_scientific_notation_str2num(
152142
exponent_ptr++;
153143
}
154144

145+
const char *integer_end = integer_ptr + digits;
155146
size_t str_scale = fractional_end - fractional_ptr;
147+
size_t str_full_len = digits + str_scale;
148+
size_t leading_zero_paddings = 0;
156149

157150
if (exponent_sign == PLUS) {
158151
digits += exponent;
159-
str_scale = str_scale > exponent ? str_scale - exponent : 0;
160-
161-
*num = bc_new_num_nonzeroed(digits, str_scale);
162-
(*num)->n_sign = *str == '-' ? MINUS : PLUS;
163-
char *nptr = (*num)->n_value;
164-
char *nend = nptr + digits + str_scale;
165-
166-
*nptr++ = *integer_ptr - '0';
167-
nptr = bc_copy_and_toggle_bcd(nptr, fractional_ptr, fractional_end);
168-
while (nptr < nend) {
169-
*nptr++ = 0;
152+
if (digits == 0) {
153+
leading_zero_paddings = 1;
170154
}
155+
str_scale = str_scale > exponent ? str_scale - exponent : 0;
171156
} else {
172-
digits = 0;
173157
str_scale += exponent;
158+
if (digits > exponent) {
159+
digits -= exponent;
160+
} else {
161+
leading_zero_paddings = exponent - digits + 1; /* 1 is for interger part */
162+
digits = 0;
163+
}
164+
}
174165

175-
*num = bc_new_num_nonzeroed(1, str_scale); // 1 is for 0
176-
(*num)->n_sign = *str == '-' ? MINUS : PLUS;
177-
char *nptr = (*num)->n_value;
166+
*num = bc_new_num_nonzeroed(digits > 0 ? digits : 1, str_scale); /* 1 is for 0 */
167+
(*num)->n_sign = *str == '-' ? MINUS : PLUS;
168+
char *nptr = (*num)->n_value;
178169

179-
for (size_t i = 0; i < exponent; i++) {
170+
for (size_t i = 0; i < leading_zero_paddings; i++) {
171+
*nptr++ = 0;
172+
}
173+
174+
nptr = bc_copy_and_toggle_bcd(nptr, integer_ptr, integer_end);
175+
nptr = bc_copy_and_toggle_bcd(nptr, fractional_ptr, fractional_end);
176+
177+
if (digits > str_full_len) {
178+
/* Fill the rest integer part with zeros */
179+
for (size_t i = 0; i < digits - str_full_len; i++) {
180180
*nptr++ = 0;
181181
}
182-
183-
*nptr++ = *integer_ptr - '0';
184-
nptr = bc_copy_and_toggle_bcd(nptr, fractional_ptr, fractional_end);
185182
}
186183

187184
if (full_scale) {

0 commit comments

Comments
 (0)