/ 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 Unified Diffs Ignore Whitespace Patch

Changes to src/util.c.

1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323


1324
1325


1326
1327
1328


1329
1330
1331
1332
1333
1334
1335
1336

1337
1338
1339
1340
1341
1342
1343
1344
    if( (*pA)>=0 ) return 1;
    *pA -= iB;
    return 0;
  }else{
    return sqlite3AddInt64(pA, -iB);
  }
}
#define TWOPOWER32 (((i64)1)<<32)
#define TWOPOWER31 (((i64)1)<<31)
int sqlite3MulInt64(i64 *pA, i64 iB){
  i64 iA = *pA;
  i64 iA1, iA0, iB1, iB0, r;

  iA1 = iA/TWOPOWER32;
  iA0 = iA % TWOPOWER32;
  iB1 = iB/TWOPOWER32;
  iB0 = iB % TWOPOWER32;
  if( iA1==0 ){
    if( iB1==0 ){
      *pA *= iB;
      return 0;
    }
    r = iA0*iB1;


  }else if( iB1==0 ){
    r = iA1*iB0;


  }else{
    /* If both iA1 and iB1 are non-zero, overflow will result */
    return 1;


  }
  testcase( r==(-TWOPOWER31)-1 );
  testcase( r==(-TWOPOWER31) );
  testcase( r==TWOPOWER31 );
  testcase( r==TWOPOWER31-1 );
  if( r<(-TWOPOWER31) || r>=TWOPOWER31 ) return 1;
  r *= TWOPOWER32;
  if( sqlite3AddInt64(&r, iA0*iB0) ) return 1;

  *pA = r;
  return 0;
}

/*
** Compute the absolute value of a 32-bit signed integer, of possible.  Or 
** if the integer has a value of -2147483648, return +2147483647
*/







<
<


<
<
<
<
<
<
<
|
<
<
<
<
>
>
|
<
>
>
|
<
|
>
>
|
<
<
<
<
<
<
<
>
|







1301
1302
1303
1304
1305
1306
1307


1308
1309







1310




1311
1312
1313

1314
1315
1316

1317
1318
1319
1320







1321
1322
1323
1324
1325
1326
1327
1328
1329
    if( (*pA)>=0 ) return 1;
    *pA -= iB;
    return 0;
  }else{
    return sqlite3AddInt64(pA, -iB);
  }
}


int sqlite3MulInt64(i64 *pA, i64 iB){
  i64 iA = *pA;







  if( iB>0 ){




    if( iA>LARGEST_INT64/iB ) return 1;
    if( iA<SMALLEST_INT64/iB ) return 1;
  }else if( iB<0 ){

    if( iA>0 ){
      if( iB<SMALLEST_INT64/iA ) return 1;
    }else if( iA<0 ){

      if( iB==SMALLEST_INT64 ) return 1;
      if( iA==SMALLEST_INT64 ) return 1;
      if( -iA>LARGEST_INT64/-iB ) return 1;
    }







  }
  *pA = iA*iB;
  return 0;
}

/*
** Compute the absolute value of a 32-bit signed integer, of possible.  Or 
** if the integer has a value of -2147483648, return +2147483647
*/

Changes to test/expr.test.

304
305
306
307
308
309
310



























311
312
313
314
315
316
317
  test_realnum_expr expr-1.255\
      {i1=4294967296, i2=-2147483647} {i1*i2}     -9223372032559808512
  test_realnum_expr expr-1.256\
      {i1=-4294967296, i2=-2147483648} {i1*i2}    9.22337203685478e+18
  test_realnum_expr expr-1.257\
      {i1=-4294967296, i2=-2147483647} {i1*i2}    9223372032559808512




























}}

ifcapable floatingpoint {
  test_expr expr-2.1 {r1=1.23, r2=2.34} {r1+r2} 3.57
  test_expr expr-2.2 {r1=1.23, r2=2.34} {r1-r2} -1.11
  test_expr expr-2.3 {r1=1.23, r2=2.34} {r1*r2} 2.8782
}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
  test_realnum_expr expr-1.255\
      {i1=4294967296, i2=-2147483647} {i1*i2}     -9223372032559808512
  test_realnum_expr expr-1.256\
      {i1=-4294967296, i2=-2147483648} {i1*i2}    9.22337203685478e+18
  test_realnum_expr expr-1.257\
      {i1=-4294967296, i2=-2147483647} {i1*i2}    9223372032559808512

  test_realnum_expr expr-1.260\
      {i1=3037000500, i2=3037000500} {i1*i2}      9.22337203700025e+18
  test_realnum_expr expr-1.261\
      {i1=3037000500, i2=-3037000500} {i1*i2}     -9.22337203700025e+18
  test_realnum_expr expr-1.262\
      {i1=-3037000500, i2=3037000500} {i1*i2}     -9.22337203700025e+18
  test_realnum_expr expr-1.263\
      {i1=-3037000500, i2=-3037000500} {i1*i2}    9.22337203700025e+18

  test_realnum_expr expr-1.264\
      {i1=3037000500, i2=3037000499} {i1*i2}      9223372033963249500
  test_realnum_expr expr-1.265\
      {i1=3037000500, i2=-3037000499} {i1*i2}     -9223372033963249500
  test_realnum_expr expr-1.266\
      {i1=-3037000500, i2=3037000499} {i1*i2}     -9223372033963249500
  test_realnum_expr expr-1.267\
      {i1=-3037000500, i2=-3037000499} {i1*i2}    9223372033963249500

  test_realnum_expr expr-1.268\
      {i1=3037000499, i2=3037000500} {i1*i2}      9223372033963249500
  test_realnum_expr expr-1.269\
      {i1=3037000499, i2=-3037000500} {i1*i2}     -9223372033963249500
  test_realnum_expr expr-1.270\
      {i1=-3037000499, i2=3037000500} {i1*i2}     -9223372033963249500
  test_realnum_expr expr-1.271\
      {i1=-3037000499, i2=-3037000500} {i1*i2}    9223372033963249500

}}

ifcapable floatingpoint {
  test_expr expr-2.1 {r1=1.23, r2=2.34} {r1+r2} 3.57
  test_expr expr-2.2 {r1=1.23, r2=2.34} {r1-r2} -1.11
  test_expr expr-2.3 {r1=1.23, r2=2.34} {r1*r2} 2.8782
}