diff --git a/vlib/math/fractions/fraction.v b/vlib/math/fractions/fraction.v index 809875ab04..6be1a2a10d 100644 --- a/vlib/math/fractions/fraction.v +++ b/vlib/math/fractions/fraction.v @@ -5,6 +5,7 @@ module fractions import math +import math.bits // Fraction Struct struct Fraction { @@ -99,8 +100,26 @@ pub fn (f1 Fraction) f64() f64 { return f64(f1.n) / f64(f1.d) } +// Returns the absolute value of an i64 +fn abs(num i64) i64 { + if num < 0 { + return -num + } else { + return num + } +} + +// Two integers are safe to multiply when their bit lengths +// sum up to less than 64 (conservative estimate). +fn safe_to_multiply(a, b i64) bool { + return (bits.len_64(abs(a)) + bits.len_64(abs(b))) < 64 +} + // Compares two Fractions pub fn (f1 Fraction) equals(f2 Fraction) bool { + if safe_to_multiply(f1.n, f2.d) && safe_to_multiply(f2.n, f1.d) { + return (f1.n * f2.d) == (f2.n * f1.d) + } r1 := f1.reduce() r2 := f2.reduce() return (r1.n == r2.n) && (r1.d == r2.d)