9
9
//! algorithm can be found in "ParseNumberF64 by Simple Decimal Conversion",
10
10
//! available online: <https://nigeltao.github.io/blog/2020/parse-number-f64-simple.html>.
11
11
12
- use crate :: num:: dec2flt:: common:: { ByteSlice , is_8digits} ;
13
12
use crate :: kani;
13
+ use crate :: num:: dec2flt:: common:: { ByteSlice , is_8digits} ;
14
14
15
15
/// A decimal floating-point number, represented as a sequence of decimal digits.
16
16
#[ derive( Clone , Debug , PartialEq ) ]
@@ -132,9 +132,9 @@ impl DecimalSeq {
132
132
let mut read_index = self . num_digits ;
133
133
let mut write_index = self . num_digits + num_new_digits;
134
134
let mut n = 0_u64 ;
135
-
136
- #[ kani:: loop_invariant( read_index <= Self :: MAX_DIGITS &&
137
- write_index == read_index + num_new_digits &&
135
+
136
+ #[ kani:: loop_invariant( read_index <= Self :: MAX_DIGITS &&
137
+ write_index == read_index + num_new_digits &&
138
138
n < 10u64 << ( shift - 1 ) &&
139
139
self . num_digits <= Self :: MAX_DIGITS &&
140
140
self . decimal_point <= self . num_digits as i32 &&
@@ -207,8 +207,8 @@ impl DecimalSeq {
207
207
return ;
208
208
}
209
209
let mask = ( 1_u64 << shift) - 1 ;
210
- #[ kani:: loop_invariant( self . num_digits <= Self :: MAX_DIGITS &&
211
- write_index < read_index &&
210
+ #[ kani:: loop_invariant( self . num_digits <= Self :: MAX_DIGITS &&
211
+ write_index < read_index &&
212
212
write_index < Self :: MAX_DIGITS - self . num_digits. saturating_sub( read_index)
213
213
) ]
214
214
while read_index < self . num_digits {
@@ -408,13 +408,14 @@ pub mod decimal_seq_verify {
408
408
num_digits : kani:: any ( ) ,
409
409
decimal_point : kani:: any ( ) ,
410
410
truncated : kani:: any ( ) ,
411
- digits : kani:: any ( ) } ;
411
+ digits : kani:: any ( ) ,
412
+ } ;
412
413
kani:: assume ( a. num_digits <= DecimalSeq :: MAX_DIGITS ) ;
413
- kani:: assume ( a. decimal_point >= 0 ) ;
414
+ kani:: assume ( a. decimal_point >= 0 ) ;
414
415
kani:: assume ( a. decimal_point <= a. num_digits as i32 ) ;
415
416
kani:: assume ( kani:: forall!( |i in ( 0 , DecimalSeq :: MAX_DIGITS ) | a. digits[ i] <= 9 ) ) ;
416
- ret
417
- }
417
+ ret
418
+ }
418
419
}
419
420
420
421
#[ kani:: proof]
@@ -428,13 +429,16 @@ pub mod decimal_seq_verify {
428
429
let mut a: DecimalSeq = kani:: any ( ) ;
429
430
let shift: usize = kani:: any_where ( |x| * x > 0 && * x <= 60 ) ;
430
431
let n = number_of_digits_decimal_left_shift ( & a, shift) ;
432
+ // 19 is the greatest number x such that 10u64^x does not overflow
433
+ // It is also TABLE.max << 11
431
434
assert ! ( n <= 19 ) ;
432
435
assert ! ( n == 19 || 1u64 << shift < 10u64 . pow( n as u32 + 1 ) )
433
436
}
434
437
435
438
#[ kani:: proof]
436
439
fn check_right_shift ( ) {
437
440
let mut a: DecimalSeq = kani:: any ( ) ;
441
+ //This function is called in parse_long_mantissa function (slow.rs), in which the maximum of shift is 60
438
442
let shift: usize = kani:: any_where ( |x| * x > 0 && * x <= 60 ) ;
439
443
a. right_shift ( shift) ;
440
444
}
0 commit comments