@@ -32,25 +32,22 @@ pub enum ModelSource<'ctx> {
3232/// Convert a decimal string `d_str` into a pair of a numerator (`num`) and
3333/// a denominator (`den`) in the form of '[numeral]' strings such that:
3434/// d_str = num / den
35- fn from_str_to_num_den ( d_str : & str ) -> Option < ( String , String ) > {
35+ fn from_str_to_num_den ( d_str : & str ) -> Option < ( BigInt , BigInt ) > {
3636 if d_str. is_empty ( ) {
3737 return None ;
3838 }
3939
40- if let Some ( pos) = d_str. find ( '.' ) {
41- let den = "1" . to_string ( ) + & "0" . repeat ( d_str. len ( ) - pos - 1 ) ;
42-
43- let mut num = d_str. to_string ( ) ;
44- num. remove ( pos) ;
45- num. trim_start_matches ( '0' ) ;
46-
47- if num. is_empty ( ) {
48- num = "0" . to_string ( ) ;
49- }
40+ if d_str. ends_with ( ".0" ) {
41+ let num = BigInt :: from_str ( & d_str. replace ( ".0" , "" ) ) . ok ( ) ?;
42+ Some ( ( num, BigInt :: from ( 1 ) ) )
43+ } else if let Some ( pos) = d_str. find ( '.' ) {
44+ let den = BigInt :: from ( 10 ) . pow ( ( d_str. len ( ) - pos - 1 ) . try_into ( ) . unwrap ( ) ) ;
45+ let num = BigInt :: from_str ( & d_str. replace ( "." , "" ) ) . ok ( ) ?;
5046
5147 Some ( ( num, den) )
5248 } else {
53- Some ( ( d_str. to_string ( ) , "1" . to_string ( ) ) )
49+ let num = BigInt :: from_str ( d_str) . ok ( ) ?;
50+ Some ( ( num, BigInt :: from ( 1 ) ) )
5451 }
5552}
5653
@@ -326,8 +323,8 @@ impl<'ctx> SmtEval<'ctx> for Real<'ctx> {
326323 } ,
327324 Term :: SpecConstant ( SpecConstant :: Decimal ( Decimal ( d_str) ) ) => {
328325 if let Some ( ( n, d) ) = from_str_to_num_den ( d_str) {
329- num *= BigInt :: from_str ( & n ) . map_err ( |_| SmtEvalError :: EvalError ) ? ;
330- den *= BigInt :: from_str ( & d ) . map_err ( |_| SmtEvalError :: EvalError ) ? ;
326+ num *= n ;
327+ den *= d ;
331328 } else {
332329 return Err ( SmtEvalError :: EvalError ) ;
333330 }
@@ -343,8 +340,8 @@ impl<'ctx> SmtEval<'ctx> for Real<'ctx> {
343340 } ,
344341 Term :: SpecConstant ( SpecConstant :: Decimal ( Decimal ( d_str) ) ) => {
345342 if let Some ( ( n, d) ) = from_str_to_num_den ( d_str) {
346- den *= BigInt :: from_str ( & n ) . map_err ( |_| SmtEvalError :: EvalError ) ? ;
347- num *= BigInt :: from_str ( & d ) . map_err ( |_| SmtEvalError :: EvalError ) ? ;
343+ den *= n ;
344+ num *= d ;
348345 } else {
349346 return Err ( SmtEvalError :: EvalError ) ;
350347 }
0 commit comments