我试图使这个工具正常工作,但未能找到使我的测试单元失败的错误。你能告诉我这个bug可能在哪里吗?我很确定algorithm是对的。
package piwords;
public class PiGenerator {
/**
* Returns precision hexadecimal digits of the fractional part of pi.
* Returns digits in most significant to least significant order.
*
* If precision < 0, return null.
*
* @param precision The number of digits after the decimal place to
* retrieve.
* @return precision digits of pi in hexadecimal.
*/
public static int[] computePiInHex(int precision) {
// TODO: Implement (Problem 1.d)
int [] b = new int [precision];
for (int a = 0; a < precision; a++) {
b[a] = piDigit( a + 1 );
}
return b;
}
/**
* Computes a^b mod m
*
* If a < 0, b < 0, or m < 0, return -1.
*
* @param a
* @param b
* @param m
* @return a^b mod m
*/
public static int powerMod(int a, int b, int m) {
// TODO: Implement (Problem 1.b)
if (( a > 0 ) && ( b > 0 ) && ( m > 0 )) {
Double t = new Double(0);
t = Math.pow(a, b);
Double re = new Double( t % m );
return re.intValue();
}
return -1;
}
/**
* Computes the nth digit of Pi in base-16.
*
* If n < 0, return -1.
*
* @param n The digit of Pi to retrieve in base-16.
* @return The nth digit of Pi in base-16.
*/
public static int piDigit(int n) {
if (n < 0) return -1;
n -= 1;
double x = 4 * piTerm(1, n) - 2 * piTerm(4, n) -
piTerm(5, n) - piTerm(6, n);
x = x - Math.floor(x);
return (int)(x * 16);
}
private static double piTerm(int j, int n) {
// Calculate the left sum
double s = 0;
for (int k = 0; k <= n; ++k) {
int r = 8 * k + j;
s += powerMod(16, n-k, r) / (double) r;
s = s - Math.floor(s);
}
// Calculate the right sum
double t = 0;
int k = n+1;
// Keep iterating until t converges (stops changing)
while (true) {
int r = 8 * k + j;
double newt = t + Math.pow(16, n-k) / r;
if (t == newt) {
break;
} else {
t = newt;
}
++k;
}
// return s+t; // little bug, should be as following
return ( ( s + t ) - Math.floor( s + t ) );
}
}
=============================================== ====================
这是我的test课程
=============================================== ===================
package piwords;
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.experimental.theories.suppliers.TestedOn;
public class PiGeneratorTest {
@Test
public void basicPowerModTest() {
// 5^7 mod 23 = 17
assertEquals(17, PiGenerator.powerMod(5, 7, 23));
assertEquals(44, PiGenerator.powerMod(11, 5, 51));
}
// TODO: Write more tests (Problem 1.a, 1.c)
@Test
public void testComputePiInHex() {
int[] a = {2, 4, 3, 15, 6};
assertArrayEquals(a, PiGenerator.computePiInHex(5));
}
}
答案 0 :(得分:1)
您应该将b > 0
更改为b >= 0
,然后结果似乎没问题
请注意,对于较大的值,您不能依赖pow
中的双数(powerMod
},因为它们的精度有限。你应该使用整数并使用这个相等:
a ^(b + c)mod m =(a ^ b mod m)*(a ^ c mod m)mod m