/* numeric.c
*
* Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999,
* 2000, 2001, 2002, 2003, by Larry Wall and others
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
*
*/
/*
* "That only makes eleven (plus one mislaid) and not fourteen, unless
* wizards count differently to other people."
*/
/*
=head1 Numeric functions
*/
#include "EXTERN.h"
#define PERL_IN_NUMERIC_C
#include "perl.h"
{
if (f < 0.0)
if (f < U32_MAX_P1) {
#if CASTFLAGS & 2
if (f < U32_MAX_P1_HALF)
return (U32) f;
f -= U32_MAX_P1_HALF;
#else
return (U32) f;
#endif
}
return f > 0 ? U32_MAX : 0 /* NaN */;
}
{
if (f < I32_MAX_P1)
if (f < U32_MAX_P1) {
#if CASTFLAGS & 2
if (f < U32_MAX_P1_HALF)
f -= U32_MAX_P1_HALF;
#else
#endif
}
}
{
if (f < IV_MAX_P1)
if (f < UV_MAX_P1) {
#if CASTFLAGS & 2
/* For future flexibility allowing for sizeof(UV) >= sizeof(IV) */
if (f < UV_MAX_P1_HALF)
f -= UV_MAX_P1_HALF;
#else
#endif
}
}
{
if (f < 0.0)
if (f < UV_MAX_P1) {
#if CASTFLAGS & 2
if (f < UV_MAX_P1_HALF)
return (UV) f;
f -= UV_MAX_P1_HALF;
#else
return (UV) f;
#endif
}
return f > 0 ? UV_MAX : 0 /* NaN */;
}
/*
* This hack is to force load of "huge" support from libm.a
* So it is in perl for (say) POSIX to use.
* Needed for SunOS with Sun's 'acc' for example.
*/
Perl_huge(void)
{
# if defined(USE_LONG_DOUBLE) && defined(HUGE_VALL)
return HUGE_VALL;
# endif
return HUGE_VAL;
}
#endif
/*
=for apidoc grok_bin
converts a string representing a binary number to numeric form.
On entry I<start> and I<*len> give the string to scan, I<*flags> gives
conversion flags, and I<result> should be NULL or a pointer to an NV.
The scan stops at the end of the string, or the first invalid character.
On return I<*len> is set to the length scanned string, and I<*flags> gives
output flags.
If the value is <= UV_MAX it is returned as a UV, the output flags are clear,
and nothing is written to I<*result>. If the value is > UV_MAX C<grok_bin>
returns UV_MAX, sets C<PERL_SCAN_GREATER_THAN_UV_MAX> in the output flags,
and writes the value to I<*result> (or the value is discarded if I<result>
is NULL).
The hex number may optionally be prefixed with "0b" or "b" unless
C<PERL_SCAN_DISALLOW_PREFIX> is set in I<*flags> on entry. If
C<PERL_SCAN_ALLOW_UNDERSCORES> is set in I<*flags> then the binary
number may use '_' characters to separate digits.
=cut
*/
const char *s = start;
if (!(*flags & PERL_SCAN_DISALLOW_PREFIX)) {
/* strip off leading b or 0b.
for compatibility silently suffer "b" and "0b" as valid binary
numbers. */
if (len >= 1) {
if (s[0] == 'b') {
s++;
len--;
}
s+=2;
len-=2;
}
}
}
for (; len-- && *s; s++) {
char bit = *s;
/* Write it in this wonky order with a goto to attempt to get the
compiler to make the common case integer-only loop pretty tight.
With gcc seems to be much straighter code than old scan_bin. */
redo:
if (!overflowed) {
continue;
}
/* Bah. We're just overflowed. */
if (ckWARN_d(WARN_OVERFLOW))
"Integer overflow in binary number");
overflowed = TRUE;
}
value_nv *= 2.0;
/* If an NV has not enough bits in its mantissa to
* represent a UV this summing of small low-order numbers
* is a waste of time (because the NV cannot preserve
* the low-order bits anyway): we could just remember when
* did we overflow and in the end just multiply value_nv by the
* right amount. */
continue;
}
{
--len;
++s;
goto redo;
}
"Illegal binary digit '%c' ignored", *s);
break;
}
#if UVSIZE > 4
#endif
) {
if (ckWARN(WARN_PORTABLE))
"Binary number > 0b11111111111111111111111111111111 non-portable");
}
if (!overflowed) {
*flags = 0;
return value;
}
if (result)
return UV_MAX;
}
/*
=for apidoc grok_hex
converts a string representing a hex number to numeric form.
On entry I<start> and I<*len> give the string to scan, I<*flags> gives
conversion flags, and I<result> should be NULL or a pointer to an NV.
The scan stops at the end of the string, or the first non-hex-digit character.
On return I<*len> is set to the length scanned string, and I<*flags> gives
output flags.
If the value is <= UV_MAX it is returned as a UV, the output flags are clear,
and nothing is written to I<*result>. If the value is > UV_MAX C<grok_hex>
returns UV_MAX, sets C<PERL_SCAN_GREATER_THAN_UV_MAX> in the output flags,
and writes the value to I<*result> (or the value is discarded if I<result>
is NULL).
The hex number may optionally be prefixed with "0x" or "x" unless
C<PERL_SCAN_DISALLOW_PREFIX> is set in I<*flags> on entry. If
C<PERL_SCAN_ALLOW_UNDERSCORES> is set in I<*flags> then the hex
number may use '_' characters to separate digits.
=cut
*/
const char *s = start;
const char *hexdigit;
if (!(*flags & PERL_SCAN_DISALLOW_PREFIX)) {
/* strip off leading x or 0x.
for compatibility silently suffer "x" and "0x" as valid hex numbers.
*/
if (len >= 1) {
if (s[0] == 'x') {
s++;
len--;
}
s+=2;
len-=2;
}
}
}
for (; len-- && *s; s++) {
if (hexdigit) {
/* Write it in this wonky order with a goto to attempt to get the
compiler to make the common case integer-only loop pretty tight.
With gcc seems to be much straighter code than old scan_hex. */
redo:
if (!overflowed) {
if (value <= max_div_16) {
continue;
}
/* Bah. We're just overflowed. */
if (ckWARN_d(WARN_OVERFLOW))
"Integer overflow in hexadecimal number");
overflowed = TRUE;
}
value_nv *= 16.0;
/* If an NV has not enough bits in its mantissa to
* represent a UV this summing of small low-order numbers
* is a waste of time (because the NV cannot preserve
* the low-order bits anyway): we could just remember when
* did we overflow and in the end just multiply value_nv by the
* right amount of 16-tuples. */
continue;
}
{
--len;
++s;
goto redo;
}
"Illegal hexadecimal digit '%c' ignored", *s);
break;
}
#if UVSIZE > 4
#endif
) {
if (ckWARN(WARN_PORTABLE))
"Hexadecimal number > 0xffffffff non-portable");
}
if (!overflowed) {
*flags = 0;
return value;
}
if (result)
return UV_MAX;
}
/*
=for apidoc grok_oct
=cut
*/
const char *s = start;
for (; len-- && *s; s++) {
/* gcc 2.95 optimiser not smart enough to figure that this subtraction
out front allows slicker code. */
/* Write it in this wonky order with a goto to attempt to get the
compiler to make the common case integer-only loop pretty tight.
*/
redo:
if (!overflowed) {
continue;
}
/* Bah. We're just overflowed. */
if (ckWARN_d(WARN_OVERFLOW))
"Integer overflow in octal number");
overflowed = TRUE;
}
value_nv *= 8.0;
/* If an NV has not enough bits in its mantissa to
* represent a UV this summing of small low-order numbers
* is a waste of time (because the NV cannot preserve
* the low-order bits anyway): we could just remember when
* did we overflow and in the end just multiply value_nv by the
* right amount of 8-tuples. */
continue;
}
{
--len;
++s;
goto redo;
}
/* Allow \octal to work the DWIM way (that is, stop scanning
* as soon as non-octal characters are seen, complain only iff
* someone seems to want to use the digits eight and nine). */
"Illegal octal digit '%c' ignored", *s);
}
break;
}
#if UVSIZE > 4
#endif
) {
if (ckWARN(WARN_PORTABLE))
"Octal number > 037777777777 non-portable");
}
if (!overflowed) {
*flags = 0;
return value;
}
if (result)
return UV_MAX;
}
/*
=for apidoc scan_bin
For backwards compatibility. Use C<grok_bin> instead.
=for apidoc scan_hex
For backwards compatibility. Use C<grok_hex> instead.
=for apidoc scan_oct
For backwards compatibility. Use C<grok_oct> instead.
=cut
*/
{
}
{
}
{
}
/*
=for apidoc grok_numeric_radix
Scan and skip for a numeric decimal separator (radix).
=cut
*/
bool
{
#ifdef USE_LOCALE_NUMERIC
if (PL_numeric_radix_sv && IN_LOCALE) {
return TRUE;
}
}
/* always try "." if numeric radix didn't match because
* we may have data from different locales mixed */
#endif
++*sp;
return TRUE;
}
return FALSE;
}
/*
=for apidoc grok_number
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, 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
will never be set unless *valuep is valid, but *valuep may have been assigned
to during processing even though IS_NUMBER_IN_UV is not set on return.
If valuep is NULL, IS_NUMBER_IN_UV will be set for the same cases as when
valuep is non-NULL, but no actual assignment (or SEGV) will occur.
IS_NUMBER_NOT_INT will be set with IS_NUMBER_IN_UV if trailing decimals were
seen (in which case *valuep gives the true value truncated to an integer), and
IS_NUMBER_NEG if the number is negative (in which case *valuep holds the
absolute value). IS_NUMBER_IN_UV is not set if e notation was used or the
number is larger than a UV.
=cut
*/
int
{
const char *s = pv;
int numtype = 0;
int sawinf = 0;
int sawnan = 0;
s++;
if (s == send) {
return 0;
} else if (*s == '-') {
s++;
}
else if (*s == '+')
s++;
if (s == send)
return 0;
/* next must be digit or the radix separator or beginning of infinity */
if (isDIGIT(*s)) {
/* UVs are at least 32 bits, so the first 9 decimal digits cannot
overflow. */
/* This construction seems to be more optimiser friendly.
(without it gcc does the isDIGIT test and the *s - '0' separately)
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) {
if (++s < send) {
digit = *s - '0';
if (++s < send) {
digit = *s - '0';
if (++s < send) {
digit = *s - '0';
if (++s < send) {
digit = *s - '0';
if (++s < send) {
digit = *s - '0';
if (++s < send) {
digit = *s - '0';
if (++s < send) {
digit = *s - '0';
if (++s < send) {
/* Now got 9 digits, so need to check
each time for overflow. */
digit = *s - '0';
&& (value < max_div_10
|| (value == max_div_10
&& digit <= max_mod_10))) {
if (++s < send)
digit = *s - '0';
else
break;
}
&& (s < send)) {
/* value overflowed.
skip the remaining digits, don't
worry about setting *valuep. */
do {
s++;
numtype |=
goto skip_value;
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
if (valuep)
if (GROK_NUMERIC_RADIX(&s, send)) {
s++;
}
}
else if (GROK_NUMERIC_RADIX(&s, send)) {
/* no digits before the radix means we need digits after it */
do {
s++;
if (valuep) {
/* integer approximation is valid - it's 0. */
*valuep = 0;
}
}
else
return 0;
} else if (*s == 'I' || *s == 'i') {
s++;
}
sawinf = 1;
} else if (*s == 'N' || *s == 'n') {
/* XXX TODO: There are signaling NaNs and quiet NaNs. */
s++;
sawnan = 1;
} else
return 0;
if (sawinf) {
} else if (sawnan) {
} else if (s < send) {
/* we can have an optional exponent part */
if (*s == 'e' || *s == 'E') {
/* The only flag we keep is sign. Blow away any "it's UV" */
numtype &= IS_NUMBER_NEG;
s++;
s++;
do {
s++;
}
else
return 0;
}
}
s++;
if (s >= send)
return numtype;
if (valuep)
*valuep = 0;
return IS_NUMBER_IN_UV;
}
return 0;
}
{
bool negative = 0;
if (exponent == 0)
return value;
if (value == 0)
return 0;
/* On OpenVMS VAX we by default use the D_FLOAT double format,
* and that format does not have *easy* capabilities [1] for
* overflowing doubles 'silently' as IEEE fp does. We also need
* to support G_FLOAT on both VAX and Alpha, and though the exponent
* range is much larger than D_FLOAT it still doesn't do silent
* overflow. Therefore we need to detect early whether we would
* overflow (this is the behaviour of the native string-to-float
* conversion routines, and therefore of native applications, too).
*
* [1] Trying to establish a condition handler to trap floating point
* exceptions is not a good idea. */
/* In UNICOS and in certain Cray models (such as T90) there is no
* IEEE fp, and no way at all from C to catch fp overflows gracefully.
* There is something you can do if you are willing to use some
* inline assembler: the instruction is called DFI-- but that will
* disable *all* floating point interrupts, a little bit too large
* a hammer. Therefore we need to catch potential overflows before
* it's too late. */
return NV_MAX;
if (exponent < 0) {
return 0.0;
while (-exponent >= NV_MAX_10_EXP) {
/* combination does not overflow, but 10^(-exponent) does */
value /= 10;
++exponent;
}
}
} STMT_END;
#endif
if (exponent < 0) {
negative = 1;
}
/* Floating point exceptions are supposed to be turned off,
* but if we're obviously done, don't risk another iteration.
*/
if (exponent == 0) break;
}
}
}
{
NV x = 0.0;
#ifdef USE_LOCALE_NUMERIC
if (PL_numeric_local && IN_LOCALE) {
NV y;
/* Scan the number twice; once using locale and once without;
* choose the larger result (in absolute value). */
Perl_atof2(s, x);
Perl_atof2(s, y);
if ((y < 0.0 && y < x) || (y > 0.0 && y > x))
return y;
}
else
Perl_atof2(s, x);
#else
Perl_atof2(s, x);
#endif
return x;
}
char*
{
char* s = (char*)orig;
#ifdef USE_PERL_ATOF
bool negative = 0;
bool seen_digit = 0;
/* the current exponent adjust for the accumulators */
/* There is no point in processing more significant digits
* than the NV can hold. Note that NV_DIG is a lower-bound value,
* while we need an upper-bound value. We add 2 to account for this;
* since it will have been conservative on both the first and last digit.
* For example a 32-bit mantissa with an exponent of 4 would have
* exact values in the set
* 4
* 8
* ..
* 17179869172
* 17179869176
* 17179869180
*
* where for the purposes of calculating NV_DIG we would have to discount
* both the first and last digit, since neither can hold all values from
* 0..9; but for calculating the value we must examine those two digits.
*/
/* the max number we can accumulate in a UV, and still safely do 10*N+9 */
/* leading whitespace */
while (isSPACE(*s))
++s;
/* sign */
switch (*s) {
case '-':
negative = 1;
/* fall through */
case '+':
++s;
}
/* we accumulate digits into an integer; when this becomes too
* large, we add the total to NV and start again */
while (1) {
if (isDIGIT(*s)) {
seen_digit = 1;
digit = *s++ - '0';
if (seen_dp)
exp_adjust[1]++;
/* don't start counting until we see the first significant
* digit, eg the 5 in 0.00005... */
if (!sig_digits && digit == 0)
continue;
if (++sig_digits > MAX_SIG_DIGITS) {
/* limits of precision reached */
if (digit > 5) {
++accumulator[seen_dp];
} else if (digit == 5) {
++accumulator[seen_dp];
}
}
if (seen_dp) {
exp_adjust[1]--;
} else {
exp_adjust[0]++;
}
/* skip remaining digits */
while (isDIGIT(*s)) {
++s;
if (! seen_dp) {
exp_adjust[0]++;
}
}
/* warn of loss of precision? */
}
else {
/* add accumulator to result and start again */
accumulator[seen_dp] = 0;
}
}
}
seen_dp = 1;
if (sig_digits > MAX_SIG_DIGITS) {
++s;
while (isDIGIT(*s)) {
++s;
}
break;
}
}
else {
break;
}
}
if (seen_dp) {
}
bool expnegative = 0;
++s;
switch (*s) {
case '-':
expnegative = 1;
/* fall through */
case '+':
++s;
}
while (isDIGIT(*s))
if (expnegative)
}
/* now apply the exponent */
if (seen_dp) {
} else {
}
/* now apply the sign */
if (negative)
#endif /* USE_PERL_ATOF */
return s;
}
long double
{
}
#endif
long double
Perl_my_frexpl(long double x, int *e) {
return (scalbnl(x, -*e));
}
#endif