首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >IEEE 754/iec 559

IEEE 754/iec 559
EN

Stack Overflow用户
提问于 2015-02-20 09:17:26
回答 3查看 3K关注 0票数 6

IEEE 754浮点格式是跨平台定义的吗?在位格式和endianness方面?

我愿意在我的代码中添加以下内容(作为初始版本):

代码语言:javascript
复制
static_assert(std::numeric_limits<float>::is_iec559, "Only support IEC 559 (IEEE 754) float");
static_assert(sizeof(float) * CHAR_BIT == 32, "Only support float => Single Precision IEC 559 (IEEE 754)");

static_assert(std::numeric_limits<double>::is_iec559, "Only support IEC 559 (IEEE 754) double");
static_assert(sizeof(float) * CHAR_BIT == 64, "Only support double => Double Precision IEC 559 (IEEE 754)");

static_assert(std::numeric_limits<long double>::is_iec559, "Only support IEC 559 (IEEE 754) long double");
static_assert(sizeof(float) * CHAR_BIT == 128, "Only support long double  => Exteneded Precision IEC 559 (IEEE 754)");
//  More asserts if required.
//  I noticed my current system has a sizeof(long double) => 128
//  But numeric_limits<long double>::digits  => 63
//  So we are not storing quad precision floats only extended.

如果我写我的浮点/双/长双二进制格式,这些可以在系统之间传输,而无需进一步解释。伊..。

代码语言:javascript
复制
void write(std::ostream& stream, double value)
{
     stream.write(reinterpret_cast<char const*>(&value), 8);
}

....

double read(std::istream& stream)
{
     double   value;
     stream.read(reinterpret_cast<char*>(&value), 8);
     return value;
}

还是我需要将整型组件分解为整数组件进行传输(正如this answer所建议的那样):

这里的区别是,我愿意将我支持的表示限制在IEEE-754上,这基本上解决了浮点值的二进制存储问题,还是需要采取进一步的步骤?

注意:对于不符合标准的平台(当我发现它们时),我愿意为代码设置特例,以便它们将IEEE-754读入本地表示。但是我想知道bit/endian是否有足够好的定义好的跨平台来支持存储/传输。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-02-20 20:00:46

位格式是很好的定义,但并不是所有的机器都是小终端.IEEE标准也不要求浮点数是特定的端点.您可以运行以下程序来查看double 42.0的字节模式

代码语言:javascript
复制
#include <stdio.h>
#include <numeric>
#include <limits>
using namespace std;

int main() {
  double d = 42;
  printf("%i\n", std::numeric_limits<double>::is_iec559);
  for (char *c = (char *)&d; c != (char *)(&d+1); c++) {
    printf("%02hhx ", *c);
  }
  printf("\n");
}

在一台使用g++ 3.4.5的未维护的旧Sun机器上,这将打印

代码语言:javascript
复制
1
40 45 00 00 00 00 00 00

在运行一个更新的g++的g++机器上:

代码语言:javascript
复制
1
00 00 00 00 00 00 45 40
票数 4
EN

Stack Overflow用户

发布于 2015-02-20 09:36:36

首先,您可能需要更改代码,以便它正确地检查类型大小.

代码语言:javascript
复制
static_assert(std::numeric_limits<float>::is_iec559, "Only support IEC 559 (IEEE 754) float");
static_assert(sizeof(float) * CHAR_BIT == 32, "Only support float => Single Precision IEC 559 (IEEE 754)");

static_assert(std::numeric_limits<double>::is_iec559, "Only support IEC 559 (IEEE 754) double");
static_assert(sizeof(double) * CHAR_BIT == 64, "Only support double => Double Precision IEC 559 (IEEE 754)");

static_assert(std::numeric_limits<long double>::is_iec559, "Only support IEC 559 (IEEE 754) long double");
static_assert(sizeof(long double) * CHAR_BIT == 128, "Only support long double  => Exteneded Precision IEC 559 (IEEE 754)");

问题是,IEEE-754不需要长双128位长.根据编译器和平台的不同,这种类型的长度可能会有所不同。但是,它指定了binary128,编译器可能支持,也可能不支持,具体取决于平台和实现(gcc有一个非标准的__float128类型)。标准只要求长倍至少和双倍一样精确,通常是80位长(gcc)或64 (VS)。

如果将受支持的表示限制为IEEE-754,则不应遇到任何问题。

票数 1
EN

Stack Overflow用户

发布于 2016-08-27 05:36:49

若要读写IEEE 754可移植,请使用这些例程。如果平台不是IEEE 754,您可能会丢失几个比特,但仍然会得到最接近的表示。

https://github.com/MalcolmMcLean/ieee754

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28625340

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档