当前位置: 首页 > 知识库问答 >
问题:

在C中使用IEEE754浮点数表示浮点是否安全?

阳昊
2023-03-14

浮点是C语言中定义的实现,因此没有任何保证。

我们的代码需要可移植,我们正在讨论是否可以在协议中使用IEEE754浮动。出于性能考虑,如果我们在发送或接收数据时不必在定点格式之间来回转换,那就太好了。

虽然我知道平台和架构之间在longwchar_t的大小上可能存在差异。但我似乎找不到任何关于浮点的具体信息。

到目前为止,我发现在big endian平台上html" target="_blank">字节顺序可能会颠倒。虽然有些平台不支持浮点运算,但包含floatdouble的代码甚至无法链接。否则,平台似乎坚持IEEE754单精度和双精度。

那么,假设浮点在IEEE754中(如果可用)安全吗?

编辑:回应评论:

你对“安全”的定义是什么?

我所说的安全是指,一个系统上的位模式在另一个系统上是相同的(在字节旋转以处理endianness之后)。

共有3个答案

彭俊智
2023-03-14

我建议你需要更仔细地研究一下便携设备的定义。

我还认为你对“安全”的定义是不够的。即使二进制表示(允许endianness)是可以的,对变量的操作也可能表现出不同的行为。毕竟,很少有不涉及变量操作的浮点应用程序。

如果您想支持所有已创建的主机体系结构,那么假设IEEE浮点格式本质上是不安全的。您必须处理支持不同格式的系统、完全不支持浮点的系统、编译器具有选择浮点行为的开关的系统(有些行为与非IEEE格式相关),具有可选协处理器的CPU(因此浮点支持取决于是否安装了额外的芯片,但CPU的其他变体是相同的)、在软件中模拟浮点操作的系统(一些这样的软件模拟器在运行时是可配置的),以及浮点实现有缺陷或不完整的系统(可能基于IEEE,也可能不基于IEEE)。

如果你愿意将自己限制在2000年后年份的硬件上,那么你的风险较低,但不是零。实际上,那个年代的所有CPU都以某种形式支持IEEE。然而,你仍然(与旧的CPU一样)需要考虑你希望支持的浮点操作,以及你愿意接受的浮点操作。不同的CPU(或软件仿真)的浮点实现不如其他CPU完整,有些CPU默认配置为不支持某些功能,因此有必要更改设置以启用某些功能,这可能会影响代码的性能或正确性。

如果您需要在应用程序之间共享浮点值(可能在具有不同功能的不同主机上,用不同的编译器构建,等等),那么您需要定义一个协议。该协议可能涉及IEEE格式,但是您的所有应用程序都需要能够处理协议和它们的本地表示之间的转换。

景仲渊
2023-03-14

有一个宏需要检查(从C99开始):

__STDC_IEC_559__整数常量1,用于表示符合附件F(IEC 60559浮点运算)中的规范。

IEC 60559(ISO/IEC/IEEE 60559的简称)是IEEE-754的另一个名称。

附录F随后建立了C浮动类型和IEEE-754类型之间的映射:

C浮动类型与IEC 60559格式匹配如下:

  • 浮点类型与IEC 60559单一格式匹配
陶福
2023-03-14

基本上,当前非穿孔卡使用的所有体系结构,包括嵌入式体系结构和外来信号处理体系结构,都提供以下两种浮点系统之一:

  • IEEE-754
  • IEEE-754除了废话。也就是说,它们主要实现754,但在一些更昂贵和/或更复杂的位上成本较低

最常见的廉价产品:

  • 将正则值刷新为零。这使某些有时有用的定理无效(特别是,如果ab在2的因子内,则a-b可以精确表示的定理),但在实践中,这通常不会成为问题。
  • 无法将infNaN识别为特殊的。这些架构将无法遵循将infNaN视为操作数的规则,并且可能不会饱和为inf,而是产生大于FLT_MAX的数字,其他架构通常将其识别为NaN
  • 除法和平方根的正确舍入。保证结果在精确结果的1-3 ulps内比在1/2 ulp内要容易得多。一个特别常见的情况是除法被实现为倒数乘法,这会损失一点精度。
  • 更少或没有保护数字。这是一个不寻常的廉价输出,但意味着其他操作可以关闭1-2 ulps。

