/ Check-in [db3ebd7c]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Improved implementation of 64-bit signed integer multiply that correctly detects overflow (and promotes to floating-point) in some corner cases. Fix for ticket [1ec41379c9c1e400]
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: db3ebd7c52cfc5fcc7be00f52e9d7c84719f7b93
User & Date: drh 2016-09-20 22:04:05
Context
2016-09-21
14:41
Update the fts5vocab table to handle "ORDER BY term" efficiently. check-in: d4928fb5 user: dan tags: trunk
2016-09-20
22:04
Improved implementation of 64-bit signed integer multiply that correctly detects overflow (and promotes to floating-point) in some corner cases. Fix for ticket [1ec41379c9c1e400] check-in: db3ebd7c user: drh tags: trunk
17:49
Fix harmless compiler warning. check-in: 72429063 user: mistachkin tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/util.c.

  1301   1301       if( (*pA)>=0 ) return 1;
  1302   1302       *pA -= iB;
  1303   1303       return 0;
  1304   1304     }else{
  1305   1305       return sqlite3AddInt64(pA, -iB);
  1306   1306     }
  1307   1307   }
  1308         -#define TWOPOWER32 (((i64)1)<<32)
  1309         -#define TWOPOWER31 (((i64)1)<<31)
  1310   1308   int sqlite3MulInt64(i64 *pA, i64 iB){
  1311   1309     i64 iA = *pA;
  1312         -  i64 iA1, iA0, iB1, iB0, r;
  1313         -
  1314         -  iA1 = iA/TWOPOWER32;
  1315         -  iA0 = iA % TWOPOWER32;
  1316         -  iB1 = iB/TWOPOWER32;
  1317         -  iB0 = iB % TWOPOWER32;
  1318         -  if( iA1==0 ){
  1319         -    if( iB1==0 ){
  1320         -      *pA *= iB;
  1321         -      return 0;
         1310  +  if( iB>0 ){
         1311  +    if( iA>LARGEST_INT64/iB ) return 1;
         1312  +    if( iA<SMALLEST_INT64/iB ) return 1;
         1313  +  }else if( iB<0 ){
         1314  +    if( iA>0 ){
         1315  +      if( iB<SMALLEST_INT64/iA ) return 1;
         1316  +    }else if( iA<0 ){
         1317  +      if( iB==SMALLEST_INT64 ) return 1;
         1318  +      if( iA==SMALLEST_INT64 ) return 1;
         1319  +      if( -iA>LARGEST_INT64/-iB ) return 1;
  1322   1320       }
  1323         -    r = iA0*iB1;
  1324         -  }else if( iB1==0 ){
  1325         -    r = iA1*iB0;
  1326         -  }else{
  1327         -    /* If both iA1 and iB1 are non-zero, overflow will result */
  1328         -    return 1;
  1329   1321     }
  1330         -  testcase( r==(-TWOPOWER31)-1 );
  1331         -  testcase( r==(-TWOPOWER31) );
  1332         -  testcase( r==TWOPOWER31 );
  1333         -  testcase( r==TWOPOWER31-1 );
  1334         -  if( r<(-TWOPOWER31) || r>=TWOPOWER31 ) return 1;
  1335         -  r *= TWOPOWER32;
  1336         -  if( sqlite3AddInt64(&r, iA0*iB0) ) return 1;
  1337         -  *pA = r;
         1322  +  *pA = iA*iB;
  1338   1323     return 0;
  1339   1324   }
  1340   1325   
  1341   1326   /*
  1342   1327   ** Compute the absolute value of a 32-bit signed integer, of possible.  Or 
  1343   1328   ** if the integer has a value of -2147483648, return +2147483647
  1344   1329   */

Changes to test/expr.test.

   304    304     test_realnum_expr expr-1.255\
   305    305         {i1=4294967296, i2=-2147483647} {i1*i2}     -9223372032559808512
   306    306     test_realnum_expr expr-1.256\
   307    307         {i1=-4294967296, i2=-2147483648} {i1*i2}    9.22337203685478e+18
   308    308     test_realnum_expr expr-1.257\
   309    309         {i1=-4294967296, i2=-2147483647} {i1*i2}    9223372032559808512
   310    310   
          311  +  test_realnum_expr expr-1.260\
          312  +      {i1=3037000500, i2=3037000500} {i1*i2}      9.22337203700025e+18
          313  +  test_realnum_expr expr-1.261\
          314  +      {i1=3037000500, i2=-3037000500} {i1*i2}     -9.22337203700025e+18
          315  +  test_realnum_expr expr-1.262\
          316  +      {i1=-3037000500, i2=3037000500} {i1*i2}     -9.22337203700025e+18
          317  +  test_realnum_expr expr-1.263\
          318  +      {i1=-3037000500, i2=-3037000500} {i1*i2}    9.22337203700025e+18
          319  +
          320  +  test_realnum_expr expr-1.264\
          321  +      {i1=3037000500, i2=3037000499} {i1*i2}      9223372033963249500
          322  +  test_realnum_expr expr-1.265\
          323  +      {i1=3037000500, i2=-3037000499} {i1*i2}     -9223372033963249500
          324  +  test_realnum_expr expr-1.266\
          325  +      {i1=-3037000500, i2=3037000499} {i1*i2}     -9223372033963249500
          326  +  test_realnum_expr expr-1.267\
          327  +      {i1=-3037000500, i2=-3037000499} {i1*i2}    9223372033963249500
          328  +
          329  +  test_realnum_expr expr-1.268\
          330  +      {i1=3037000499, i2=3037000500} {i1*i2}      9223372033963249500
          331  +  test_realnum_expr expr-1.269\
          332  +      {i1=3037000499, i2=-3037000500} {i1*i2}     -9223372033963249500
          333  +  test_realnum_expr expr-1.270\
          334  +      {i1=-3037000499, i2=3037000500} {i1*i2}     -9223372033963249500
          335  +  test_realnum_expr expr-1.271\
          336  +      {i1=-3037000499, i2=-3037000500} {i1*i2}    9223372033963249500
          337  +
   311    338   }}
   312    339   
   313    340   ifcapable floatingpoint {
   314    341     test_expr expr-2.1 {r1=1.23, r2=2.34} {r1+r2} 3.57
   315    342     test_expr expr-2.2 {r1=1.23, r2=2.34} {r1-r2} -1.11
   316    343     test_expr expr-2.3 {r1=1.23, r2=2.34} {r1*r2} 2.8782
   317    344   }