Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Handle overflow and rounding cases in sqlite4_num_to_int64. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
de7fb192cbd9aadba2c6608ff3d80f85 |
User & Date: | peterreid 2013-06-01 23:42:30.602 |
Context
2013-06-03
| ||
15:23 | Merge overflow and rounding fixes for sqlite4_num_to_int64(). check-in: e8db1e81a4 user: dan tags: trunk | |
2013-06-01
| ||
23:42 | Handle overflow and rounding cases in sqlite4_num_to_int64. check-in: de7fb192cb user: peterreid tags: trunk | |
23:35 | Add tests for sqlite4_num_to_int64. check-in: 11fd3e7ec4 user: peterreid tags: trunk | |
Changes
Changes to src/math.c.
︙ | ︙ | |||
527 528 529 530 531 532 533 534 535 536 | } /* ** Convert the number passed as the first argument to a signed 64-bit ** integer and return the value. If the second argument is not NULL, ** then set the value that it points to 1 if data was lost as part ** of the conversion, or 0 otherwise. */ sqlite4_int64 sqlite4_num_to_int64(sqlite4_num num, int *pbLossy){ static const i64 L10 = (LARGEST_INT64 / 10); | > > > > | | | > > | | > | | | > | < < < > | | | 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 | } /* ** Convert the number passed as the first argument to a signed 64-bit ** integer and return the value. If the second argument is not NULL, ** then set the value that it points to 1 if data was lost as part ** of the conversion, or 0 otherwise. ** ** Values round towards 0. If the number is outside the range that a ** signed 64-bit integer can represent, it is clamped to be inside ** that range. */ sqlite4_int64 sqlite4_num_to_int64(sqlite4_num num, int *pbLossy){ static const i64 L10 = (LARGEST_INT64 / 10); u64 iRet; int i; iRet = num.m; if( pbLossy ) *pbLossy = 0; for(i=0; i<num.e; i++){ if( iRet>L10 ) goto overflow; iRet = iRet * 10; } for(i=num.e; i<0; i++){ if( pbLossy && (iRet % 10) ) *pbLossy = 1; iRet = iRet / 10; } if( num.sign ){ if( iRet>(u64)LARGEST_INT64+1 ) goto overflow; return -(i64)iRet; }else{ if( iRet>(u64)LARGEST_INT64 ) goto overflow; return (i64)iRet; } overflow: if( pbLossy ) *pbLossy = 1; return num.sign ? -LARGEST_INT64-1 : LARGEST_INT64; } /* ** Convert an integer into text in the buffer supplied. The ** text is zero-terminated and right-justified in the buffer. ** A pointer to the first character of text is returned. |
︙ | ︙ |
Changes to test/num.test.
︙ | ︙ | |||
163 164 165 166 167 168 169 170 171 172 173 174 175 176 | foreach {tn in out} { 0 50 50 1 -94 -94 2 {sign:0 approx:0 e:4 m:2} 20000 3 9223372036854775807 9223372036854775807 4 -9223372036854775808 -9223372036854775808 5 {sign:0 approx:0 e:-1 m:51} ~5 } { do_test num-10.1.$tn { sqlite4_num_to_int64 $in } [list {*}$out] } #------------------------------------------------------------------------- finish_test | > > > > > > > > > > > | 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | foreach {tn in out} { 0 50 50 1 -94 -94 2 {sign:0 approx:0 e:4 m:2} 20000 3 9223372036854775807 9223372036854775807 4 -9223372036854775808 -9223372036854775808 5 {sign:0 approx:0 e:-1 m:51} ~5 6 {sign:0 approx:0 e:0 m:9223372036854775808} ~9223372036854775807 7 9223372036854775808 ~9223372036854775807 8 10000000000000000000 ~9223372036854775807 9 -10000000000000000000 ~-9223372036854775808 10 {sign:0 approx:0 e:50 m:244} ~9223372036854775807 11 {sign:1 approx:0 e:50 m:34220} ~-9223372036854775808 12 50.1 ~50 13 10.9 ~10 14 .995 ~0 15 -93.9 ~-93 16 -12.1 ~-12 } { do_test num-10.1.$tn { sqlite4_num_to_int64 $in } [list {*}$out] } #------------------------------------------------------------------------- finish_test |
︙ | ︙ |