简短问题:以最大精度定义的比较运算符的行为是什么? 意思是,如果我有两个数字(x和y)在精度上是相同的,那么当我做x<时,我总是期望得到相同的答案。 ÿ?
我意识到这似乎是一个愚蠢的问题,但让我详细说明。
我正在使用double
,我有一系列数字,如:
0: 62536.5477752959
1: 62536.4840613718
2: 62536.4576412381
3: 62522.8487197062
4: 62536.5473896233
5: 62536.5467941254
6: 62527.3508907998
7: 62536.5477752959
8: 62517.5900098039
9: 62536.5477752959
请注意,条目0,7和9具有相同的值。
当我这样做时(
)int low = 0, high = 0;
for(int i = 0; i < N; ++i) {
if(x[i] < x[low])
low = i;
if(x[i] > x[high])
high = i;
}
cout << "low: " << low << " high: " << high << endl;
我有时得到:low: 8 high: 0
,有时:low: 8 high: 7
我本来期望总是最低的指数值。
有什么想法吗?
[编辑缺失的大括号。]
答案 0 :(得分:4)
是的,假设您的浮点类型为IEEE754。任何两个double
值x
和y
表示x < y
,x == y
或x > y
中只有一个成立,但一些边缘情况,如+ Inf,-Inf或NaN。
当您使用十进制表示法来表示浮点值时,会出现混淆;例如没有这样的double
为62536.5477752959(或者您列表中的任何其他人)。
您提供的数字已被调试器/标准输出器截断,它们不在您提供的实际算法中使用的数字。请确保相同的十进制数始终生成相同的double
,此处不做任意选择:IEEE754要求选择最接近的double
。
如需进一步阅读,请参阅Is floating point math broken?
最后,将int i
替换为int i = 0
。目前,您的程序的行为是 undefined 。
答案 1 :(得分:2)
你可以使用库来回避内置类型的行为/限制:
<强> Live On Coliru 强>
pip install -U tensorflow tensorflow-gpu keras
打印
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <algorithm>
#include <iostream>
int main() {
using Float = boost::multiprecision::cpp_dec_float_100;
std::vector<Float> values = {
Float{ "62536.5477752959" }, Float{ "62536.4840613718" }, Float{ "62536.4576412381" }, Float{ "62522.8487197062" },
Float{ "62536.5473896233" }, Float{ "62536.5467941254" }, Float{ "62527.3508907998" }, Float{ "62536.5477752959" },
Float{ "62517.5900098039" }, Float{ "62536.5477752959" },
};
auto hilo = std::minmax_element(values.begin(),values.end());
std::cout << "low: " << *hilo.first << " high: " << *hilo.second << std::endl;
}
打印索引:
low: 62517.6 high: 62536.5