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
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to