new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <math.h>
|
|
|
|
#include <float.h>
|
|
|
|
#include <limits.h>
|
2012-04-10 22:38:21 -04:00
|
|
|
#include <errno.h>
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
|
2012-04-10 21:47:37 -04:00
|
|
|
#include "shgetc.h"
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
#include "floatscan.h"
|
|
|
|
|
|
|
|
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
|
|
|
|
|
|
|
#define LD_B1B_DIG 2
|
|
|
|
#define LD_B1B_MAX 9007199, 254740991
|
|
|
|
#define KMAX 128
|
|
|
|
|
|
|
|
#else /* LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 */
|
|
|
|
|
|
|
|
#define LD_B1B_DIG 3
|
|
|
|
#define LD_B1B_MAX 18, 446744073, 709551615
|
|
|
|
#define KMAX 2048
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define MASK (KMAX-1)
|
|
|
|
|
|
|
|
|
2012-04-10 21:47:37 -04:00
|
|
|
static long long scanexp(FILE *f, int pok)
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
{
|
|
|
|
int c;
|
|
|
|
int x;
|
|
|
|
long long y;
|
|
|
|
int neg = 0;
|
|
|
|
|
2012-04-10 21:47:37 -04:00
|
|
|
c = shgetc(f);
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
if (c=='+' || c=='-') {
|
|
|
|
neg = (c=='-');
|
2012-04-10 21:47:37 -04:00
|
|
|
c = shgetc(f);
|
|
|
|
if (c-'0'>=10U && pok) shunget(f);
|
|
|
|
}
|
|
|
|
if (c-'0'>=10U) {
|
|
|
|
shunget(f);
|
|
|
|
return LLONG_MIN;
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
}
|
2012-04-10 21:47:37 -04:00
|
|
|
for (x=0; c-'0'<10U && x<INT_MAX/10; c = shgetc(f))
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
x = 10*x + c-'0';
|
2012-04-10 23:05:16 -04:00
|
|
|
for (y=x; c-'0'<10U && x<LLONG_MAX/100; c = shgetc(f))
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
y = 10*y + c-'0';
|
2012-04-10 21:47:37 -04:00
|
|
|
for (; c-'0'<10U; c = shgetc(f));
|
|
|
|
shunget(f);
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
return neg ? -y : y;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-04-10 21:47:37 -04:00
|
|
|
static long double decfloat(FILE *f, int bits, int emin, int sign, int pok)
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
{
|
|
|
|
uint32_t x[KMAX];
|
|
|
|
static const uint32_t th[] = { LD_B1B_MAX };
|
|
|
|
int i, j, k, a, z;
|
|
|
|
long long lrp=-1, dc=0;
|
2012-04-10 21:47:37 -04:00
|
|
|
long long e10=0;
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
int gotdig = 0;
|
|
|
|
int rp;
|
|
|
|
int e2;
|
|
|
|
long double y;
|
|
|
|
long double frac=0;
|
|
|
|
long double bias=0;
|
2012-04-10 21:47:37 -04:00
|
|
|
int c;
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
|
|
|
|
j=0;
|
|
|
|
k=0;
|
|
|
|
|
2012-04-10 21:47:37 -04:00
|
|
|
c = shgetc(f);
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
|
|
|
|
/* Don't let leading zeros consume buffer space */
|
2012-04-10 21:47:37 -04:00
|
|
|
for (; c=='0'; c = shgetc(f)) gotdig=1;
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
|
|
|
|
x[0] = 0;
|
2012-04-10 21:47:37 -04:00
|
|
|
for (; c-'0'<10U || c=='.'; c = shgetc(f)) {
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
if (c == '.') {
|
|
|
|
if (lrp!=-1) break;
|
|
|
|
lrp = dc;
|
|
|
|
} else if (k < KMAX) {
|
|
|
|
dc++;
|
|
|
|
if (j) x[k] = x[k]*10 + c-'0';
|
|
|
|
else x[k] = c-'0';
|
|
|
|
if (++j==9) {
|
|
|
|
k++;
|
|
|
|
j=0;
|
|
|
|
}
|
|
|
|
gotdig=1;
|
|
|
|
} else {
|
|
|
|
dc++;
|
|
|
|
x[KMAX-1] |= c-'0';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (lrp==-1) lrp=dc;
|
|
|
|
|
|
|
|
if (gotdig && (c|32)=='e') {
|
2012-04-10 21:47:37 -04:00
|
|
|
e10 = scanexp(f, pok);
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
if (e10 == LLONG_MIN) {
|
2012-04-10 21:47:37 -04:00
|
|
|
if (pok) {
|
|
|
|
shunget(f);
|
|
|
|
} else {
|
|
|
|
shlim(f, 0);
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
e10 = 0;
|
|
|
|
}
|
|
|
|
lrp += e10;
|
|
|
|
} else if (c>=0) {
|
2012-04-10 21:47:37 -04:00
|
|
|
shunget(f);
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
}
|
|
|
|
if (!gotdig) {
|
2012-04-10 22:38:21 -04:00
|
|
|
errno = EINVAL;
|
2012-04-10 21:47:37 -04:00
|
|
|
shlim(f, 0);
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!x[0])
|
|
|
|
return sign * 0.0;
|
|
|
|
if (lrp==dc && (!k || (k==1 && !j)) && (bits>30 || x[0]>>bits==0))
|
|
|
|
return sign * (long double)x[0];
|
2012-04-10 22:38:21 -04:00
|
|
|
if (lrp > -emin/2) {
|
|
|
|
errno = ERANGE;
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
return sign * LDBL_MAX * LDBL_MAX;
|
2012-04-10 22:38:21 -04:00
|
|
|
}
|
|
|
|
if (lrp < emin-2*LDBL_MANT_DIG) {
|
|
|
|
errno = ERANGE;
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
return sign * LDBL_MIN * LDBL_MIN;
|
2012-04-10 22:38:21 -04:00
|
|
|
}
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
|
|
|
|
if (k<KMAX && j) {
|
|
|
|
for (; j<9; j++) x[k]*=10;
|
|
|
|
k++;
|
|
|
|
j=0;
|
|
|
|
}
|
|
|
|
|
|
|
|
a = 0;
|
|
|
|
z = k;
|
|
|
|
e2 = 0;
|
|
|
|
rp = lrp;
|
|
|
|
|
|
|
|
while (rp < 18+9*LD_B1B_DIG) {
|
|
|
|
uint32_t carry = 0;
|
|
|
|
e2 -= 29;
|
|
|
|
for (k=(z-1 & MASK); ; k=(k-1 & MASK)) {
|
|
|
|
uint64_t tmp = ((uint64_t)x[k] << 29) + carry;
|
|
|
|
if (tmp > 1000000000) {
|
|
|
|
carry = tmp / 1000000000;
|
|
|
|
x[k] = tmp % 1000000000;
|
|
|
|
} else {
|
|
|
|
carry = 0;
|
|
|
|
x[k] = tmp;
|
|
|
|
}
|
|
|
|
if (k==(z-1 & MASK) && k!=a && !x[k]) z = k;
|
|
|
|
if (k==a) break;
|
|
|
|
}
|
|
|
|
if (carry) {
|
|
|
|
rp += 9;
|
|
|
|
if (a == z) {
|
|
|
|
z = (z-1 & MASK);
|
|
|
|
x[z-1 & MASK] |= x[z];
|
|
|
|
}
|
|
|
|
a = (a-1 & MASK);
|
|
|
|
x[a] = carry;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rp % 9) {
|
|
|
|
static const int p10s[] = {
|
|
|
|
100000000, 10000000, 1000000, 100000,
|
|
|
|
10000, 1000, 100, 10
|
|
|
|
};
|
|
|
|
int rpm9 = rp % 9;
|
|
|
|
int p10 = p10s[rpm9-1];
|
|
|
|
uint32_t carry = 0;
|
|
|
|
for (k=a; k!=z; k=(k+1 & MASK)) {
|
|
|
|
uint32_t tmp = x[k] % p10;
|
|
|
|
x[k] = x[k]/p10 + carry;
|
|
|
|
carry = 1000000000/p10 * tmp;
|
|
|
|
if (k==a && !x[k]) {
|
|
|
|
a = (a+1 & MASK);
|
|
|
|
rp -= 9;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (carry) {
|
|
|
|
if ((z+1 & MASK) != a) {
|
|
|
|
x[z] = carry;
|
|
|
|
z = (z+1 & MASK);
|
|
|
|
} else x[z-1 & MASK] |= 1;
|
|
|
|
}
|
|
|
|
rp += 9-rpm9;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
uint32_t carry = 0;
|
|
|
|
int sh = 1;
|
|
|
|
for (i=0; i<LD_B1B_DIG; i++) {
|
|
|
|
k = (a+i & MASK);
|
|
|
|
if (k == z || x[k] < th[i]) {
|
|
|
|
i=LD_B1B_DIG;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (x[a+i & MASK] > th[i]) break;
|
|
|
|
}
|
|
|
|
if (i==LD_B1B_DIG && rp==9*LD_B1B_DIG) break;
|
|
|
|
/* FIXME: find a way to compute optimal sh */
|
|
|
|
if (rp > 9+9*LD_B1B_DIG) sh = 9;
|
|
|
|
e2 += sh;
|
|
|
|
for (k=a; k!=z; k=(k+1 & MASK)) {
|
|
|
|
uint32_t tmp = x[k] & (1<<sh)-1;
|
|
|
|
x[k] = (x[k]>>sh) + carry;
|
|
|
|
carry = (1000000000>>sh) * tmp;
|
|
|
|
if (k==a && !x[k]) {
|
|
|
|
a = (a+1 & MASK);
|
|
|
|
rp -= 9;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (carry) {
|
|
|
|
if ((z+1 & MASK) != a) {
|
|
|
|
x[z] = carry;
|
|
|
|
z = (z+1 & MASK);
|
|
|
|
} else x[z-1 & MASK] |= 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-10 23:41:54 -04:00
|
|
|
for (y=i=0; i<LD_B1B_DIG; i++) {
|
|
|
|
if ((a+i & MASK)==z) x[z=(z+1 & MASK)] = 0;
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
y = 1000000000.0L * y + x[a+i & MASK];
|
2012-04-10 23:41:54 -04:00
|
|
|
}
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
|
|
|
|
y *= sign;
|
|
|
|
|
|
|
|
if (bits > LDBL_MANT_DIG+e2-emin) {
|
|
|
|
bits = LDBL_MANT_DIG+e2-emin;
|
|
|
|
if (bits<0) bits=0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bits < LDBL_MANT_DIG) {
|
|
|
|
bias = copysignl(scalbn(1, 2*LDBL_MANT_DIG-bits-1), y);
|
|
|
|
frac = fmodl(y, scalbn(1, LDBL_MANT_DIG-bits));
|
|
|
|
y -= frac;
|
|
|
|
y += bias;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((a+i & MASK) != z) {
|
|
|
|
uint32_t t = x[a+i & MASK];
|
|
|
|
if (t < 500000000 && (t || (a+i+1 & MASK) != z))
|
|
|
|
frac += 0.25*sign;
|
|
|
|
else if (t > 500000000)
|
|
|
|
frac += 0.75*sign;
|
|
|
|
else if (t == 500000000) {
|
|
|
|
if ((a+i+1 & MASK) == z)
|
|
|
|
frac += 0.5*sign;
|
|
|
|
else
|
|
|
|
frac += 0.75*sign;
|
|
|
|
}
|
|
|
|
if (LDBL_MANT_DIG-bits >= 2 && !fmodl(frac, 1))
|
|
|
|
frac++;
|
|
|
|
}
|
|
|
|
|
|
|
|
y += frac;
|
|
|
|
y -= bias;
|
|
|
|
|
|
|
|
y = scalbnl(y, e2);
|
|
|
|
|
2012-04-10 22:38:21 -04:00
|
|
|
if (!y) errno = ERANGE;
|
|
|
|
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
return y;
|
|
|
|
}
|
|
|
|
|
2012-04-10 21:47:37 -04:00
|
|
|
static long double hexfloat(FILE *f, int bits, int emin, int sign, int pok)
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
{
|
|
|
|
uint32_t x = 0;
|
|
|
|
long double y = 0;
|
|
|
|
long double scale = 1;
|
|
|
|
long double bias = 0;
|
|
|
|
int gottail = 0, gotrad = 0, gotdig = 0;
|
|
|
|
long long rp = 0;
|
|
|
|
long long dc = 0;
|
|
|
|
long long e2 = 0;
|
|
|
|
int d;
|
2012-04-10 21:47:37 -04:00
|
|
|
int c;
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
|
2012-04-10 21:47:37 -04:00
|
|
|
c = shgetc(f);
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
|
|
|
|
/* Skip leading zeros */
|
2012-04-10 21:47:37 -04:00
|
|
|
for (; c=='0'; c = shgetc(f)) gotdig = 1;
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
|
|
|
|
if (c=='.') {
|
|
|
|
gotrad = 1;
|
2012-04-10 21:47:37 -04:00
|
|
|
c = shgetc(f);
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
/* Count zeros after the radix point before significand */
|
2012-04-10 21:47:37 -04:00
|
|
|
for (rp=0; c=='0'; c = shgetc(f), rp--) gotdig = 1;
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
}
|
|
|
|
|
2012-04-10 21:47:37 -04:00
|
|
|
for (; c-'0'<10U || (c|32)-'a'<6U || c=='.'; c = shgetc(f)) {
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
if (c=='.') {
|
|
|
|
if (gotrad) break;
|
|
|
|
rp = dc;
|
|
|
|
gotrad = 1;
|
|
|
|
} else {
|
|
|
|
gotdig = 1;
|
|
|
|
if (c > '9') d = (c|32)+10-'a';
|
|
|
|
else d = c-'0';
|
|
|
|
if (dc<8) {
|
|
|
|
x = x*16 + d;
|
|
|
|
} else if (dc < LDBL_MANT_DIG/4+1) {
|
|
|
|
y += d*(scale/=16);
|
|
|
|
} else if (d && !gottail) {
|
|
|
|
y += 0.5*scale;
|
|
|
|
gottail = 1;
|
|
|
|
}
|
|
|
|
dc++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!gotdig) {
|
2012-04-10 21:47:37 -04:00
|
|
|
shunget(f);
|
|
|
|
if (pok) {
|
|
|
|
shunget(f);
|
|
|
|
if (gotrad) shunget(f);
|
|
|
|
} else {
|
|
|
|
shlim(f, 0);
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (!gotrad) rp = dc;
|
|
|
|
while (dc<8) x *= 16, dc++;
|
|
|
|
if ((c|32)=='p') {
|
2012-04-10 21:47:37 -04:00
|
|
|
e2 = scanexp(f, pok);
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
if (e2 == LLONG_MIN) {
|
2012-04-10 21:47:37 -04:00
|
|
|
if (pok) {
|
|
|
|
shunget(f);
|
|
|
|
} else {
|
|
|
|
shlim(f, 0);
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
e2 = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
e2 += 4*rp - 32;
|
|
|
|
|
|
|
|
if (!x) return sign * 0.0;
|
2012-04-10 22:38:21 -04:00
|
|
|
if (e2 > -emin) {
|
|
|
|
errno = ERANGE;
|
|
|
|
return sign * LDBL_MAX * LDBL_MAX;
|
|
|
|
}
|
|
|
|
if (e2 < emin-2*LDBL_MANT_DIG) {
|
|
|
|
errno = ERANGE;
|
|
|
|
return sign * LDBL_MIN * LDBL_MIN;
|
|
|
|
}
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
|
|
|
|
while (x < 0x80000000) {
|
|
|
|
if (y>=0.5) {
|
|
|
|
x += x + 1;
|
|
|
|
y += y - 1;
|
|
|
|
} else {
|
|
|
|
x += x;
|
|
|
|
y += y;
|
|
|
|
}
|
|
|
|
e2--;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bits > 32+e2-emin) {
|
|
|
|
bits = 32+e2-emin;
|
|
|
|
if (bits<0) bits=0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bits < LDBL_MANT_DIG)
|
|
|
|
bias = copysignl(scalbn(1, 32+LDBL_MANT_DIG-bits-1), sign);
|
|
|
|
|
|
|
|
if (bits<32 && y && !(x&1)) x++, y=0;
|
|
|
|
|
|
|
|
y = bias + sign*(long double)x + sign*y;
|
|
|
|
y -= bias;
|
|
|
|
|
2012-04-10 22:38:21 -04:00
|
|
|
if (!y) errno = ERANGE;
|
|
|
|
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
return scalbnl(y, e2);
|
|
|
|
}
|
|
|
|
|
2012-04-10 21:47:37 -04:00
|
|
|
long double __floatscan(FILE *f, int c, int prec, int pok)
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
{
|
|
|
|
int sign = 1;
|
|
|
|
int i;
|
|
|
|
int bits;
|
|
|
|
int emin;
|
|
|
|
|
|
|
|
switch (prec) {
|
|
|
|
case 0:
|
|
|
|
bits = 24;
|
|
|
|
emin = -149;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
bits = 53;
|
|
|
|
emin = -1074;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
bits = LDBL_MANT_DIG;
|
|
|
|
emin = -16445;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-04-10 21:47:37 -04:00
|
|
|
if (c<0) c = shgetc(f);
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
|
|
|
|
if (c=='+' || c=='-') {
|
|
|
|
sign -= 2*(c=='-');
|
2012-04-10 21:47:37 -04:00
|
|
|
c = shgetc(f);
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
for (i=0; i<8 && (c|32)=="infinity"[i]; i++)
|
2012-04-10 21:47:37 -04:00
|
|
|
if (i<7) c = shgetc(f);
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
if (i==3 || i==8 || (i>3 && pok)) {
|
2012-04-10 21:47:37 -04:00
|
|
|
if (i==3) shunget(f);
|
|
|
|
if (pok) for (; i>3; i--) shunget(f);
|
|
|
|
else shlim(f, 0);
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
return sign * INFINITY;
|
|
|
|
}
|
|
|
|
if (!i) for (i=0; i<3 && (c|32)=="nan"[i]; i++)
|
2012-04-10 21:47:37 -04:00
|
|
|
if (i<3) c = shgetc(f);
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
if (i==3) {
|
2012-04-10 21:47:37 -04:00
|
|
|
return NAN;
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (i) {
|
2012-04-10 21:47:37 -04:00
|
|
|
shunget(f);
|
2012-04-10 22:38:21 -04:00
|
|
|
errno = EINVAL;
|
2012-04-10 21:47:37 -04:00
|
|
|
shlim(f, 0);
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (c=='0') {
|
2012-04-10 21:47:37 -04:00
|
|
|
c = shgetc(f);
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
if ((c|32) == 'x')
|
2012-04-10 21:47:37 -04:00
|
|
|
return hexfloat(f, bits, emin, sign, pok);
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
c = '0';
|
|
|
|
}
|
|
|
|
|
2012-04-10 21:47:37 -04:00
|
|
|
shunget(f);
|
|
|
|
return decfloat(f, bits, emin, sign, pok);
|
new floating point parser/converter
this version is intended to be fully conformant to the ISO C, POSIX,
and IEEE standards for conversion of decimal/hex floating point
strings to float, double, and long double (ld64 or ld80 only at
present) values. in particular, all results are intended to be rounded
correctly according to the current rounding mode. further, this
implementation aims to set the floating point underflow, overflow, and
inexact flags to reflect the conversion performed.
a moderate amount of testing has been performed (by nsz and myself)
prior to integration of the code in musl, but it still may have bugs.
so far, only strto(d|ld|f) use the new code. scanf integration will be
done as a separate commit, and i will add implementations of the wide
character functions later.
2012-04-10 11:52:55 -04:00
|
|
|
}
|