mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-11 01:42:22 +03:00
An idea for improving accuracy of fp-to-decimal conversion for systems that
do not have "long double". Does not quite work. Retained only for documentation purposes. FossilOrigin-Name: 702243333843219f8904ee0fd12283080d6c6b3fc1ffb36c534cdefb3563c00d
This commit is contained in:
15
manifest
15
manifest
@@ -1,5 +1,5 @@
|
|||||||
C This\scheck-in\sadds\sthe\suse\sof\s"long\sdouble"\sto\ssqlite3FpDecode()\swhich\swhen\nrun\son\sx86\susing\sa\scompiler\sthat\stranslates\s"long\sdouble"\sinto\sbinary80,\ncauses\sall\slegacy\stests\sto\spass.\s\sBut\son\sa\ssystem\swhere\s"long\sdouble"\sis\sjust\nan\salias\sfor\s"double",\ssome\sof\sthe\stests\sare\sstill\sfailing.
|
C An\sidea\sfor\simproving\saccuracy\sof\sfp-to-decimal\sconversion\sfor\ssystems\sthat\ndo\snot\shave\s"long\sdouble".\s\sDoes\snot\squite\swork.\s\sRetained\sonly\sfor\ndocumentation\spurposes.
|
||||||
D 2023-07-01T20:21:27.087
|
D 2023-07-03T00:40:37.359
|
||||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||||
@@ -705,7 +705,7 @@ F src/trigger.c ad6ab9452715fa9a8075442e15196022275b414b9141b566af8cdb7a1605f2b0
|
|||||||
F src/update.c 0aa36561167a7c40d01163238c297297962f31a15a8d742216b3c37cdf25f731
|
F src/update.c 0aa36561167a7c40d01163238c297297962f31a15a8d742216b3c37cdf25f731
|
||||||
F src/upsert.c 5303dc6c518fa7d4b280ec65170f465c7a70b7ac2b22491598f6d0b4875b3145
|
F src/upsert.c 5303dc6c518fa7d4b280ec65170f465c7a70b7ac2b22491598f6d0b4875b3145
|
||||||
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
|
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
|
||||||
F src/util.c d68692390be083744bd0dfafc797472b0d304743040220e18b93bc9bad8c8d6e
|
F src/util.c 12741de9969af5134488b7c89a97ecc22144f93f62c6255f797abb9b3121608a
|
||||||
F src/vacuum.c 604fcdaebe76f3497c855afcbf91b8fa5046b32de3045bab89cc008d68e40104
|
F src/vacuum.c 604fcdaebe76f3497c855afcbf91b8fa5046b32de3045bab89cc008d68e40104
|
||||||
F src/vdbe.c 74282a947234513872a83b0bab1b8c644ece64b3e27b053ef17677c8ff9c81e0
|
F src/vdbe.c 74282a947234513872a83b0bab1b8c644ece64b3e27b053ef17677c8ff9c81e0
|
||||||
F src/vdbe.h 41485521f68e9437fdb7ec4a90f9d86ab294e9bb8281e33b235915e29122cfc0
|
F src/vdbe.h 41485521f68e9437fdb7ec4a90f9d86ab294e9bb8281e33b235915e29122cfc0
|
||||||
@@ -2041,8 +2041,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P 07eab52e0801bb0e4743b304a06ad16e18cdf8eaa18c0faf8d47a1f5d8576ea0
|
P ce06982f880339cf46704e95c907249827c3e44af2b9420005200ca8abd3f371
|
||||||
R c4051b06b266c29a490b4cec354913fc
|
R ae7783ab51788007ac81a8600cb6b0a8
|
||||||
|
T *branch * fp-to-decimal-branch1
|
||||||
|
T *sym-fp-to-decimal-branch1 *
|
||||||
|
T -sym-fp-to-decimal-refactor *
|
||||||
U drh
|
U drh
|
||||||
Z 95eef79511e3e10371b4b76031a5a06d
|
Z 0f216e6dd96bccb8187eb2a64c983082
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
ce06982f880339cf46704e95c907249827c3e44af2b9420005200ca8abd3f371
|
702243333843219f8904ee0fd12283080d6c6b3fc1ffb36c534cdefb3563c00d
|
||||||
64
src/util.c
64
src/util.c
@@ -937,16 +937,18 @@ int sqlite3Atoi(const char *z){
|
|||||||
** decimal point if n is negative. No rounding is performed if
|
** decimal point if n is negative. No rounding is performed if
|
||||||
** n is zero.
|
** n is zero.
|
||||||
*/
|
*/
|
||||||
void sqlite3FpDecode(FpDecode *p, double rr, int iRound, int mxRound){
|
void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRound){
|
||||||
int i;
|
int i;
|
||||||
u64 v;
|
u64 v;
|
||||||
int e, exp = 0;
|
int e, exp = 0;
|
||||||
long double r;
|
|
||||||
p->isSpecial = 0;
|
p->isSpecial = 0;
|
||||||
if( rr<0.0 ){
|
|
||||||
|
/* Convert negative numbers to positive. Deal with Infinity, 0.0, and
|
||||||
|
** NaN. */
|
||||||
|
if( r<0.0 ){
|
||||||
p->sign = '-';
|
p->sign = '-';
|
||||||
rr = -rr;
|
r = -r;
|
||||||
}else if( rr==0.0 ){
|
}else if( r==0.0 ){
|
||||||
p->sign = '+';
|
p->sign = '+';
|
||||||
p->n = 1;
|
p->n = 1;
|
||||||
p->iDP = 1;
|
p->iDP = 1;
|
||||||
@@ -955,7 +957,7 @@ void sqlite3FpDecode(FpDecode *p, double rr, int iRound, int mxRound){
|
|||||||
}else{
|
}else{
|
||||||
p->sign = '+';
|
p->sign = '+';
|
||||||
}
|
}
|
||||||
memcpy(&v,&rr,8);
|
memcpy(&v,&r,8);
|
||||||
e = v>>52;
|
e = v>>52;
|
||||||
if( (e&0x7ff)==0x7ff ){
|
if( (e&0x7ff)==0x7ff ){
|
||||||
p->isSpecial = 1 + (v!=0x7ff0000000000000L);
|
p->isSpecial = 1 + (v!=0x7ff0000000000000L);
|
||||||
@@ -963,23 +965,47 @@ void sqlite3FpDecode(FpDecode *p, double rr, int iRound, int mxRound){
|
|||||||
p->iDP = 0;
|
p->iDP = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
r = rr;
|
|
||||||
|
|
||||||
/* At this point, r is positive (non-zero) and is not Inf or NaN.
|
/* Multiply r by powers of ten until it lands somewhere in between
|
||||||
** The strategy is to multiple or divide r by powers of 10 until
|
** 1.0e+19 and 1.0e+17.
|
||||||
** it is in between 1.0e+17 and 1.0e+19. Then convert r into
|
|
||||||
** an unsigned 64-bit integer v, and extract digits from v.
|
|
||||||
*/
|
*/
|
||||||
if( r>=1.0e+19 ){
|
if( sizeof(long double)>8
|
||||||
while( r>=1.0e+119L ){ exp+=100; r *= 1.0e-100L; }
|
|| (v & 0x0000000000ffffffLL)==0
|
||||||
while( r>=1.0e+29L ){ exp+=10; r *= 1.0e-10L; }
|
|| (v & 0xffffffffff000000LL)==0
|
||||||
while( r>=1.0e+19L ){ exp++; r *= 1.0e-1L; }
|
){
|
||||||
|
long double rr = r;
|
||||||
|
if( rr>=1.0e+19 ){
|
||||||
|
while( rr>=1.0e+119L ){ exp+=100; rr *= 1.0e-100L; }
|
||||||
|
while( rr>=1.0e+29L ){ exp+=10; rr *= 1.0e-10L; }
|
||||||
|
while( rr>=1.0e+19L ){ exp++; rr *= 1.0e-1L; }
|
||||||
}else{
|
}else{
|
||||||
while( r<1.0e-97L ){ exp-=100; r *= 1.0e+100L; }
|
while( rr<1.0e-97L ){ exp-=100; rr *= 1.0e+100L; }
|
||||||
while( r<1.0e+07L ){ exp-=10; r *= 1.0e+10L; }
|
while( rr<1.0e+07L ){ exp-=10; rr *= 1.0e+10L; }
|
||||||
while( r<1.0e+17L ){ exp--; r *= 1.0e+1L; }
|
while( rr<1.0e+17L ){ exp--; rr *= 1.0e+1L; }
|
||||||
}
|
}
|
||||||
v = (u64)r;
|
v = (u64)rr;
|
||||||
|
}else{
|
||||||
|
double r2, r3;
|
||||||
|
v &= 0xffffffffff000000LL;
|
||||||
|
memcpy(&r2, &v, 8);
|
||||||
|
assert( r2<r );
|
||||||
|
assert( r2>0.0 );
|
||||||
|
r3 = r - r2;
|
||||||
|
assert( r3>0.0 );
|
||||||
|
if( r2>=1.0e+19 ){
|
||||||
|
while( r2>=1.0e+119L ){ exp+=100; r2 *= 1.0e-100; r3 *= 1.0e-100; }
|
||||||
|
while( r2>=1.0e+29L ){ exp+=10; r2 *= 1.0e-10; r3 *= 1.0e-10; }
|
||||||
|
while( r2>=1.0e+19L ){ exp++; r2 *= 1.0e-1; r3 *= 1.0e-1; }
|
||||||
|
}else{
|
||||||
|
while( r2<1.0e-97L ){ exp-=100; r2 *= 1.0e+100; r3 *= 1.0e+100; }
|
||||||
|
while( r2<1.0e+07L ){ exp-=10; r2 *= 1.0e+10; r3 *= 1.0e+10; }
|
||||||
|
while( r2<1.0e+17L ){ exp--; r2 *= 1.0e+1; r3 *= 1.0e+1; }
|
||||||
|
}
|
||||||
|
v = (u64)(r2+r3);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Extract significant digits. */
|
||||||
i = sizeof(p->z)-1;
|
i = sizeof(p->z)-1;
|
||||||
while( v ){ p->z[i--] = (v%10) + '0'; v /= 10; }
|
while( v ){ p->z[i--] = (v%10) + '0'; v /= 10; }
|
||||||
p->n = sizeof(p->z) - 1 - i;
|
p->n = sizeof(p->z) - 1 - i;
|
||||||
|
|||||||
Reference in New Issue
Block a user