如何检查是否使用了IEEE 754单精度(32位)浮点表示?

时间:2014-01-28 11:21:22

标签: c algorithm floating-point double

我想在目标板上测试以下内容:

  • 使用IEEE 754单精度(32位)浮点变量实现“浮动”吗?
  • 使用IEEE 754双精度(64位)浮点变量实现“双重”?

我可以用简单的C程序测试它的方法有哪些。

3 个答案:

答案 0 :(得分:6)

不存在简单的测试。

今天绝大多数系统都使用IEEE-754格式进行浮点运算。但是,大多数C实现不完全符合IEEE 754(与IEC 60559相同),并且不设置预处理器标识符__STDC_IEC_559__。在没有此标识符的情况下,确定C实现是否符合IEEE 754的唯一方法是:或者组合:

  • 阅读其文档。
  • 检查其源代码。
  • 测试它(当然,当只有详尽的测试可以确定时,这当然是困难的。)

在许多C实现和软件应用程序中,可以忽略或解决与IEEE 754的偏差:您可以编写代码,就像IEEE 754正在使用中一样,并且许多代码将在很大程度上起作用。然而,有许多事情可能使一个毫无戒心的程序员绊倒;即使遵守完整的规范,写入完全正确的浮点代码也很困难。

常见偏差包括:

  • 执行中间算术的精度高于标称类型。例如,使用double值的表达式可以用long double精度计算。
  • sqrt在每种情况下都不会返回正确的舍入值。
  • 其他数学库例程从正确舍入的结果返回可能稍微偏离(几个ULP)的值。 (事实上​​,没有人实现IEEE 754-2008中推荐的所有数学例程,同时保证了正确的舍入和保证的绑定运行时间。)
  • 可以将次正规数(浮点格式边缘附近的微小数字)转换为零,而不是按照IEEE 754的规定进行处理。
  • 十进制数字(例如,源代码中的3.1415926535897932384626433)和二进制浮点格式(例如,通用double格式,IEEE-754 64位二进制)之间的转换并不总是舍入正确地,在任何转换方向上。
  • 仅支持舍入到最近的模式;不支持IEEE 754中指定的其他舍入模式。或者它们可用于简单算术但需要使用特定于机器的汇编语言来访问。标准数学库(coslog等等很少支持其他舍入模式。

答案 1 :(得分:3)

在C99中,您可以查看__STDC_IEC_559__

#ifdef __STDC_IEC_559__
/* using IEEE-754 */
#endif

这是因为C99引用的国际浮点标准是IEC 60559:989(IEC 559和IEEE-754是之前的描述)。从C语言到IEC 60559的映射是可选的,但如果在使用中,实现定义了宏__STDC_IEC_559__(C99标准的附录F),因此您可以完全依赖它。

另一种方法是手动检查float.h中的值,例如FLT_MAXFLT_EPSILONFLT_MAX_10_EXP等是否符合IEEE-754限制,尽管从理论上讲,可能存在具有相同值的另一种表示。

答案 2 :(得分:3)

首先,您可以在维基百科中找到有关ISO / IEC / IEEE 60559(或IEEE 754)的详细信息:

Floating point standard types

正如F. Goncalvez告诉你的那样,宏__STDC_IEC_559__为您提供有关编译器的信息,如果它符合IEEE 754的要求。

接下来,我们

但是,您可以使用宏FLT_EVAL_METHOD获取其他信息。

此宏的值表示:

  • 0所有操作和常量都在所用类型的范围和精度中进行评估。

  • 1 floatdouble类型的操作在double的范围和精度中进行评估,而long double以您自己的方式进行...

  • 2所有类型的评估均以long double的精度和范围完成。

  • -1 Indeterminate

  • 其他负值:已定义实施(取决于您的编译器)。

例如,如果FLT_EVAL_METHOD == 2,并且您在浮点变量x中保存了多个计算的结果,则所有操作和常量都以最佳预算计算或处理,即{ {1}},但只有最终结果会舍入为long double所具有的类型。

这种行为减少了数字错误的影响。

为了了解浮点类型的详细信息,您必须观察标准标题x提供的常量宏。
例如,请看这个链接:

Çharacteristics of floating point types


如果您的实施不符合IEEE 754标准,您可以尝试在标准标题<float.h>中查找详细信息(如果存在)。
此外,您还必须阅读编译器的文档。

例如,编译器GCC解释浮点数的作用:

Stadus of C99 features in GCC