我写了一个用Leibniz公式计算PI编号的程序:
[
我写了一个初始化类型的for循环是" int" ,循环工作正常,但当我将初始化类型更改为" long"结果发生了变化。这仅在循环时间超过十亿时才会发生。这使得" int - loop"计算PI比" long-loop"更准确。我不知道为什么会这样。请帮我理解这个问题。谢谢!这是我的代码。
def after_sign_in_path_for(resource)
case resource.class
when Technician
new_services_path
when User
root_path
end
end
结果是:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int index_func(int number, int *array, int x);
int main(){
int n;
scanf("%d", &n);
int *nums = (int*)malloc(n*sizeof(int));
int i;
for(i=0; i<n; i++) {
scanf("%d", &nums[i]);
}
int j;
int counter = 0;
for(j=0; j<n-1; j++){
if((abs(nums[j+1] - nums[j]) != abs(n-1)) && (abs((nums[j+1] - nums[j]) != 1)))
{
counter = 0;
}
else
{
counter = 1;
}
}
if(counter == 0){
printf("ambiguous\n");
}else{
printf("non ambiguous\n");
}
free(nums);
return 0;
}
答案 0 :(得分:34)
实际上,当int
足够大时,你的第一个循环会在(2 * i + 1)
的计算中溢出i
,所以我不会依赖它的输出。
另一方面,第二个循环产生更正确的输出,因为(2 * j + 1)
不会溢出,因为它执行long
乘法。
这使得“int-loop”计算PI比“long-loop”
更准确
这可能只是一个巧合,因为int
循环中的计算溢出。
答案 1 :(得分:11)
因为你在线上溢出
result1 += sign/(2 * i + 1);
2*i
的值越过最大整数值
int范围是-2,147,483,648 to 2,147,483,647
,但是当您2*i
获得更大的值时,它会越过该范围。
最好坚持使用long
,这样可以提供正确的输出。
答案 2 :(得分:10)
2 * i
当我接近你的循环结束时溢出最大值 2147483647
使用long操作不会溢出。
正确的程序是使用长型。可能因为某些奇怪行为在正确的PI周围添加和删除了值,溢出会瞬间计算到更接近正确PI的值。
我认为更改少量值的for循环限制会将最终结果更改为距离正确PI更远的值。
答案 3 :(得分:9)
你有整数溢出。
signed int的最大容量为(2 ^ 31)-1或2,147,483,647。
(1,607,702,095 * 2)为3215404190,大于2,147,483,647。
当你将i改为long时,你将i的容量增加到(2 ^ 63)-1。
答案 4 :(得分:7)
注意到每个人都指向整数溢出,但您可能需要一个解决方案。 (如果您已经有一个,请忽略以下:))
在代码的(2 * i + 1)
部分出现溢出时,您应该将for循环中的i
最大化为(Integer.MAX_VALUE / 2 - 1)
,这会导致:
for (int i = 0; i <= (Integer.MAX_VALUE / 2 - 1); i++) {
result1 += sign/(2 * i + 1);
sign *= -1;
}
你也可以使用(Long.MAX_VALUE / 2 - 1)
对长篇文章进行操作,但它会运行很长时间。