- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我在进行一些按位练习时遇到了这个不寻常的错误。当 pow()
的输出被强制为 unsigned int
, pow()
的结果当指数变为零时使用变量调用,而当指数为文字整数时,结果被
正常
强制为0xFFFFFFFF(2^32 - 1).只有当值过大(在本例中为 2^32)时才会发生这种情况。用作指数参数的变量类型似乎不会影响此结果。我还尝试将两次调用的输出存储到 pow()
作为 double ,然后在引用变量时应用强制转换;差距依然存在。
#import <math.h>
int main (void) {
int thirtytwo = 32; // double, unsigned, etc... all yielded the same result
printf("Raw Doubles Equal: %s\n", pow(2, 32) == pow(2, thirtytwo) ? "true" : "false"); // -> true
printf("Coerced to Unsigned Equal: %s\n", (unsigned) pow(2, 32) == (unsigned) pow(2, thirtytwo) ? "true": "false"); // -> false
return 0;
}
出于好奇,我通过 clang/llvm 运行相同的代码,并获得了不同的结果:无论指数是否为变量,将结果强制转换为 unsigned int 会产生零(如预期)。
编辑:最大 32 位无符号整数是 2^32 - 1
,因此强制输出实际上正确。我的错误是超出了整数大小限制。为什么 gcc 基本上四舍五入到最大整数值是一个有趣的好奇心,但不是特别重要。
最佳答案
编译器将使用常量折叠将 pow(2, 32)
替换为常量结果; pow(2, thirttwo)
将在运行时计算。 C11 实际上允许编译时计算比相应的运行时计算(C11 6.6p5)更精确:
If a floating expression is evaluated in the translation environment, the arithmetic range and precision shall be at least as great as if the expression were being evaluated in the execution environment.
例如,众所周知,GCC 就是这样做的。因此,C 标准并不真正要求第一个打印 true
(and in practice this does occur in some implementations)。
至于为什么第二个打印false
:是因为pow(2 ^ 32)
不能用32位的unsigned int表示。 C11 6.3.1.4 :
When a finite value of real floating type is converted to an integer type other than _Bool, the fractional part is discarded (i.e., the value is truncated toward zero). If the value of the integral part cannot be represented by the integer type, the behavior is undefined.
因此,第二个输出 false
是由于未定义的行为。与将整数转换缩小为无符号整数不同,对于从 float 到偶数无符号整数的转换,溢出是明确未定义的。
值得注意的是,我无法让我的 GCC 6.2.0 警告 (unsigned int)pow(2, 32)
的编译时未定义行为。 (我尝试使用 -lm -Wall -Werror -pedantic -ubsan -Wfloat-conversion -Wconversion -Wextra -std=c11
没有任何输出)。
关于c - 如果指数是变量,为什么从 pow() 输出的超大值不以相同的方式强制转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43062561/
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 9 年前。 Improv
我发现了 pow(x, n) 的迭代实现,它需要 o(log n) 时间和常量空间,如下所示: double pow(double x, int n) { double left = x;
我想创建一个特征,说它实现了num_traits::pow::Pow - Rust。 我的特征当前定义为: pub trait PrimeSieveTrait: AddAssign + MulAs
对于我的项目,我应该在 java 中创建一个图形计算器(绘制图形),并以函数作为输入。我已经找到了一种正确绘制函数图的方法。但是我想不出一种方法可以让解释器理解该功能。如果我能够做到这一点,以便我可以
我发现对于大整数,math.pow() 没有成功给出它的整数版本。 (我在使用 math.pow 实现时遇到了一个错误 Karatsuba multiplication)。 例如: >>> a_Siz
问题或多或少说明了一切。 calling a host function("std::pow ") from a __device__/__global__ function("_calc_psd")
我想知道,因为当我在检查模式下运行我的代码时,似乎出现了一些差异。例如: List getFactors(int n) { List factors = [[1, n]]; doubl
pow(a/b,x) 和 pow(b/a,-x) 在精度上有区别吗?如果存在,将小于 1 的数字提升为正幂或将大于 1 的数字提升为负幂会产生更准确的结果吗? 编辑:让我们假设 x86_64 处理器和
此代码在 Windows 上的 Visual Studio 2010 上正确编译,但我在 Linux、g++ 上遇到此错误。谁能解释一下如何解决这个问题? int bits; T scale; std
Python内置的pow(x, y)(没有第三个参数)返回的结果和math.pow()返回的值有区别吗>,在两个 float 参数的情况下。 我问这个问题是因为 documentation对于 mat
这个问题在这里已经有了答案: Why was std::pow(double, int) removed from C++11? (1 个回答) 关闭 9 年前。 在 C++ 03 中,使用例如st
我可以将pow()与#include 一起使用,而无需使用using关键字或::运算符。为什么? 最佳答案 来自标准的[headers]/4。 Except as noted in Clause 20
我觉得这很有趣: System.out.println( (long)(Math.pow(2,63) - 1) == Long.MAX_VALUE); // true System.out.prin
这个打印 100: int j=2; int i= pow(10,2); printf("%d\n", i); 这个打印出 99: int j=2; int i= pow(10,j); print
这也是一个与数学相关的问题,但我想用 C++ 实现它...所以,我有一个 2^n 形式的数字,我必须计算它的数字总和(以 10 为基数;P)。我的想法是用下面的公式来计算: sum = (2^n mo
我看到这个关于 std::pow 的老问题:What is more efficient? Using pow to square or just multiply it with itself? 旧
我正在尝试比较 pow(x,2.0) 和 pow(x,2.0000001) 的性能,但我认为 2.0 会快得多,但它们的速度相同。我什至通过使用 -Xint 参数运行 jar 来删除 JIT 优化。
我的 linux 版本是 4.19.0-6-amd64 #1 SMP Debian 4.19.67-2+deb10u1 (2019-09-20) x86_64 GNU/Linux我的 gcc 版本是
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 6 年前。 Improve t
python3 中的 pow() 函数提供指数的值。 >>>pow(2,3) 8 Python3 支持负指数,即 可以使用 pow(10,-1) 表示。当我计算 pow(4,-1,5) 时,它给出了输
我是一名优秀的程序员,十分优秀!