【问题标题】:How to represent Infinity in floating/double values in C++?如何在 C++ 中以浮点/双精度值表示无穷大?
【发布时间】:2021-05-08 23:16:01
【问题描述】:

正如cppreference 所说,“在 IEEE 754 中,浮点数最常见的二进制表示形式,正无穷大是指数的所有位都被设置并且分数的所有位都被清除的值。”。我试过这个代码 sn-p,但我没有看到指数位设置。我是不是哪里错了?

#include <iostream>
#include <limits>
#include <bitset>
#include <math.h>
using namespace std;
int main() {
    float a = 0b00000000000000000000000000000000;

    double b = std::numeric_limits<double>::infinity();
    bitset<64> x(b);

    cout<<x<<endl;
    return 0;
}

它在控制台上打印 0000000000000000000000000000000000000000000000000000000000000000。

【问题讨论】:

  • bitset&lt;64&gt; x(b) - 这使用构造函数std::bitset::bitset(unsigned long long)
  • 打开编译器警告。你在这里从double 制作long。我不确定这是否是无限的定义行为。
  • @Thomas:我的编译器警告被调高了,Apple Clang 11.0 没有报告任何警告。
  • 嗯,确实!即使使用-Wall -Wextra -pedantic,gcc 和 clang 也不会对此发出警告。那为什么我记得看到类似“从浮点数制作整数而不进行强制转换”的警告?
  • 您必须添加 -Wconversion 才能看到这些警告。

标签: c++ ieee-754 infinite


【解决方案1】:

00000000000000000000000000000000000000000000000000000000000000000

真的吗?

我的指纹

#include <cmath>
#include <iostream>
#include <limits>
#include <bitset>

const char NL = '\n';

int main() {
    typedef union {
        double   d;
        uint64_t u;
    } du;

    du b;
    
    b.d = std::numeric_limits<double>::infinity();
    std::bitset<64> x(b.d);

    std::cout << x << " " << b.u << NL;
    std::cout << std::bitset<64>(b.u) << NL;
    return 0;
}

10000000000000000000000000000000000000000000000000000000000000000 9218868437227405312

最后一行打印

0111111111110000000000000000000000000000000000000000000000000000

是的,UB,我知道,我知道

【讨论】:

  • 1000000000000000000000000000000000000000000000000000000000000000 也不是无穷大的表示。
  • @eerorika 我同意。我为无穷位表示添加了输出。
【解决方案2】:

std::bitset 没有接受double 的构造函数。当您传递double 时,您改为调用接受unsigned long long 的构造函数,并且double 首先隐式转换为unsigned long long

问题是,unsigned long long 不能表示无穷大,因此程序的行为是未定义的。标准说:

[conv.fpint]

浮点类型的纯右值可以转换为整数类型的纯右值。 转换截断;也就是说,小数部分被丢弃。 如果截断的值无法在目标类型中表示,则行为未定义。


要查看位,您可以先将浮点“bitcast”为整数类型,然后将该整数传递给 bitset:

auto int_b = std::bit_cast<std::uint64_t>(b);
std::bitset<64> x(int_b);

【讨论】:

  • 啊哈,sd::bit_cast - 每天都学点东西
【解决方案3】:

线

bitset<64> x(b);

b 隐式转换为unsigned long long(或C++11 之前的unsigned long)以调用std::bitsetbitset(unsigned long long) 构造函数。

请注意,在浮点类型和整数类型之间进行转换时,如果无法在目标类型中表示值,则行为未定义 (N4659 7.10/1)。因此,以这种方式创建 bitset 可能会导致 anything 被打印。

【讨论】:

    猜你喜欢
    • 2010-11-11
    • 2021-07-02
    • 1970-01-01
    • 2011-05-17
    • 1970-01-01
    • 1970-01-01
    • 2021-10-10
    • 1970-01-01
    • 2011-04-18
    相关资源
    最近更新 更多