BUUUUT...即使那些除了blah架构之外的架构仍然使用IEEE-754的数字表示。除了字节排序问题,在架构A上描述浮动的位基本上保证在架构B上具有相同的含义。

所以只要你关心的只是价值观的体现,你就没事。如果你关心操作的跨平台一致性,你可能需要做一些额外的工作。

编辑:正如Chux在评论中提到的,平台之间不一致的一个常见额外来源是使用扩展精度,如x87的80位内部表示。这与廉价的相反,并且(经过适当的处理)完全符合IEEE-754和C标准,但它同样会导致不同架构之间的结果不同,甚至编译器版本之间的结果不同,以及明显轻微且不相关的代码更改。然而:由于扩展精度,特定的x86/x64可执行文件不会在不同的处理器上产生不同的结果。

 类似资料:
  • 问题内容: 比较浮点数和这样的整数是否安全? 根据JLS(5.6.2。二进制数值提升),如果其中一个参数为,则另一个参数将转换为比较之前的值。但是据我了解,如果转换后的float与原始float二进制相同,则这样的比较将返回true。我们如何确保呢? 问题答案: 是的,您的具体示例很好,因为和都可以精确地表示为。 请注意,通常情况下并非如此:有很多大值无法完全表示为。例如,即使2_000_000_

  • 3.2. 浮点数 Go语言提供了两种精度的浮点数,float32和float64。它们的算术规范由IEEE754浮点数国际标准定义,该浮点数规范被所有现代的CPU支持。 这些浮点数类型的取值范围可以从很微小到很巨大。浮点数的范围极限值可以在math包找到。常量math.MaxFloat32表示float32能表示的最大数值,大约是 3.4e38;对应的math.MaxFloat64常量大约是1.8

  • 问题内容: 我想将浮点数表示为四舍五入到一定位数的字符串,并且从不使用指数格式。本质上,我想显示任何浮点数并确保它“看起来不错”。 这个问题有几个部分: 我需要能够指定有效位数。 有效位数必须是可变的,而字符串格式化运算符不能做到这一点。[编辑]我已经改正了;字符串格式化操作符可以做到这一点。 我需要将其四舍五入到一个人期望的方式,而不是像1.999999999999 我想出了一种方法来完成此任务

  • 本文向大家介绍C#浮点数的表示和基本运算,包括了C#浮点数的表示和基本运算的使用技巧和注意事项,需要的朋友参考一下 1 浮点数的表示 通常,我们可以用下面的格式来表示浮点数 S P M 其中S是符号位,P是阶码,M是尾数 对于IBM-PC而言,单精度浮点数是32位(即4字节)的,双精度浮点数是64位(即8字节)的。两者的S,P,M所占的位数以及表示方法由下表可知 S P M 表示公式 偏移量 1

  • 我编写了一个程序来演示Go中的浮点错误: 它打印: 这与用C编写的相同程序的行为相匹配(使用双代码类型) 但是,如果改用,程序就会陷入无限循环!如果将C程序修改为使用而不是,它将打印 为什么在使用时,Go程序的输出与C程序的输出不一样?

  • 我最近一直在开发一个需要存储和加载大量数据的系统,包括单精度浮点值。我决定在网络上对整数的字节顺序进行标准化,并决定以big-endian格式存储浮点值,即: 理想情况下,我希望提供像和这样的函数,因为我已经将它们用于抽汲整数,并且我还希望以一种尽可能具有平台独立性的方式实现这一点(同时假设类型对应于IEEE754 32位浮点值)。是否有某种方法,可能使用,要这样做吗? 我有一个似乎有效的答案,我