Skip to content

The USE_NATIVE_FULL_ITERATIONS codepath in div64 is broken #555

@koute

Description

@koute

It looks like this codepath is completely broken. If enabled like this:

diff --git a/src/float/div.rs b/src/float/div.rs
index 8c4cf55..d15c2b9 100644
--- a/src/float/div.rs
+++ b/src/float/div.rs
@@ -466,7 +466,7 @@ where
 {
     const NUMBER_OF_HALF_ITERATIONS: usize = 3;
     const NUMBER_OF_FULL_ITERATIONS: usize = 1;
-    const USE_NATIVE_FULL_ITERATIONS: bool = false;
+    const USE_NATIVE_FULL_ITERATIONS: bool = true;
 
     let one = F::Int::ONE;
     let zero = F::Int::ZERO;
@@ -922,3 +922,8 @@ intrinsics! {
         a / b
     }
 }
+
+#[test]
+fn test_div64() {
+    div64(10.0_f64, 5.0_f64);
+}

it fails with an overflow:

thread 'float::div::test_div64' panicked at 'attempt to multiply with overflow', src/float/div.rs:767:17

Looking at this code and looking at the div32 implementation I'm guessing this is how it should be fixed?

diff --git a/src/float/div.rs b/src/float/div.rs
index 8c4cf55..4ea7500 100644
--- a/src/float/div.rs
+++ b/src/float/div.rs
@@ -764,8 +764,8 @@ where
     let mut x_uq0 = if USE_NATIVE_FULL_ITERATIONS {
         for _ in 0..NUMBER_OF_FULL_ITERATIONS {
             let corr_uq1: u64 = 0.wrapping_sub(
-                (CastInto::<u64>::cast(x_uq0) * (CastInto::<u64>::cast(b_uq1))) >> F::BITS,
-            );
+                (CastInto::<u64>::cast(x_uq0) as u128 * (CastInto::<u64>::cast(b_uq1) as u128)) >> F::BITS,
+            ) as u64;
             x_uq0 = ((((CastInto::<u64>::cast(x_uq0) as u128) * (corr_uq1 as u128))
                 >> (F::BITS - 1)) as u64)
                 .cast();

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions