]> Repositorios git - scryer-prolog.git/commitdiff
detect float rounding overflows (#1365)
authorMark Thom <[email protected]>
Thu, 24 Mar 2022 16:25:42 +0000 (10:25 -0600)
committerMark Thom <[email protected]>
Thu, 24 Mar 2022 16:25:42 +0000 (10:25 -0600)
src/arithmetic.rs
src/heap_print.rs

index 894e9d1f52e1d57dc84e2bc733bf4d4f9a134151..cc0b01942460641606c775bc0de522f9e9aab1db 100644 (file)
@@ -375,7 +375,18 @@ impl<'a, TermMarker: Allocator> ArithmeticEvaluator<'a, TermMarker> {
 pub(crate) fn rnd_i<'a>(n: &'a Number, arena: &mut Arena) -> Number {
     match n {
         &Number::Integer(_) | &Number::Fixnum(_) => *n,
-        &Number::Float(OrderedFloat(f)) => fixnum!(Number, f.floor() as i64, arena),
+        &Number::Float(OrderedFloat(f)) => {
+            let f = f.floor();
+
+            const I64_MIN_TO_F: OrderedFloat<f64> = OrderedFloat(i64::MIN as f64);
+            const I64_MAX_TO_F: OrderedFloat<f64> = OrderedFloat(i64::MIN as f64);
+
+            if I64_MIN_TO_F <= OrderedFloat(f) && OrderedFloat(f) <= I64_MAX_TO_F {
+                fixnum!(Number, f as i64, arena)
+            } else {
+                Number::Integer(arena_alloc!(Integer::from_f64(f).unwrap(), arena))
+            }
+        }
         &Number::Rational(ref r) => {
             let r_ref = r.fract_floor_ref();
             let (mut fract, mut floor) = (Rational::new(), Integer::new());
index 8ee3ec678fae364cb2519e11319cabe9f1f67030..030e7c737bd615ed95325520f8e8ba3aad6378cf 100644 (file)
@@ -116,7 +116,6 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
         let mut parent_spec = DirectedOp::Left(atom!("-"), OpDesc::build_with(200, FY as u8));
 
         loop {
-            // match self.machine_st.store(self.machine_st.deref(addr)) {
             read_heap_cell!(self.heap[h],
                 (HeapCellValueTag::Str, s) => {
                     read_heap_cell!(self.heap[s],
@@ -156,7 +155,6 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
             None => return false,
         };
 
-        // let addr = self.machine_st.store(self.machine_st.deref(addr));
         property_check(addr)
     }
 }