Jan Staněk wrote:
> I'm trying to build sqlite for aarch64 (ARMv8) and one of the expression
> tests is failing (specifically e_expr-31.2.4) with:
>> Expected: [integer -9223372036854775808]
>> Got: [integer 9223372036854775807]
> From the comment, I gather that this should test correct CASTing from
> REAL to INT, and that somehow it returns the wrong extreme (largest
> positive integer instead of largest negative).
>
> Can someone point me where in the source is that implemented?
sqlite> explain select cast(123.45 as integer);
addr opcode p1 p2 p3 p4 p5 comment
---- ------------- ---- ---- ---- ------------- -- -------------
...
2 Real 0 1 0 123.45 00
3 ToInt 1 0 0 00
...
In sqlite3.c, the OP_ToInt implementation calls sqlite3VdbeMemIntegerify,
which calls sqlite3VdbeIntValue, which calls doubleToInt64:
static i64 doubleToInt64(double r){
#ifdef SQLITE_OMIT_FLOATING_POINT
/* When floating-point is omitted, double and int64 are the same thing */
return r;
#else
/*
** Many compilers we encounter do not define constants for the
** minimum and maximum 64-bit integers, or they define them
** inconsistently. And many do not understand the "LL" notation.
** So we define our own static constants here using nothing
** larger than a 32-bit integer constant.
*/
static const i64 maxInt = LARGEST_INT64;
static const i64 minInt = SMALLEST_INT64;
if( r<(double)minInt ){
return minInt;
}else if( r>(double)maxInt ){
/* minInt is correct here - not maxInt. It turns out that assigning
** a very large positive number to an integer results in a very large
** negative integer. This makes no sense, but it is what x86 hardware
** does so for compatibility we will do the same in software. */
return minInt;
}else{
return (i64)r;
}
#endif
}
... so I guess the value of SMALLEST_INT64 might not be computed correctly:
/*
** Constants for the largest and smallest possible 64-bit signed integers.
** These macros are designed to work correctly on both 32-bit and 64-bit
** compilers.
*/
#define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32))
#define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64)
Regards,
Clemens
_______________________________________________
sqlite-users mailing list
[email protected]
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users