Browse Source

big: Use new comparison helpers.

Jeroen van Rijn 4 years ago
parent
commit
671b413b15

+ 3 - 2
core/math/big/build.bat

@@ -1,9 +1,10 @@
 @echo off
 @echo off
-odin run . -vet
+:odin run . -vet
 
 
 set TEST_ARGS=-fast-tests
 set TEST_ARGS=-fast-tests
+:set TEST_ARGS=
 :odin build . -build-mode:shared -show-timings -o:minimal -no-bounds-check -define:MATH_BIG_EXE=false && python test.py %TEST_ARGS%
 :odin build . -build-mode:shared -show-timings -o:minimal -no-bounds-check -define:MATH_BIG_EXE=false && python test.py %TEST_ARGS%
 :odin build . -build-mode:shared -show-timings -o:size -no-bounds-check -define:MATH_BIG_EXE=false && python test.py %TEST_ARGS%
 :odin build . -build-mode:shared -show-timings -o:size -no-bounds-check -define:MATH_BIG_EXE=false && python test.py %TEST_ARGS%
 :odin build . -build-mode:shared -show-timings -o:size -define:MATH_BIG_EXE=false && python test.py %TEST_ARGS%
 :odin build . -build-mode:shared -show-timings -o:size -define:MATH_BIG_EXE=false && python test.py %TEST_ARGS%
-:odin build . -build-mode:shared -show-timings -o:speed -no-bounds-check -define:MATH_BIG_EXE=false && python test.py %TEST_ARGS%
+odin build . -build-mode:shared -show-timings -o:speed -no-bounds-check -define:MATH_BIG_EXE=false && python test.py %TEST_ARGS%
 :odin build . -build-mode:shared -show-timings -o:speed -define:MATH_BIG_EXE=false && python test.py -fast-tests %TEST_ARGS%
 :odin build . -build-mode:shared -show-timings -o:speed -define:MATH_BIG_EXE=false && python test.py -fast-tests %TEST_ARGS%

+ 14 - 15
core/math/big/internal.odin

@@ -136,7 +136,7 @@ internal_int_add_signed :: proc(dest, a, b: ^Int, allocator := context.allocator
 		Subtract the one with the greater magnitude from the other.
 		Subtract the one with the greater magnitude from the other.
 		The result gets the sign of the one with the greater magnitude.
 		The result gets the sign of the one with the greater magnitude.
 	*/
 	*/
-	if #force_inline internal_cmp_mag(a, b) == -1 {
+	if #force_inline internal_lt_abs(a, b) {
 		x, y = y, x;
 		x, y = y, x;
 	}
 	}
 
 
