Recognise (or not) a number. The type of the number is returned
(0 if unrecognised), otherwise it is a bit-ORed combination of
IS_NUMBER_IN_UV, IS_NUMBER_GREATER_THAN_UV_MAX, IS_NUMBER_NOT_INT,
-IS_NUMBER_NEG, IS_NUMBER_INFINITY (defined in perl.h).
+IS_NUMBER_NEG, IS_NUMBER_INFINITY, IS_NUMBER_NAN (defined in perl.h).
If the value of the number can fit an in UV, it is returned in the *valuep
IS_NUMBER_IN_UV will be set to indicate that *valuep is valid, IS_NUMBER_IN_UV
const char max_mod_10 = UV_MAX % 10;
int numtype = 0;
int sawinf = 0;
+ int sawnan = 0;
while (s < send && isSPACE(*s))
s++;
With it gcc on arm is managing 6 instructions (6 cycles) per digit.
In theory the optimiser could deduce how far to unroll the loop
before checking for overflow. */
- if (s < send) {
- int digit = *++s - '0';
+ if (++s < send) {
+ int digit = *s - '0';
if (digit >= 0 && digit <= 9) {
value = value * 10 + digit;
- if (s < send) {
- digit = *++s - '0';
+ if (++s < send) {
+ digit = *s - '0';
if (digit >= 0 && digit <= 9) {
value = value * 10 + digit;
- if (s < send) {
- digit = *++s - '0';
+ if (++s < send) {
+ digit = *s - '0';
if (digit >= 0 && digit <= 9) {
value = value * 10 + digit;
- if (s < send) {
- digit = *++s - '0';
+ if (++s < send) {
+ digit = *s - '0';
if (digit >= 0 && digit <= 9) {
value = value * 10 + digit;
- if (s < send) {
- digit = *++s - '0';
+ if (++s < send) {
+ digit = *s - '0';
if (digit >= 0 && digit <= 9) {
value = value * 10 + digit;
- if (s < send) {
- digit = *++s - '0';
+ if (++s < send) {
+ digit = *s - '0';
if (digit >= 0 && digit <= 9) {
value = value * 10 + digit;
- if (s < send) {
- digit = *++s - '0';
+ if (++s < send) {
+ digit = *s - '0';
if (digit >= 0 && digit <= 9) {
value = value * 10 + digit;
- if (s < send) {
- digit = *++s - '0';
+ if (++s < send) {
+ digit = *s - '0';
if (digit >= 0 && digit <= 9) {
value = value * 10 + digit;
- if (s < send) {
+ if (++s < send) {
/* Now got 9 digits, so need to check
each time for overflow. */
- digit = *++s - '0';
+ digit = *s - '0';
while (digit >= 0 && digit <= 9
&& (value < max_div_10
|| (value == max_div_10
&& digit <= max_mod_10))) {
value = value * 10 + digit;
- if (s < send)
- digit = *++s - '0';
+ if (++s < send)
+ digit = *s - '0';
else
break;
}
if (digit >= 0 && digit <= 9
- && !(s < send)) {
+ && (s < send)) {
/* value overflowed.
skip the remaining digits, don't
worry about setting *valuep. */
s++;
}
sawinf = 1;
- } else /* Add test for NaN here. */
+ } else if (*s == 'N' || *s == 'n') {
+ /* XXX TODO: There are signaling NaNs and quiet NaNs. */
+ s++; if (s == send || (*s != 'A' && *s != 'a')) return 0;
+ s++; if (s == send || (*s != 'N' && *s != 'n')) return 0;
+ s++;
+ sawnan = 1;
+ } else
return 0;
if (sawinf) {
numtype &= IS_NUMBER_NEG; /* Keep track of sign */
numtype |= IS_NUMBER_INFINITY | IS_NUMBER_NOT_INT;
+ } else if (sawnan) {
+ numtype &= IS_NUMBER_NEG; /* Keep track of sign */
+ numtype |= IS_NUMBER_NAN | IS_NUMBER_NOT_INT;
} else if (s < send) {
/* we can have an optional exponent part */
if (*s == 'e' || *s == 'E') {
while (s < send && isSPACE(*s))
s++;
if (s >= send)
- return numtype;
+ return numtype;
if (len == 10 && memEQ(pv, "0 but true", 10)) {
if (valuep)
*valuep = 0;
I32 ipart = 0; /* index into part[] */
I32 offcount; /* number of digits in least significant part */
+ /* leading whitespace */
+ while (isSPACE(*s))
+ ++s;
+
/* sign */
switch (*s) {
case '-':