繁体   English   中英

比较算子的数值精度

[英]Numerical precision of comparison operators

简短问题:以最大精度定义的比较运算符的行为是什么? 意思是,如果我有两个数字(x和y)在精度上是相同的,那么当我做x <y时,我总是期望得到相同的答案吗?

我意识到这可能看起来像一个愚蠢的问题,但让我详细说明。 我正在使用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我本来期望总是最低的指数值。

有任何想法吗?

[编辑缺失的大括号。]

是的,假设您的浮点类型为IEEE754。 任何两个doublexy都表示x < yx == yx > y中只有一个成立,除了一些边缘情况,如+ Inf,-Inf或NaN。

当您使用十进制表示法来表示浮点值时,会出现混淆; 例如,有没有这样的double如62536.5477752959(或你的清单上的任何其他一个为此事)。

您提供的数字已被调试器/标准输出器截断,它们不是您提供的实际算法中使用的数字。 请确保相同的十进制数始终生成相同的double ,此处没有任意选择:IEEE754要求选择最接近的double

有关进一步阅读,请参阅浮点数学是否已损坏?

最后,用int i = 0替换int i 目前,程序的行为未定义

可以使用库来回避内置类型的行为/限制:

住在Coliru

#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

要打印索引:

// indexes:
std::cout << "low: " << (hilo.first-values.begin()) << " high: " << (hilo.second-values.begin()) << std::endl;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM