Enhance sqlite3AtoF() so that it honors the USELONGDOUBLE test-control.
Enable the test/atof1.test module on non-intel platforms. FossilOrigin-Name: b7850fd480535980d66f107c2746e7f7fc0a5379ec8244d84f7785533c83f276
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
C Whether\sor\snot\sto\suse\sthe\slong-double\sfloating\spoint\sconversion\stechnique\nis\snow\sa\stest-control\ssetting.
|
||||
D 2023-07-03T14:56:49.741
|
||||
C Enhance\ssqlite3AtoF()\sso\sthat\sit\shonors\sthe\sUSELONGDOUBLE\stest-control.\nEnable\sthe\stest/atof1.test\smodule\son\snon-intel\splatforms.
|
||||
D 2023-07-03T18:18:35.350
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@@ -705,7 +705,7 @@ F src/trigger.c ad6ab9452715fa9a8075442e15196022275b414b9141b566af8cdb7a1605f2b0
|
||||
F src/update.c 0aa36561167a7c40d01163238c297297962f31a15a8d742216b3c37cdf25f731
|
||||
F src/upsert.c 5303dc6c518fa7d4b280ec65170f465c7a70b7ac2b22491598f6d0b4875b3145
|
||||
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
|
||||
F src/util.c 452f1e5e4a85b7869daf15d9b6468ac754836467004fa04c3419f2bd628eb6ad
|
||||
F src/util.c 5c6a3c7a88af0cbabb17707314b07f6026410610be73c6b6fba163b1cbf8b5ea
|
||||
F src/vacuum.c 604fcdaebe76f3497c855afcbf91b8fa5046b32de3045bab89cc008d68e40104
|
||||
F src/vdbe.c 74282a947234513872a83b0bab1b8c644ece64b3e27b053ef17677c8ff9c81e0
|
||||
F src/vdbe.h 41485521f68e9437fdb7ec4a90f9d86ab294e9bb8281e33b235915e29122cfc0
|
||||
@@ -775,7 +775,7 @@ F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b
|
||||
F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7
|
||||
F test/async4.test 1787e3952128aa10238bf39945126de7ca23685a
|
||||
F test/async5.test 383ab533fdb9f7ad228cc99ee66e1acb34cc0dc0
|
||||
F test/atof1.test 191ce0d7b0d527aafeafe659c31e2433e430324b5ebce3fb066178b4d9035767
|
||||
F test/atof1.test f2765d7fdc1348ae58b279d096d301a208e46da623213877b2ba580dc2768975
|
||||
F test/atomic.test 065a453dde33c77ff586d91ccaa6ed419829d492dbb1a5694b8a09f3f9d7d061
|
||||
F test/atomic2.test b6863b4aa552543874f80b42fb3063f1c8c2e3d8e56b6562f00a3cc347b5c1da
|
||||
F test/atrc.c c388fac43dbba05c804432a7135ae688b32e8f25818e9994ffba4b64cf60c27c
|
||||
@@ -2042,8 +2042,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 9435ed76cd9bb1be02768b3853a2323834f67bda75d3e3f76f6aa7bd0bade3d7
|
||||
R c19a4cd19e732c53bd925a8fc2b0f976
|
||||
P 02ae6caff1f7925c696ad263fe78b1036364d24b6373e1baec10d53aafb14a12
|
||||
R bad32f05b3c6a0ddbf09f09fc45b76f6
|
||||
U drh
|
||||
Z ccc178a785227b10fda86cb46a381790
|
||||
Z 7edb4dd9862f63ed43ef736b26696576
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
02ae6caff1f7925c696ad263fe78b1036364d24b6373e1baec10d53aafb14a12
|
||||
b7850fd480535980d66f107c2746e7f7fc0a5379ec8244d84f7785533c83f276
|
||||
+93
-132
@@ -386,43 +386,34 @@ u8 sqlite3StrIHash(const char *z){
|
||||
return h;
|
||||
}
|
||||
|
||||
/*
|
||||
** Compute 10 to the E-th power. Examples: E==1 results in 10.
|
||||
** E==2 results in 100. E==50 results in 1.0e50.
|
||||
/* Double-Double multiplication. *(z,zz) = (x,xx) * (y,yy)
|
||||
**
|
||||
** This routine only works for values of E between 1 and 341.
|
||||
** Reference:
|
||||
** T. J. Dekker, "A Floating-Point Technique for Extending the
|
||||
** Available Precision". 1971-07-26.
|
||||
*/
|
||||
static LONGDOUBLE_TYPE sqlite3Pow10(int E){
|
||||
#if defined(_MSC_VER)
|
||||
static const LONGDOUBLE_TYPE x[] = {
|
||||
1.0e+001L,
|
||||
1.0e+002L,
|
||||
1.0e+004L,
|
||||
1.0e+008L,
|
||||
1.0e+016L,
|
||||
1.0e+032L,
|
||||
1.0e+064L,
|
||||
1.0e+128L,
|
||||
1.0e+256L
|
||||
};
|
||||
LONGDOUBLE_TYPE r = 1.0;
|
||||
int i;
|
||||
assert( E>=0 && E<=307 );
|
||||
for(i=0; E!=0; i++, E >>=1){
|
||||
if( E & 1 ) r *= x[i];
|
||||
}
|
||||
return r;
|
||||
#else
|
||||
LONGDOUBLE_TYPE x = 10.0;
|
||||
LONGDOUBLE_TYPE r = 1.0;
|
||||
while(1){
|
||||
if( E & 1 ) r *= x;
|
||||
E >>= 1;
|
||||
if( E==0 ) break;
|
||||
x *= x;
|
||||
}
|
||||
return r;
|
||||
#endif
|
||||
static void dekkerMul2(
|
||||
double x, double xx,
|
||||
double y, double yy,
|
||||
double *z, double *zz
|
||||
){
|
||||
double hx, tx, hy, ty, p, q, c, cc;
|
||||
u64 m;
|
||||
memcpy(&m, &x, 8);
|
||||
m &= 0xfffffffffc000000L;
|
||||
memcpy(&hx, &m, 8);
|
||||
tx = x - hx;
|
||||
memcpy(&m, &y, 8);
|
||||
m &= 0xfffffffffc000000L;
|
||||
memcpy(&hy, &m, 8);
|
||||
ty = y - hy;
|
||||
p = hx*hy;
|
||||
q = hx*ty + tx*hy;
|
||||
c = p+q;
|
||||
cc = p - c + q + tx*ty;
|
||||
cc = x*yy + xx*y + cc;
|
||||
*z = c + cc;
|
||||
*zz = c - *z + cc;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -463,12 +454,11 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
|
||||
const char *zEnd;
|
||||
/* sign * significand * (10 ^ (esign * exponent)) */
|
||||
int sign = 1; /* sign of significand */
|
||||
i64 s = 0; /* significand */
|
||||
u64 s = 0; /* significand */
|
||||
int d = 0; /* adjust exponent for shifting decimal point */
|
||||
int esign = 1; /* sign of exponent */
|
||||
int e = 0; /* exponent */
|
||||
int eValid = 1; /* True exponent is either not used or is well-formed */
|
||||
LONGDOUBLE_TYPE result;
|
||||
int nDigit = 0; /* Number of digits processed */
|
||||
int eType = 1; /* 1: pure integer, 2+: fractional -1 or less: bad UTF16 */
|
||||
|
||||
@@ -508,7 +498,7 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
|
||||
while( z<zEnd && sqlite3Isdigit(*z) ){
|
||||
s = s*10 + (*z - '0');
|
||||
z+=incr; nDigit++;
|
||||
if( s>=((LARGEST_INT64-9)/10) ){
|
||||
if( s>=((LARGEST_UINT64-9)/10) ){
|
||||
/* skip non-significant significand digits
|
||||
** (increase exponent by d to shift decimal left) */
|
||||
while( z<zEnd && sqlite3Isdigit(*z) ){ z+=incr; d++; }
|
||||
@@ -523,7 +513,7 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
|
||||
/* copy digits from after decimal to significand
|
||||
** (decrease exponent by d to shift decimal right) */
|
||||
while( z<zEnd && sqlite3Isdigit(*z) ){
|
||||
if( s<((LARGEST_INT64-9)/10) ){
|
||||
if( s<((LARGEST_UINT64-9)/10) ){
|
||||
s = s*10 + (*z - '0');
|
||||
d--;
|
||||
nDigit++;
|
||||
@@ -563,78 +553,79 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
|
||||
while( z<zEnd && sqlite3Isspace(*z) ) z+=incr;
|
||||
|
||||
do_atof_calc:
|
||||
/* Zero is a special case */
|
||||
if( s==0 ){
|
||||
*pResult = sign<0 ? -0.0 : +0.0;
|
||||
goto atof_return;
|
||||
}
|
||||
|
||||
/* adjust exponent by d, and update sign */
|
||||
e = (e*esign) + d;
|
||||
if( e<0 ) {
|
||||
esign = -1;
|
||||
e *= -1;
|
||||
} else {
|
||||
esign = 1;
|
||||
|
||||
/* Try to adjust the exponent to make it smaller */
|
||||
while( e>0 && s<(LARGEST_UINT64/10) ){
|
||||
s *= 10;
|
||||
e--;
|
||||
}
|
||||
while( e<0 && (s%10)==0 ){
|
||||
s /= 10;
|
||||
e++;
|
||||
}
|
||||
|
||||
if( s==0 ) {
|
||||
/* In the IEEE 754 standard, zero is signed. */
|
||||
result = sign<0 ? -(double)0 : (double)0;
|
||||
} else {
|
||||
/* Attempt to reduce exponent.
|
||||
**
|
||||
** Branches that are not required for the correct answer but which only
|
||||
** help to obtain the correct answer faster are marked with special
|
||||
** comments, as a hint to the mutation tester.
|
||||
*/
|
||||
while( e>0 ){ /*OPTIMIZATION-IF-TRUE*/
|
||||
if( esign>0 ){
|
||||
if( s>=(LARGEST_INT64/10) ) break; /*OPTIMIZATION-IF-FALSE*/
|
||||
s *= 10;
|
||||
}else{
|
||||
if( s%10!=0 ) break; /*OPTIMIZATION-IF-FALSE*/
|
||||
s /= 10;
|
||||
}
|
||||
e--;
|
||||
}
|
||||
|
||||
/* adjust the sign of significand */
|
||||
s = sign<0 ? -s : s;
|
||||
|
||||
if( e==0 ){ /*OPTIMIZATION-IF-TRUE*/
|
||||
result = (LONGDOUBLE_TYPE)s;
|
||||
if( e==0 ){
|
||||
*pResult = s;
|
||||
}else if( sqlite3Config.bUseLongDouble ){
|
||||
LONGDOUBLE_TYPE r = (LONGDOUBLE_TYPE)s;
|
||||
if( e>0 ){
|
||||
while( e>=100 ){ e-=100; r *= 1.0e+100L; }
|
||||
while( e>=10 ){ e-=10; r *= 1.0e+10L; }
|
||||
while( e>=1 ){ e-=1; r *= 1.0e+01L; }
|
||||
}else{
|
||||
/* attempt to handle extremely small/large numbers better */
|
||||
if( e>307 ){ /*OPTIMIZATION-IF-TRUE*/
|
||||
if( e<342 ){ /*OPTIMIZATION-IF-TRUE*/
|
||||
LONGDOUBLE_TYPE scale = sqlite3Pow10(e-308);
|
||||
if( esign<0 ){
|
||||
result = s / scale;
|
||||
result /= 1.0e+308L;
|
||||
}else{
|
||||
result = s * scale;
|
||||
result *= 1.0e+308L;
|
||||
}
|
||||
}else{ assert( e>=342 );
|
||||
if( esign<0 ){
|
||||
result = 0.0*s;
|
||||
}else{
|
||||
#ifdef INFINITY
|
||||
result = INFINITY*s;
|
||||
#else
|
||||
result = 1e308*1e308*s; /* Infinity */
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}else{
|
||||
LONGDOUBLE_TYPE scale = sqlite3Pow10(e);
|
||||
if( esign<0 ){
|
||||
result = s / scale;
|
||||
}else{
|
||||
result = s * scale;
|
||||
}
|
||||
while( e<=-100 ){ e+=100; r *= 1.0e-100L; }
|
||||
while( e<=-10 ){ e+=10; r *= 1.0e-10L; }
|
||||
while( e<=-1 ){ e+=1; r *= 1.0e-01L; }
|
||||
}
|
||||
*pResult = r;
|
||||
}else{
|
||||
double r, rr;
|
||||
u64 s2;
|
||||
r = (double)s;
|
||||
s2 = (u64)r;
|
||||
rr = s>=s2 ? (double)(s - s2) : -(double)(s2 - s);
|
||||
if( e>0 ){
|
||||
while( e>=100 ){
|
||||
e -= 100;
|
||||
dekkerMul2(r, rr, 1.0e+100, -1.5902891109759918046e+83, &r, &rr);
|
||||
}
|
||||
while( e>=10 ){
|
||||
e -= 10;
|
||||
dekkerMul2(r, rr, 1.0e+10, 0.0, &r, &rr);
|
||||
}
|
||||
while( e>=1 ){
|
||||
e -= 1;
|
||||
dekkerMul2(r, rr, 1.0e+01, 0.0, &r, &rr);
|
||||
}
|
||||
}else{
|
||||
while( e<=-100 ){
|
||||
e += 100;
|
||||
dekkerMul2(r, rr, 1.0e-100, -1.99918998026028836196e-117, &r, &rr);
|
||||
}
|
||||
while( e<=-10 ){
|
||||
e += 10;
|
||||
dekkerMul2(r,rr, 1.0e-10, -3.6432197315497741579e-27, &r, &rr);
|
||||
}
|
||||
while( e<=-1 ){
|
||||
e += 1;
|
||||
dekkerMul2(r,rr, 1.0e-01, -5.5511151231257827021e-18, &r, &rr);
|
||||
}
|
||||
}
|
||||
*pResult = r+rr;
|
||||
if( sqlite3IsNaN(*pResult) ) *pResult = 1e300*1e300;
|
||||
}
|
||||
if( sign<0 ) *pResult = -*pResult;
|
||||
assert( !sqlite3IsNaN(*pResult) );
|
||||
|
||||
/* store the result */
|
||||
*pResult = result;
|
||||
|
||||
atof_return:
|
||||
/* return true if number and no extra non-whitespace characters after */
|
||||
if( z==zEnd && nDigit>0 && eValid && eType>0 ){
|
||||
return eType;
|
||||
@@ -928,36 +919,6 @@ int sqlite3Atoi(const char *z){
|
||||
return x;
|
||||
}
|
||||
|
||||
/* Double-Double multiplication. *(z,zz) = (x,xx) * (y,yy)
|
||||
**
|
||||
** Reference:
|
||||
** T. J. Dekker, "A Floating-Point Technique for Extending the
|
||||
** Available Precision". 1971-07-26.
|
||||
*/
|
||||
static void dekkerMul2(
|
||||
double x, double xx,
|
||||
double y, double yy,
|
||||
double *z, double *zz
|
||||
){
|
||||
double hx, tx, hy, ty, p, q, c, cc;
|
||||
u64 m;
|
||||
memcpy(&m, &x, 8);
|
||||
m &= 0xfffffffffc000000L;
|
||||
memcpy(&hx, &m, 8);
|
||||
tx = x - hx;
|
||||
memcpy(&m, &y, 8);
|
||||
m &= 0xfffffffffc000000L;
|
||||
memcpy(&hy, &m, 8);
|
||||
ty = y - hy;
|
||||
p = hx*hy;
|
||||
q = hx*ty + tx*hy;
|
||||
c = p+q;
|
||||
cc = p - c + q + tx*ty;
|
||||
cc = x*yy + xx*y + cc;
|
||||
*z = c + cc;
|
||||
*zz = c - *z + cc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Decode a floating-point value into an approximate decimal
|
||||
** representation.
|
||||
|
||||
+2
-10
@@ -15,18 +15,10 @@
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
if {$::longdouble_size<=8} {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
if {$::tcl_platform(machine)!="x86_64"} {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
set mxpow [expr {[use_long_double]?100:35}]
|
||||
expr srand(1)
|
||||
for {set i 1} {$i<20000} {incr i} {
|
||||
set pow [expr {int((rand()-0.5)*100)}]
|
||||
set pow [expr {int((rand()-0.5)*$mxpow)}]
|
||||
set x [expr {pow((rand()-0.5)*2*rand(),$pow)}]
|
||||
set xf [format %.32e $x]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user