@@ -11,6 +11,8 @@ use crate::avm2::Namespace;
11
11
use crate :: ecma_conversions:: { f64_to_wrapping_i32, f64_to_wrapping_u32} ;
12
12
use crate :: string:: { AvmAtom , AvmString , WStr } ;
13
13
use gc_arena:: { Collect , GcCell , Mutation } ;
14
+ use num_bigint:: BigInt ;
15
+ use num_traits:: { ToPrimitive , Zero } ;
14
16
use std:: cell:: Ref ;
15
17
use std:: mem:: size_of;
16
18
use swf:: avm2:: types:: { DefaultValue as AbcDefaultValue , Index } ;
@@ -383,7 +385,7 @@ pub fn string_to_f64(mut s: &WStr, swf_version: u8, strict: bool) -> Option<f64>
383
385
// Finally, calculate the result.
384
386
let mut result = if total_digits > 15 {
385
387
// With more than 15 digits, avmplus uses integer arithmetic to avoid rounding errors.
386
- let mut result: i64 = 0 ;
388
+ let mut result: BigInt = Zero :: zero ( ) ;
387
389
let mut decimal_digits = -1 ;
388
390
for c in s {
389
391
if let Some ( digit) = to_decimal_digit ( c) {
@@ -408,7 +410,7 @@ pub fn string_to_f64(mut s: &WStr, swf_version: u8, strict: bool) -> Option<f64>
408
410
result *= i64:: pow ( 10 , exponent as u32 ) ;
409
411
}
410
412
411
- result as f64
413
+ result. to_f64 ( ) . unwrap_or ( f64:: NAN )
412
414
} else {
413
415
let mut result = 0.0 ;
414
416
let mut decimal_digits = -1 ;
@@ -1330,3 +1332,16 @@ impl<'gc> Value<'gc> {
1330
1332
Ok ( Some ( num_self < num_other) )
1331
1333
}
1332
1334
}
1335
+
1336
+ #[ cfg( test) ]
1337
+ mod tests {
1338
+ use super :: * ;
1339
+
1340
+ #[ test]
1341
+ fn test_string_to_f64 ( ) {
1342
+ assert_eq ! (
1343
+ string_to_f64( WStr :: from_units( b"350000000000000000000" ) , 0 , true ) ,
1344
+ Some ( 3.5e20 )
1345
+ ) ;
1346
+ }
1347
+ }
0 commit comments