@@ -358,7 +358,7 @@ internal_int_sub_signed :: proc(dest, number, decrease: ^Int, allocator := conte
 		Subtract a positive from a positive, OR negative from a negative.
 		Subtract a positive from a positive, OR negative from a negative.
 		First, take the difference between their magnitudes, then...
 		First, take the difference between their magnitudes, then...
 	*/
 	*/
-	if #force_inline internal_cmp_mag(number, decrease) == -1 {
+	if #force_inline internal_lt_abs(number, decrease) {
 		/*
 		/*
 			The second has a larger magnitude.
 			The second has a larger magnitude.
 			The result has the *opposite* sign from the first number.
 			The result has the *opposite* sign from the first number.
@@ -718,7 +718,7 @@ internal_int_divmod :: proc(quotient, remainder, numerator, denominator: ^Int, a
 	/*
 	/*
 		If numerator < denominator then quotient = 0, remainder = numerator.
 		If numerator < denominator then quotient = 0, remainder = numerator.
 	*/
 	*/
-	if #force_inline internal_cmp_mag(numerator, denominator) == -1 {
+	if #force_inline internal_lt_abs(numerator, denominator) {
 		if remainder != nil {
 		if remainder != nil {
 			internal_copy(remainder, numerator) or_return;
 			internal_copy(remainder, numerator) or_return;
 		}
 		}
@@ -731,7 +731,6 @@ internal_int_divmod :: proc(quotient, remainder, numerator, denominator: ^Int, a
 	if (denominator.used > 2 * MUL_KARATSUBA_CUTOFF) && (denominator.used <= (numerator.used / 3) * 2) {
 	if (denominator.used > 2 * MUL_KARATSUBA_CUTOFF) && (denominator.used <= (numerator.used / 3) * 2) {
 		assert(denominator.used >= 160 && numerator.used >= 240, "MUL_KARATSUBA_CUTOFF global not properly set.");
 		assert(denominator.used >= 160 && numerator.used >= 240, "MUL_KARATSUBA_CUTOFF global not properly set.");
 		err = _private_int_div_recursive(quotient, remainder, numerator, denominator);
 		err = _private_int_div_recursive(quotient, remainder, numerator, denominator);
-		// err = #force_inline _private_int_div_school(quotient, remainder, numerator, denominator);
 	} else {
 	} else {
 		when true {
 		when true {
 			err = #force_inline _private_int_div_school(quotient, remainder, numerator, denominator);
 			err = #force_inline _private_int_div_school(quotient, remainder, numerator, denominator);
@@ -1243,12 +1242,12 @@ internal_less_than_or_equal :: proc {
 	internal_int_less_than_or_equal,
 	internal_int_less_than_or_equal,
 	internal_int_less_than_or_equal_digit,
 	internal_int_less_than_or_equal_digit,
 }
 }
-internal_lteq :: internal_less_than_or_equal;
+internal_lte :: internal_less_than_or_equal;
 
 
 internal_less_than_or_equal_abs :: proc {
 internal_less_than_or_equal_abs :: proc {
 	internal_int_less_than_or_equal_abs,
 	internal_int_less_than_or_equal_abs,
 }
 }
-internal_lteq_abs :: internal_less_than_or_equal_abs;
+internal_lte_abs :: internal_less_than_or_equal_abs;
 
 
 
 
 /*
 /*
@@ -1311,12 +1310,12 @@ internal_greater_than_or_equal :: proc {
 	internal_int_greater_than_or_equal,
 	internal_int_greater_than_or_equal,
 	internal_int_greater_than_or_equal_digit,
 	internal_int_greater_than_or_equal_digit,
 }
 }
-internal_gteq :: internal_greater_than_or_equal;
+internal_gte :: internal_greater_than_or_equal;
 
 
 internal_greater_than_or_equal_abs :: proc {
 internal_greater_than_or_equal_abs :: proc {
 	internal_int_greater_than_or_equal_abs,
 	internal_int_greater_than_or_equal_abs,
 }
 }
-internal_gteq_abs :: internal_greater_than_or_equal_abs;
+internal_gte_abs :: internal_greater_than_or_equal_abs;
 
 
 
 
 /*
 /*
@@ -1410,7 +1409,7 @@ internal_int_is_square :: proc(a: ^Int, allocator := context.allocator) -> (squa
 	sqrt(t, a) or_return;
 	sqrt(t, a) or_return;
 	sqr(t, t)  or_return;
 	sqr(t, t)  or_return;
 
 
-	square = internal_cmp_mag(t, a) == 0;
+	square = internal_eq_abs(t, a);
 
 
 	return;
 	return;
 }
 }
@@ -1642,7 +1641,7 @@ internal_int_sqrt :: proc(dest, src: ^Int, allocator := context.allocator) -> (e
 		internal_add(t2, t1, x)  or_return;
 		internal_add(t2, t1, x)  or_return;
 		internal_shr(y, t2, 1)   or_return;
 		internal_shr(y, t2, 1)   or_return;
 
 
-		if c := internal_cmp(y, x); c == 0 || c == 1 {
+		if internal_gte(y, x) {
 			internal_swap(dest, x);
 			internal_swap(dest, x);
 			return nil;
 			return nil;
 		}
 		}
@@ -1757,8 +1756,8 @@ internal_int_root_n :: proc(dest, src: ^Int, n: int, allocator := context.alloca
 			 Number of rounds is at most log_2(root). If it is more it
 			 Number of rounds is at most log_2(root). If it is more it
 			 got stuck, so break out of the loop and do the rest manually.
 			 got stuck, so break out of the loop and do the rest manually.
 		*/
 		*/
-		if ilog2 -= 1;    ilog2 == 0 { break; }
-		if internal_cmp(t1, t2) == 0 { break; }
+		if ilog2 -= 1; ilog2 == 0 { break; }
+		if internal_eq(t1, t2)    { break; }
 
 
 		iterations += 1;
 		iterations += 1;
 		if iterations == MAX_ITERATIONS_ROOT_N {
 		if iterations == MAX_ITERATIONS_ROOT_N {
@@ -1796,7 +1795,7 @@ internal_int_root_n :: proc(dest, src: ^Int, n: int, allocator := context.alloca
 	for {
 	for {
 		internal_pow(t2, t1, n) or_return;
 		internal_pow(t2, t1, n) or_return;
 	
 	
-		if internal_cmp(t2, a) != 1 { break; }
+		if internal_lt(t2, a) { break; }
 		
 		
 		internal_sub(t1, t1, DIGIT(1)) or_return;
 		internal_sub(t1, t1, DIGIT(1)) or_return;
 
 
@@ -2001,12 +2000,12 @@ internal_int_inverse_modulo :: proc(dest, a, b: ^Int, allocator := context.alloc
 	/*
 	/*
 		For all n in N and n > 0, n = 0 mod 1.
 		For all n in N and n > 0, n = 0 mod 1.
 	*/
 	*/
-	if internal_is_positive(a) && internal_cmp(b, 1) == 0 { return internal_zero(dest);	}
+	if internal_is_positive(a) && internal_eq(b, 1) { return internal_zero(dest);	}
 
 
 	/*
 	/*
 		`b` cannot be negative and has to be > 1
 		`b` cannot be negative and has to be > 1
 	*/
 	*/
-	if internal_is_negative(b) && internal_cmp(b, 1) != 1 { return .Invalid_Argument; }
+	if internal_is_negative(b) || internal_gt(b, 1) { return .Invalid_Argument; }
 
 
 	/*
 	/*
 		If the modulus is odd we can use a faster routine instead.
 		If the modulus is odd we can use a faster routine instead.

+ 1 - 1
core/math/big/prime.odin

@@ -163,7 +163,7 @@ internal_int_kronecker :: proc(a, p: ^Int, allocator := context.allocator) -> (k
 
 
 	for {
 	for {
 		if internal_is_zero(a1) {
 		if internal_is_zero(a1) {
-			if internal_cmp(p1, 1) == 0 {
+			if internal_eq(p1, 1) {
 				return k, nil;
 				return k, nil;
 			} else {
 			} else {
 				return 0, nil;
 				return 0, nil;

+ 23 - 27
core/math/big/private.odin

@@ -1071,11 +1071,11 @@ _private_int_div_school :: proc(quotient, remainder, numerator, denominator: ^In
 
 
 	internal_shl_digit(y, n - t) or_return;
 	internal_shl_digit(y, n - t) or_return;
 
 
-	c := internal_cmp(x, y);
-	for c != -1 {
+	gte := internal_gte(x, y);
+	for gte {
 		q.digit[n - t] += 1;
 		q.digit[n - t] += 1;
 		internal_sub(x, x, y) or_return;
 		internal_sub(x, x, y) or_return;
-		c = internal_cmp(x, y);
+		gte = internal_gte(x, y);
 	}
 	}
 
 
 	/*
 	/*
@@ -1134,7 +1134,7 @@ _private_int_div_school :: proc(quotient, remainder, numerator, denominator: ^In
 			t2.digit[2] = x.digit[i];
 			t2.digit[2] = x.digit[i];
 			t2.used = 3;
 			t2.used = 3;
 
 
-			if t1_t2 := internal_cmp_mag(t1, t2); t1_t2 != 1 {
+			if internal_lte(t1, t2) {
 				break;
 				break;
 			}
 			}
 			iter += 1; if iter > 100 {
 			iter += 1; if iter > 100 {
@@ -1227,15 +1227,13 @@ _private_div_recursion :: proc(quotient, remainder, a, b: ^Int, allocator := con
 	/*
 	/*
 		While A1 < 0 do Q1 = Q1 - 1, A1 = A1 + (beta^k * B)
 		While A1 < 0 do Q1 = Q1 - 1, A1 = A1 + (beta^k * B)
 	*/
 	*/
-	if internal_cmp(A1, 0) == -1 {
+	if internal_lt(A1, 0) {
 		internal_shl(t, b, k * _DIGIT_BITS) or_return;
 		internal_shl(t, b, k * _DIGIT_BITS) or_return;
 
 
 		for {
 		for {
 			internal_decr(Q1) or_return;
 			internal_decr(Q1) or_return;
 			internal_add(A1, A1, t) or_return;
 			internal_add(A1, A1, t) or_return;
-			if internal_cmp(A1, 0) != -1 {
-				break;
-			}
+			if internal_gte(A1, 0) { break; }
 		}
 		}
 	}
 	}
 
 
@@ -1256,7 +1254,7 @@ _private_div_recursion :: proc(quotient, remainder, a, b: ^Int, allocator := con
 	/*
 	/*
 		While A2 < 0 do Q0 = Q0 - 1, A2 = A2 + B.
 		While A2 < 0 do Q0 = Q0 - 1, A2 = A2 + B.
 	*/
 	*/
-	for internal_cmp(A2, 0) == -1 {
+	for internal_is_negative(A2) { // internal_lt(A2, 0) {
 		internal_decr(Q0) or_return;
 		internal_decr(Q0) or_return;
 		internal_add(A2, A2, b) or_return;
 		internal_add(A2, A2, b) or_return;
 	}
 	}
@@ -1391,7 +1389,7 @@ _private_int_div_small :: proc(quotient, remainder, numerator, denominator: ^Int
 		shl(tq, tq, n)       or_return;
 		shl(tq, tq, n)       or_return;
 
 
 		for n >= 0 {
 		for n >= 0 {
-			if c, _ = cmp_mag(ta, tb); c == 0 || c == 1 {
+			if internal_gte(ta, tb) {
 				// ta -= tb
 				// ta -= tb
 				sub(ta, ta, tb) or_return;
 				sub(ta, ta, tb) or_return;
 				//  q += tq
 				//  q += tq
@@ -1596,7 +1594,7 @@ _private_int_gcd_lcm :: proc(res_gcd, res_lcm, a, b: ^Int, allocator := context.
 		/*
 		/*
 			Make sure `v` is the largest.
 			Make sure `v` is the largest.
 		*/
 		*/
-		if internal_cmp_mag(u, v) == 1 {
+		if internal_gt(u, v) {
 			/*
 			/*
 				Swap `u` and `v` to make sure `v` is >= `u`.
 				Swap `u` and `v` to make sure `v` is >= `u`.
 			*/
 			*/
@@ -1634,7 +1632,7 @@ _private_int_gcd_lcm :: proc(res_gcd, res_lcm, a, b: ^Int, allocator := context.
 		Computes least common multiple as `|a*b|/gcd(a,b)`
 		Computes least common multiple as `|a*b|/gcd(a,b)`
 		Divide the smallest by the GCD.
 		Divide the smallest by the GCD.
 	*/
 	*/
-	if internal_cmp_mag(a, b) == -1 {
+	if internal_lt_abs(a, b) {
 		/*
 		/*
 			Store quotient in `t2` such that `t2 * b` is the LCM.
 			Store quotient in `t2` such that `t2 * b` is the LCM.
 		*/
 		*/
@@ -1694,9 +1692,7 @@ _private_int_log :: proc(a: ^Int, base: DIGIT, allocator := context.allocator) -
 		/*
 		/*
 			Iterate until `a` is bracketed between low + high.
 			Iterate until `a` is bracketed between low + high.
 		*/
 		*/
-		if #force_inline internal_cmp(bracket_high, a) != -1 {
-			break;
-		}
+		if #force_inline internal_gte(bracket_high, a) { break; }
 
 
 		low = high;
 		low = high;
 		#force_inline internal_copy(bracket_low, bracket_high) or_return;
 		#force_inline internal_copy(bracket_low, bracket_high) or_return;
@@ -1844,7 +1840,7 @@ _private_montgomery_reduce_comba :: proc(x, n: ^Int, rho: DIGIT, allocator := co
 	/*
 	/*
 		if A >= m then A = A - m
 		if A >= m then A = A - m
 	*/
 	*/
-	if internal_cmp_mag(x, n) != -1 {
+	if internal_gte_abs(x, n) {
 		return internal_sub(x, x, n);
 		return internal_sub(x, x, n);
 	}
 	}
 	return nil;
 	return nil;
@@ -1932,7 +1928,7 @@ _private_int_montgomery_reduce :: proc(x, n: ^Int, rho: DIGIT, allocator := cont
 	/*
 	/*
 		if x >= n then x = x - n
 		if x >= n then x = x - n
 	*/
 	*/
-	if internal_cmp_mag(x, n) != -1 {
+	if internal_gte_abs(x, n) {
 		return internal_sub(x, x, n);
 		return internal_sub(x, x, n);
 	}
 	}
 
 
@@ -1969,7 +1965,7 @@ _private_int_montgomery_calc_normalization :: proc(a, b: ^Int, allocator := cont
 	*/
 	*/
 	for x := bits - 1; x < _DIGIT_BITS; x += 1 {
 	for x := bits - 1; x < _DIGIT_BITS; x += 1 {
 		internal_int_shl1(a, a)                                      or_return;
 		internal_int_shl1(a, a)                                      or_return;
-		if internal_cmp_mag(a, b) != -1 {
+		if internal_gte_abs(a, b) {
 			internal_sub(a, a, b)                                    or_return;
 			internal_sub(a, a, b)                                    or_return;
 		}
 		}
 	}
 	}
@@ -2064,7 +2060,7 @@ _private_int_reduce :: proc(x, m, mu: ^Int, allocator := context.allocator) -> (
 	/*
 	/*
 		If x < 0, add b**(k+1) to it.
 		If x < 0, add b**(k+1) to it.
 	*/
 	*/
-	if internal_cmp(x, 0) == -1 {
+	if internal_is_negative(x) {
 		internal_set(q, 1)                                           or_return;
 		internal_set(q, 1)                                           or_return;
 		internal_shl_digit(q, um + 1)                                or_return;
 		internal_shl_digit(q, um + 1)                                or_return;
 		internal_add(x, x, q)                                        or_return;
 		internal_add(x, x, q)                                        or_return;
@@ -2073,7 +2069,7 @@ _private_int_reduce :: proc(x, m, mu: ^Int, allocator := context.allocator) -> (
 	/*
 	/*
 		Back off if it's too big.
 		Back off if it's too big.
 	*/
 	*/
-	for internal_cmp(x, m) != -1 {
+	for internal_gte(x, m) {
 		internal_sub(x, x, m)                                        or_return;
 		internal_sub(x, x, m)                                        or_return;
 	}
 	}
 
 
@@ -2110,7 +2106,7 @@ _private_int_reduce_2k :: proc(a, n: ^Int, d: DIGIT, allocator := context.alloca
 			a = a + q
 			a = a + q
 		*/
 		*/
 		internal_add(a, a, q)                                        or_return;
 		internal_add(a, a, q)                                        or_return;
-		if internal_cmp_mag(a, n) == -1                              { break; }
+		if internal_lt_abs(a, n)                                     { break; }
 		internal_sub(a, a, n)                                        or_return;
 		internal_sub(a, a, n)                                        or_return;
 	}
 	}
 
 
@@ -2146,7 +2142,7 @@ _private_int_reduce_2k_l :: proc(a, n, d: ^Int, allocator := context.allocator)
 			a = a + q
 			a = a + q
 		*/
 		*/
 		internal_add(a, a, q)                                        or_return;
 		internal_add(a, a, q)                                        or_return;
-		if internal_cmp_mag(a, n) == -1                              { break; }
+		if internal_lt_abs(a, n)                                     { break; }
 		internal_sub(a, a, n)                                        or_return;
 		internal_sub(a, a, n)                                        or_return;
 	}
 	}
 
 
@@ -2359,7 +2355,7 @@ _private_int_dr_reduce :: proc(x, n: ^Int, k: DIGIT, allocator := context.alloca
 			If x >= n then subtract and reduce again.
 			If x >= n then subtract and reduce again.
 			Each successive "recursion" makes the input smaller and smaller.
 			Each successive "recursion" makes the input smaller and smaller.
 		*/
 		*/
-		if internal_cmp_mag(x, n) == -1 { break; }
+		if internal_lt_abs(x, n) { break; }
 
 
 		internal_sub(x, x, n)                                        or_return;
 		internal_sub(x, x, n)                                        or_return;
 	}
 	}
@@ -2985,21 +2981,21 @@ _private_inverse_modulo :: proc(dest, a, b: ^Int, allocator := context.allocator
 	/*
 	/*
 		If `v` != `1` then there is no inverse.
 		If `v` != `1` then there is no inverse.
 	*/
 	*/
-	if internal_cmp(v, 1) != 0 {
+	if !internal_eq(v, 1) {
 		return .Invalid_Argument;
 		return .Invalid_Argument;
 	}
 	}
 
 
 	/*
 	/*
 		If its too low.
 		If its too low.
 	*/
 	*/
-	if internal_cmp(C, 0) == -1 {
+	if internal_is_negative(C) {
 		internal_add(C, C, b) or_return;
 		internal_add(C, C, b) or_return;
 	}
 	}
 
 
 	/*
 	/*
 		Too big.
 		Too big.
 	*/
 	*/
-	if internal_cmp(C, 0) != -1 {
+	if internal_gte(C, 0) {
 		internal_sub(C, C, b) or_return;
 		internal_sub(C, C, b) or_return;
 	}
 	}
 
 
@@ -3152,7 +3148,7 @@ _private_inverse_modulo_odd :: proc(dest, a, b: ^Int, allocator := context.alloc
 	/*
 	/*
 		Too big.
 		Too big.
 	*/
 	*/
-	for internal_cmp_mag(D, b) != -1 {
+	for internal_gte_abs(D, b) {
 		internal_sub(D, D, b) or_return;
 		internal_sub(D, D, b) or_return;
 	}
 	}
 
 

+ 0 - 1
core/math/big/test.py

@@ -413,7 +413,6 @@ def test_shr_signed(a = 0, bits = 0, expected_error = Error.Okay):
 	return test("test_shr_signed", res, [a, bits], expected_error, expected_result)
 	return test("test_shr_signed", res, [a, bits], expected_error, expected_result)
 
 
 def test_factorial(number = 0, expected_error = Error.Okay):
 def test_factorial(number = 0, expected_error = Error.Okay):
-	print("Factorial:", number)
 	args  = [number]
 	args  = [number]
 	try:
 	try:
 		res = int_factorial(*args)
 		res = int_factorial(*args)