对变量和常量的操作在c中给出不同的结果
Opeartion on a variable and constant giving different result in c
简单计算:3^20%15。
根据计算器,答案是 6。
以下代码生成答案 7。
#include <stdio.h>
#include <math.h>
int main() {
int i = 20;
printf("%d\n", ((int)pow(3,20)%15));
return 0;
}
如果我用变量 i
替换 printf
语句中的 20
,它会给出 -8
作为输出。
假设计算器正确(或不正确?),程序中有什么问题?
谢谢。
pow(3,20)
的结果不适合您平台(或我的平台)上的 int
。因此,您会遇到意想不到的结果。
更改为更大的整数类型,例如 long long
即可。
此外,pow
处理在内存中未准确表示的浮点数(查找)。在转换为整数期间,这可能会导致某些错误。例如,对于 printf("%fl\n", (pow(3,20)));
我得到 3486784401.000000l
这不是一个精确的整数值。
这里可能发生的事情是:
- 在您的 C 实现中,
int
是 32 位,最小值为 −2,147,483,648,最大值为 2,147,483,647。
pow(3, 20)
的结果是3486784401。(见下面注释1。)
- 3486784401 对于
int
来说太大了,所以会溢出。在整数溢出的情况下,C 标准允许实现做任何事情。
- 在
(int) pow(3, 20)
中,到 int
的转换可能是在编译时通过生成最大值 2,147,483,647 计算出来的。然后除以 15 的余数是 7.
- 在
(int) pow(3, i)
中,到 int
的转换可能是在 运行 时通过产生最小值 −2,147,483,648 计算出来的。 (一些处理器为整数溢出产生这样的结果。)然后除以 15 的余数是 −8。
总结:
- 您的代码溢出,因此 C 标准未定义该行为。
- 编译器对
pow(3, 20)
和 pow(3, i)
的行为可能不同,因为它在编译时评估前者,在执行时评估后者。
备注
pow
return 的良好实施 pow(3, 20)
正好是 3486784401。不幸的是,糟糕的实施可能 return 不准确的值,例如 3486784401.000000476837158203125 或 3486784400.999999523162841796875.
简单计算:3^20%15。
根据计算器,答案是 6。
以下代码生成答案 7。
#include <stdio.h>
#include <math.h>
int main() {
int i = 20;
printf("%d\n", ((int)pow(3,20)%15));
return 0;
}
如果我用变量 i
替换 printf
语句中的 20
,它会给出 -8
作为输出。
假设计算器正确(或不正确?),程序中有什么问题?
谢谢。
pow(3,20)
的结果不适合您平台(或我的平台)上的 int
。因此,您会遇到意想不到的结果。
更改为更大的整数类型,例如 long long
即可。
此外,pow
处理在内存中未准确表示的浮点数(查找)。在转换为整数期间,这可能会导致某些错误。例如,对于 printf("%fl\n", (pow(3,20)));
我得到 3486784401.000000l
这不是一个精确的整数值。
这里可能发生的事情是:
- 在您的 C 实现中,
int
是 32 位,最小值为 −2,147,483,648,最大值为 2,147,483,647。 pow(3, 20)
的结果是3486784401。(见下面注释1。)- 3486784401 对于
int
来说太大了,所以会溢出。在整数溢出的情况下,C 标准允许实现做任何事情。 - 在
(int) pow(3, 20)
中,到int
的转换可能是在编译时通过生成最大值 2,147,483,647 计算出来的。然后除以 15 的余数是 7. - 在
(int) pow(3, i)
中,到int
的转换可能是在 运行 时通过产生最小值 −2,147,483,648 计算出来的。 (一些处理器为整数溢出产生这样的结果。)然后除以 15 的余数是 −8。
总结:
- 您的代码溢出,因此 C 标准未定义该行为。
- 编译器对
pow(3, 20)
和pow(3, i)
的行为可能不同,因为它在编译时评估前者,在执行时评估后者。
备注
pow
return 的良好实施pow(3, 20)
正好是 3486784401。不幸的是,糟糕的实施可能 return 不准确的值,例如 3486784401.000000476837158203125 或 3486784400.999999523162841796875.