diff options
author | drh <drh@noemail.net> | 2019-05-30 00:46:37 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2019-05-30 00:46:37 +0000 |
commit | 05921223c25ae385a5e17bbf5484f5885bb78f2c (patch) | |
tree | 6d9322878bcebdab37d303524dc09ddcaac6f40d /src | |
parent | 8a3884efae47b8f762fdd7c3b0751ddca8e41243 (diff) | |
download | sqlite-05921223c25ae385a5e17bbf5484f5885bb78f2c.tar.gz sqlite-05921223c25ae385a5e17bbf5484f5885bb78f2c.zip |
Smaller and faster sqlite3IsNaN() implementation makes deserialization of
floating point values much faster.
FossilOrigin-Name: ea748edecb261f2b862d542daff6e99a6fd8879a8ace94b440d99e110577d1c1
Diffstat (limited to 'src')
-rw-r--r-- | src/sqliteInt.h | 4 | ||||
-rw-r--r-- | src/util.c | 42 | ||||
-rw-r--r-- | src/vdbeaux.c | 4 |
3 files changed, 9 insertions, 41 deletions
diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 24fabe627..542200795 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3802,8 +3802,12 @@ void sqlite3MutexWarnOnContention(sqlite3_mutex*); #endif #ifndef SQLITE_OMIT_FLOATING_POINT +# define EXP754 (((u64)0x7ff)<<52) +# define MAN754 ((((u64)1)<<52)-1) +# define IsNaN(X) (((X)&EXP754)==EXP754 && ((X)&MAN754)!=0) int sqlite3IsNaN(double); #else +# define IsNaN(X) 0 # define sqlite3IsNaN(X) 0 #endif diff --git a/src/util.c b/src/util.c index 938b6a9fb..31c88046e 100644 --- a/src/util.c +++ b/src/util.c @@ -58,47 +58,11 @@ int sqlite3FaultSim(int iTest){ #ifndef SQLITE_OMIT_FLOATING_POINT /* ** Return true if the floating point value is Not a Number (NaN). -** -** Use the math library isnan() function if compiled with SQLITE_HAVE_ISNAN. -** Otherwise, we have our own implementation that works on most systems. */ int sqlite3IsNaN(double x){ - int rc; /* The value return */ -#if !SQLITE_HAVE_ISNAN && !HAVE_ISNAN - /* - ** Systems that support the isnan() library function should probably - ** make use of it by compiling with -DSQLITE_HAVE_ISNAN. But we have - ** found that many systems do not have a working isnan() function so - ** this implementation is provided as an alternative. - ** - ** This NaN test sometimes fails if compiled on GCC with -ffast-math. - ** On the other hand, the use of -ffast-math comes with the following - ** warning: - ** - ** This option [-ffast-math] should never be turned on by any - ** -O option since it can result in incorrect output for programs - ** which depend on an exact implementation of IEEE or ISO - ** rules/specifications for math functions. - ** - ** Under MSVC, this NaN test may fail if compiled with a floating- - ** point precision mode other than /fp:precise. From the MSDN - ** documentation: - ** - ** The compiler [with /fp:precise] will properly handle comparisons - ** involving NaN. For example, x != x evaluates to true if x is NaN - ** ... - */ -#ifdef __FAST_MATH__ -# error SQLite will not work correctly with the -ffast-math option of GCC. -#endif - volatile double y = x; - volatile double z = y; - rc = (y!=z); -#else /* if HAVE_ISNAN */ - rc = isnan(x); -#endif /* HAVE_ISNAN */ - testcase( rc ); - return rc; + u64 y; + memcpy(&y,&x,sizeof(y)); + return IsNaN(y); } #endif /* SQLITE_OMIT_FLOATING_POINT */ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 98c50f362..8dd2b421a 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3652,7 +3652,7 @@ u32 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type){ ** routine so that in most cases the overhead of moving the stack pointer ** is avoided. */ -static u32 SQLITE_NOINLINE serialGet( +static u32 serialGet( const unsigned char *buf, /* Buffer to deserialize from */ u32 serial_type, /* Serial type to deserialize */ Mem *pMem /* Memory cell to write value into */ @@ -3684,7 +3684,7 @@ static u32 SQLITE_NOINLINE serialGet( assert( sizeof(x)==8 && sizeof(pMem->u.r)==8 ); swapMixedEndianFloat(x); memcpy(&pMem->u.r, &x, sizeof(x)); - pMem->flags = sqlite3IsNaN(pMem->u.r) ? MEM_Null : MEM_Real; + pMem->flags = IsNaN(x) ? MEM_Null : MEM_Real; } return 8; } |