Java - ตามจำนวนเต็ม
โปรแกรมนี้ไม่ได้ใช้ pi และไม่ได้เรียกใช้ฟังก์ชั่นภายนอกใด ๆ - ไม่แม้แต่ sqrt เพียงใช้ง่ายเลขคณิต - +
, -
, และ*
/
นอกจากนี้นอกจากขั้นตอนการปรับสเกลมันทำงานเฉพาะกับจำนวนเต็ม โดยทั่วไปมันจะแบ่งทรงกลมเป็นลูกบาศก์เล็ก ๆ แล้วนับจำนวนที่อยู่นอกกรอบ
public class Box {
private static final int MIN = 10000;
private static final int MAX = MIN * 2;
private static final int[] SQ = new int[MAX * MAX + 1];
static {
int t = 1;
for (int i = 1; i <= MAX; ++i) {
while (t < i * i) SQ[t++] = i - 1;
}
SQ[MAX * MAX] = MAX;
}
public static long outsideInt(int r, int w, int z) {
int r2 = r * r;
int o = z - r + 1;
if (w < r * 2) {
int t = 1 - SQ[r2 - w * w / 4];
if (t < o) o = t;
}
long v = 0;
for (int i = o; i <= r; ++i) {
int d = r2 - i * i;
int j0 = SQ[d];
v += 1 + 3 * j0;
for (int j = 1; j <= j0; ++j)
v += 4 * SQ[d - j * j];
}
return v;
}
public static double outside(double x, double y, double z, double d) {
double f = 1;
double w = x < y ? x : y;
double r = d / 2;
while (r < MIN) {
f *= 8;
r *= 2;
w *= 2;
z *= 2;
}
while (r > MAX) {
f /= 8;
r /= 2;
w /= 2;
z /= 2;
}
return outsideInt((int) r, (int) w, (int) z) / f;
}
public static void main(final String... args) {
System.out.println(outside(1, 1, 1, 1));
System.out.println(outside(1, 1, 0, 1));
System.out.println(outside(1, 1, 0.5, 1));
System.out.println(outside(1, 0.999, 1, 1));
System.out.println(outside(0.1, 1, 1, 0.5));
}
}
เอาท์พุท:
0.0
0.5235867850933005
0.26178140856157484
0.27938608275528054
0.06542839088004015
ในรูปแบบนี้โปรแกรมต้องการหน่วยความจำมากกว่า 2GB (ทำงานได้-Xmx2300m
ที่นี่) และทำงานช้ากว่าที่กำหนด มันใช้หน่วยความจำในการคำนวณกลุ่มของรากที่สอง (คำนวณ); มันไม่จำเป็นจริงๆ แต่ถ้าไม่มีมันจะช้ากว่ามาก เพื่อปรับปรุงความต้องการและความเร็วของหน่วยความจำให้ลดค่าของค่าMIN
คงที่ (ซึ่งจะลดความแม่นยำลง)