-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
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
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
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.
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;
}
/*
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 */
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++; }
/* 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++;
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;
- }
-
- 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;
+ /* 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( 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;
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.