我写了这个小程序来计算pi。
在玩代码并试图找到最准确的结果时,我发现我的计算机无法计算结果。它可以在几秒钟内完成 33554430 重复,但是如果我将for循环增加到 33554431 它没有输出任何东西。
33554430 一个特殊号码?
public class CalculatePi{
public static void main(String[] args){
float pi=0;
int sign=1;
for(float i=1; i <= 33554430; i+=2){
pi += (sign*(1.0/i));
sign*= -1;
}
pi *= 4;
System.out.println(pi);
}
}
答案 0 :(得分:2)
你正在获得无限循环,因为在比较i <= 33554431
期间,int
值33554431
是promoted to a float
值,这对于浮点数来说太“精确”了等于33554432
。
然后,当您尝试将值增加+2
时,float
只是不够精确,无法从值33554432
增加。为了说明我的观点:
float f = 33554432;
System.out.println(f); //33554432
f += 2;
System.out.println(f); //33554432
因此,f
值不会因精度限制而增加。如果你增加它,比如说11
,你会得到33554444
(而不是33554443
),因为这是最接近该精度的数字。
33554430 一个特殊号码?
排序,而不是33554430,而是33554432.浮点数的第一个“特殊数字”是16777217
,这是第一个不能表示为float
的正整数(等于16777216
作为浮动)。因此,如果您将i
变量增加1
,这就是您要坚持的数字。现在,由于您按2
递增,因此您遇到的数字为16777216 * 2 = 33554432
。
答案 1 :(得分:1)
public class CalculatePi{
public static void main(String[] args){
float pi=0;
int sign=1;
for(float i=1; i <= 33554431; i+=2){
pi += (sign*(1.0/i));
sign*= -1;
if( i > 33554410) System.out.println(i);
}
pi *= 4;
System.out.println(pi);
System.out.println((float)33554431);
System.out.println((float)33554432);
System.out.println((float)33554434);
}
}
在for循环中将float与int进行比较。当您将33554431
(它的int值)转换为float时,您将获得3.3554432E7
。
这是关于准确性,精确度。当你跑:
System.out.println((float)33554431); // -> 3.3554432E7
System.out.println((float)33554432); // -> 3.3554432E7
System.out.println((float)33554434); // -> 3.3554432E7
所有3个打印3.3554432E7
,这意味着当你将浮点值33554432增加2时,你得到3.3554432E7
,这个值完全相同,你的循环将永远运行。
答案 2 :(得分:0)
此版本适用于两者。它是浮动循环变量导致问题:
public static class Extensions
{
public static string ReadTextResource(this Assembly asm, string resName)
{
string text;
using (Stream strm = asm.GetManifestResourceStream(resName))
{
using (StreamReader sr = new StreamReader(strm))
{
text = sr.ReadToEnd();
}
}
return text;
}
}
可能这是issue:
任何浮点值集的有限非零值都可以 以s·m·2(e-N + 1)的形式表示,其中s是+1或-1,m是 小于2N的正整数,e是Emin =之间的整数 - (2K-1-2)和Emax = 2K-1-1,包括端点,其中N和K是取决于设定值的参数。
答案 3 :(得分:0)
你的循环每次增加2。
2 * 33554430 = 67108860
2 ^ 26 = 67108864
也许Java在32位系统中存储浮点数,尾数为26位,指数为6位?