Forráskód Böngészése

Merge branch 'master' of https://github.com/odin-lang/Odin

gingerBill 4 éve
szülő
commit
4b7dcc1513

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

@@ -1,10 +1,10 @@
 @echo off
-odin run . -vet -define:MATH_BIG_USE_FROBENIUS_TEST=true
+:odin run . -vet -define:MATH_BIG_USE_FROBENIUS_TEST=true
 
 set TEST_ARGS=-fast-tests
-:set TEST_ARGS=
+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: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: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%

+ 10 - 4
core/math/big/example.odin

@@ -84,16 +84,20 @@ print :: proc(name: string, a: ^Int, base := i8(10), print_name := true, newline
 	}
 }
 
-printf :: fmt.printf;
+//printf :: fmt.printf;
 
 demo :: proc() {
 	a, b, c, d, e, f, res := &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{};
 	defer destroy(a, b, c, d, e, f, res);
 
-	err: Error;
+	err:  Error;
+	frob:  bool;
 	prime: bool;
 
-	set(a, "3317044064679887385961981"); // Composite: 1287836182261 × 2575672364521
+	// USE_MILLER_RABIN_ONLY = true;
+
+	// set(a, "3317044064679887385961979"); // Composite: 17 × 1709 × 1366183751 × 83570142193
+	set(a, "359334085968622831041960188598043661065388726959079837"); // 6th Bell prime
 	trials := number_of_rabin_miller_trials(internal_count_bits(a));
 	{
 		SCOPED_TIMING(.is_prime);
@@ -101,7 +105,9 @@ demo :: proc() {
 	}
 	print("Candidate prime: ", a);
 	fmt.printf("%v Miller-Rabin trials needed.\n", trials);
-	fmt.printf("Is prime: %v, Error: %v\n", prime, err);
+
+	frob, err = internal_int_prime_frobenius_underwood(a);
+	fmt.printf("Frobenius-Underwood: %v, Prime: %v, Error: %v\n", frob, prime, err);
 }
 
 main :: proc() {

+ 22 - 4
core/math/big/internal.odin

@@ -854,7 +854,7 @@ internal_int_mod :: proc(remainder, numerator, denominator: ^Int, allocator := c
 
 	if remainder.used == 0 || denominator.sign == remainder.sign { return nil; }
 
-	return #force_inline internal_add(remainder, remainder, numerator, allocator);
+	return #force_inline internal_add(remainder, remainder, denominator, allocator);
 }
 
 internal_int_mod_digit :: proc(numerator: ^Int, denominator: DIGIT, allocator := context.allocator) -> (remainder: DIGIT, err: Error) {
@@ -2747,9 +2747,27 @@ internal_int_count_lsb :: proc(a: ^Int) -> (count: int, err: Error) {
 	x: int;
 	#no_bounds_check for x = 0; x < a.used && a.digit[x] == 0; x += 1 {}
 
-	q := a.digit[x];
-	x *= _DIGIT_BITS;
-	x += internal_count_lsb(q);
+	when true {
+		q := a.digit[x];
+		x *= _DIGIT_BITS;
+		x += internal_count_lsb(q);
+	} else {
+		lnz := []int{
+   			4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+		};
+
+		q := a.digit[x];
+		x *= _DIGIT_BITS;
+		if q & 1 == 0 {
+			p: DIGIT;
+			for {
+				p = q & 15;
+				x += lnz[p];
+				q >>= 4;
+				if p != 0 { break; }
+			}
+		}		
+	}
 	return x, nil;
 }
 

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

@@ -185,14 +185,14 @@ internal_int_kronecker :: proc(a, p: ^Int, allocator := context.allocator) -> (k
 				a1.digit[0] + 1 cannot overflow because the MSB
 				of the DIGIT type is not set by definition.
 			 */
-			if a1.digit[0] + 1 & p1.digit[0] & 2 != 0 {
+			if ((a1.digit[0] + 1) & p1.digit[0] & 2) != 0 {
 				k = -k;
 			}
 		} else {
 			/*
 				Compute k = (-1)^((a1-1)*(p1-1)/4) * k.
 			*/
-			if a1.digit[0] & p1.digit[0] & 2 != 0 {
+			if (a1.digit[0] & p1.digit[0] & 2) != 0 {
 				k = -k;
 			}
 		}