在所有操作系统上,IEEE浮动和双重保证是相同的大小吗?

时间:2014-06-11 07:32:38

标签: c++ floating-point posix portability

我正在使用OS便携式数据库系统。我希望我们的数据库文件是可移植的操作系统,以便客户可以自行决定将其数据库文件移动到其他类型的操作系统。由于这个用例,我需要我的数据类型在操作系统中保持一致,并且我想知道IEEE浮点数和双数据是否保证在任何字节大小都相同OS?

4 个答案:

答案 0 :(得分:6)

C ++几乎没有说浮点类型的表示。

[basic.fundamental]/8说(强调我的):

  

有三种浮点类型:floatdoublelong double。类型double提供的精度至少与float一样,而类型long double提供的精度至少与double一样多。类型float的值集是类型double的值集的子集;类型double的值集是类型long double的值集的子集。 浮点类型的值表示是实现定义的。积分和浮动类型统称为算术类型。标准模板std::numeric_limits(18.3)的特化应指定实现的每种算术类型的最大值和最小值。

如果您只是使用floatdoublelong double编写C ++代码,除了特定编译器的文档中给出的那些代码之外,您几乎没有任何保证。从std::numeric_limits隐含。

另一方面,IEEE 754提供了其浮点类型的行为和二进制表示的精确定义。这些定义完全不足以保证所有IEEE 754平台上的相同行为,因为(例如)IEEE 754有时允许将多个操作折叠在一起,而结果比执行两个操作更精确分别。这可能对您的具体情况不重要,因为您只是希望文件是可移植的,并且可能不太关心相同的查询对不同平台上的文件创建相同的更改,因为您正在加载相同的文件在不同平台上采用相同的方式。

所以问题是:“如何获得C ++的便携式IEEE 754实现?”。

这个问题的答案有些棘手。合理平台的大多数C ++编译器至少会提供floatdouble,它们大致符合IEEE 754的binary32binary64规范(尽管您需要阅读每个人的文档)编译器确定)。

或者,您可以使用软件浮点实现或包装,例如FLIPlibgcc's soft-floatSoftFloatSTREFLOP。这些库有时仍会根据C ++标准对实现进行假设,而这些实现并非完全可移植,因此使用风险自负。

答案 1 :(得分:2)

- cut-- Nevermind https://stackoverflow.com/a/24157568/2422450为浮点大小提供了更好的解释。

如果您考虑将这些浮点数存储在二进制数据文件中,请确保不要弄乱字节顺序或endianness。如果您要转储原始浮点数,某些系统会以不同的顺序存储字节,因此将刚读取的4个字节转换为double可能会产生一些令人惊讶的结果。

答案 2 :(得分:2)

<强> std::numeric_limits<T>::is_iec559

确定给定类型是否遵循IEC 559,这是IEEE 754的另一个名称。

这进一步证明IEEE是可选的,并提供了一种检查是否使用IEEE的方法。

C++11 N3337 standard draft 18.3.2.4 numeric_limits成员

  

static constexpr bool is_iec559;

     

56当且仅当类型符合IEC 559标准时才为真。 (217)

     

57对所有浮点类型都有意义。

     

(217)国际电工委员会标准559与IEEE 754相同。

示例代码:

#include <iostream>
#include <limits>

int main() {
    std::cout << std::numeric_limits<float>::is_iec559 << std::endl;
    std::cout << std::numeric_limits<double>::is_iec559 << std::endl;
    std::cout << std::numeric_limits<long double>::is_iec559 << std::endl;
}

输出:

1
1
1

在Ubuntu 16.04 x86-64上。

__STDC_IEC_559__是C的类似宏:https://stackoverflow.com/a/31967139/895245

<强>原理

这是一篇有趣的文章,描述了不修复尺寸背后的理由,以及解决它的热门问题:http://yosefk.com/blog/consistency-how-to-defeat-the-purpose-of-ieee-floating-point.html

答案 3 :(得分:0)

他们是。 “float”将是32位,“double”将是64位。字节排序可能不同;它与32位和64位整数完全相同。

如果您需要扩展精度:那可能是也可能不是“long double”。扩展精度使用80位,但“long double”可能有额外的填充位。