Selaa lähdekoodia

big: Add `submod`, `mulmod`, `sqrmod`.

Jeroen van Rijn 4 vuotta sitten
vanhempi
commit
9646d1f2b8
2 muutettua tiedostoa jossa 37 lisäystä ja 5 poistoa
  1. 35 3
      core/math/big/basic.odin
  2. 2 2
      core/math/big/example.odin

+ 35 - 3
core/math/big/basic.odin

@@ -656,7 +656,7 @@ sqr :: proc(dest, src: ^Int) -> (err: Error) {
 	divmod.
 	Both the quotient and remainder are optional and may be passed a nil.
 */
-int_div :: proc(quotient, remainder, numerator, denominator: ^Int) -> (err: Error) {
+int_divmod :: proc(quotient, remainder, numerator, denominator: ^Int) -> (err: Error) {
 	/*
 		Early out if neither of the results is wanted.
 	*/
@@ -692,7 +692,12 @@ int_div :: proc(quotient, remainder, numerator, denominator: ^Int) -> (err: Erro
 
 	return err;
 }
-div :: proc{ int_div, };
+divmod :: proc{ int_divmod, };
+
+int_div :: proc(quotient, numerator, denominator: ^Int) -> (err: Error) {
+	return int_divmod(quotient, nil, numerator, denominator);
+}
+div :: proc { int_div, };
 
 /*
 	remainder = numerator % denominator.
@@ -700,7 +705,7 @@ div :: proc{ int_div, };
 	denominator < remainder <= 0 if denominator < 0
 */
 int_mod :: proc(remainder, numerator, denominator: ^Int) -> (err: Error) {
-	if err = div(nil, remainder, numerator, denominator); err != .None { return err; }
+	if err = divmod(nil, remainder, numerator, denominator); err != .None { return err; }
 
 	z: bool;
 	if z, err = is_zero(remainder); z || denominator.sign == remainder.sign { return .None; }
@@ -717,6 +722,33 @@ int_addmod :: proc(remainder, number, addend, modulus: ^Int) -> (err: Error) {
 }
 addmod :: proc { int_addmod, };
 
+/*
+	remainder = (number - decrease) % modulus.
+*/
+int_submod :: proc(remainder, number, decrease, modulus: ^Int) -> (err: Error) {
+	if err = add(remainder, number, decrease); err != .None { return err; }
+	return mod(remainder, remainder, modulus);
+}
+submod :: proc { int_submod, };
+
+/*
+	remainder = (number * multiplicand) % modulus.
+*/
+int_mulmod :: proc(remainder, number, multiplicand, modulus: ^Int) -> (err: Error) {
+	if err = mul(remainder, number, multiplicand); err != .None { return err; }
+	return mod(remainder, remainder, modulus);
+}
+mulmod :: proc { int_mulmod, };
+
+/*
+	remainder = (number * number) % modulus.
+*/
+int_sqrmod :: proc(remainder, number, modulus: ^Int) -> (err: Error) {
+	if err = sqr(remainder, number); err != .None { return err; }
+	return mod(remainder, remainder, modulus);
+}
+sqrmod :: proc { int_sqrmod, };
+
 /*
 	==========================
 		Low-level routines    

+ 2 - 2
core/math/big/example.odin

@@ -69,10 +69,10 @@ demo :: proc() {
 
 	err = set (numerator,   3);
 	err = set (denominator, 2);
-	err = set (quotient,    3);
+	err = set (quotient,    5);
 	err = zero(remainder);
 
-	err = addmod(remainder, numerator, denominator, quotient);
+	err = mulmod(remainder, numerator, denominator, quotient);
 	if err != .None {
 		fmt.printf("Error: %v\n", err);
 	} else {