std::p ow 与整数类型进行比较,与整数类型进行比较
std::pow with integer parameters, comparing to an integer type
根据 http://en.cppreference.com/w/cpp/numeric/math/pow,当std::pow
与整数参数一起使用时,结果被提升为double
。
那么我的问题如下:
将整数类型与std::pow(int1, int2)
的结果进行比较有多安全?例如,下面的if
能否计算为 true?
std::size_t n = 1024;
if(n != std::pow(2, 10))
cout << "Roundoff issues..." << endl;
也就是说,rhs 上的结果是否有可能类似于 1023.99...9,因此当转换为 size_t 时变为 1023?
我的猜测是,回应是一个很大的NO,但想知道确定。我在检查矩阵等的维度时使用这些比较,我不想在任何地方都使用std::round
。
你应该问这很有趣,因为 StackOverflow 上的其他人有一个问题,这个问题是由应用于小整数pow
没有计算出他们平台上的明显结果这一事实引起的(另请参阅我的文章)。
所以是的,当pow
应用于小整数时,参数和理想的数学结果都是完全可表示的。这不会强制exp
的实现返回数学结果,因为没有标准指定pow
不能被多个 ULP 不准确。至少有一个非常流行的平台默认提供了一个pow
函数,该函数不会将pow(10, 2)
计算为 100,但您可以自由地冒险pow(2, N)
也许它总是会返回您有权期望的整数。
结果完全可表示时,对整数参数的pow
应该始终为您提供正确的答案。 问题是,它没有。 有一些现代平台(例如,许多Linux发行版,无论是旧的还是最新的),它没有。 找到一堆SO问题并不难,人们给出了pow
非常好的输入,它返回了一个非常错误的答案。
对于该特定示例,它应始终返回 false,特别是因为您使用的是 int 类型,因此不会有舍入错误。
您需要谨慎舍入误差的地方是当您比较两个不同的算术函数时,这些函数返回长小数的浮点数或双精度数。很多时候,由于不同的舍入和不同的操作,它们会返回为不相等。
正如几个答案所指出的那样,即使对于小数字,结果应该是完全可表示的,但也有一些低质量的实现。
对于使用 const 表达式的情况,例如:
std::pow(2, 10)
许多编译器将使用内置函数,例如gcc
和clang
将使用内置函数,这些函数可能会使用查找表或更简单的公式来处理这些琐碎的情况。对于上述情况,我们可以看到使用 godbolt gcc
在编译时计算值:
movl $1024, %esi
这些结果更有可能是正确的,因为问题C:我用pow(10,2)和pow(10,j)得到了不同的结果,j=2;证明。
- 将模板化的类型与C++中的某些类/类型进行比较
- C++中"std::sort"比较器的不同类型
- 比较两个整数在C++中与未知 int 类型的相等性
- 如何使用变量模板比较 C++ 17 中的变量类型?
- 比较LLVM值的类型
- 用于比较基元类型的std::可选的有趣程序集
- 在C++中返回基元类型数组(Java比较)
- 为模板类中的特定类型编写比较器函数
- 为什么比较函数类型需要指定为模板参数?
- C++,"由于数据类型范围有限,比较总是正确的"
- 如何在C++中比较 lambda 函数的返回类型?
- C++ - 比较模板和类之间的数据类型
- 类型ID指针和引用比较差异?
- 在C++中,您能否像比较类型一样比较模板
- 使用具有自定义比较类型的关联容器时出现的问题
- 在Template中设置默认比较类型
- STL中使用的C++自定义比较类型(函数谓词与较少结构)
- C++类型比较:类型 ID 与双重调度dynamic_cast
- 比较类型指针
- double比较类型的变量总是返回false