一致性:将整数除以 2 的幂与 10 的幂?

Posted

技术标签:

【中文标题】一致性:将整数除以 2 的幂与 10 的幂?【英文标题】:Consistency: Dividing an integer by the powers of 2 vs powers of 10? 【发布时间】:2012-07-08 11:17:34 【问题描述】:

这是一个关于浮点运算的跨平台一致性和确定性的问题(IE 在不同的 CPU/系统上产生不同的结果)

哪个更可能保持跨平台一致(伪代码):

float myFloat = float ( myInteger) / float( 1024 )

float myFloat = float ( myInteger ) / float( 1000 )

平台是 C# 和 AS3。

.

AS3 版本:

var myFloat:Number = myInteger  /  1000 // AS3
var myFloat:Number = myInteger  /  1024 // AS3

- 好的,我添加了 AS3 版本进行说明,相当于上面的“C 伪代码”。正如您在 AS3 中看到的,所有计算,即使是整数,都自动作为浮点数执行,不需要强制转换(也不能避免它或强制运行时执行真正的整数除法) 希望这可以解释为什么我将所有内容都“投射”到浮点数中:我不是!这只是在其中一种目标语言中发生的事情!

【问题讨论】:

您没有在问题或标签中指定任何编程语言。在许多编程语言中,这两种结构同样具有可移植性和面向未来的能力。实际上,在许多编程语言中,“伪代码”中的除法是整数除法,结果是整数结果。 为了清楚起见,我添加了语言和“cast to float”。在 C# 中确实会被视为整数除法,但在 AS3 中,内部所有计算都以浮点数执行,并且自动隐含强制转换。 啊;别再换问题了! 我没有改变它,只是澄清“伪代码”部分,正如我所说的那样,其中一种语言是 AS3,在 AS3 var myInt:int = 1/3 + 2/3; // = 1 中没有任何“强制转换”浮动,如在 AS3 中,所有计算都在内部作为浮点数执行。因此,我添加了“更改”,我只是明确说明了 AS3 中发生的情况。当然,在 C# 中它是不同的,但由于我同时针对这两种语言,我必须在最低公分母上工作。 @MartinK:我不得不删除我原来的答案,因为它不再有效(因此,你改变了问题的意思!)。无论如何,我不确定 C# 和 AS3 的“最小公分母”是什么;它们是完全不同的语言,处理浮点问题的规范可能不同。 【参考方案1】:

第一个在两个平台上可能相同,因为不存在表示问题。特别是对于小整数(最高 8 位未使用),只有一个确切的结果,而且很有可能会使用这个结果。

但我不会依赖它。如果您需要有保证的确定性,我建议您自己在纯整数之上实现所需的算术。例如使用定点表示。

第二个可能不一致,即使在不同硬件或 .net 版本上使用相同的 C# 代码也是如此。见相关问题Is floating-point math consistent in C#? Can it be?

【讨论】:

固定点表示在 AS3 中是不可能的!在 AS3 中,所有计算,即使是整数,都以浮点数形式执行,即var myInt:int = 1/3 + 2/3; // = 1。在 C# 中,等效值为 = 0!无论如何,您是否建议除以 1024 至少应该比除以 1000 更安全? (虽然不是 100%)【参考方案2】:

我建议您阅读 IEEE 754-1985 标准。 A copy can be purchased for $43. 虽然已被 2008 版本取代,但它是浮点数的极好介绍,因为它只有 20 页,可读性强。它将向您展示为什么除以 1000 和除以 1024 都是确定性的,以及为什么前者可能有错误但后者没有(下溢除外)。它还将为您理解所获得的答案以及您为何走上错误的轨道提供了基础。

【讨论】:

正如我所说,我必须让相同的代码在 2 种不同的语言 C# 和 AS3 以及不同的系统上产生相同的结果(一个是客户端 PC/MAC 32/64 位,另一个是服务器 64 位)。因此,绝对不能保证 IEEE 754-1985 标准始终存在于所有方面。我正在寻找最小公分母的最差解决方案。【参考方案3】:

哪个更可能保持跨平台一致(伪代码):

除以 1024。 每个基于二进制的浮点系统(IEEE754、IBM、VAX、Cray)将除以 1024 到所有有限数将产生精确 产生给定的表示。原因是除以1024等于

将位向右移动 10 个位置,这意味着 将二进制指数减 10

如果数字太小(对于IEEE754 1E-38/1E-308),你会失去一个精确的结果,但这不是操作的问题,而是数字的有限范围......它根本无法准确显示这么小的结果。

由于不需要四舍五入,因此四舍五入不会有任何差异(是的,虽然大多数编程语言使用舍入到偶数,但有些语言可以选择另一种舍入模式)。

【讨论】:

以上是关于一致性:将整数除以 2 的幂与 10 的幂?的主要内容,如果未能解决你的问题,请参考以下文章

右移代替除以 2 的幂

leetcode326.三的幂(342.四的幂/231.二的幂)

MQ中的坑及高并发下保证接口的幂等性

MQ中的坑及高并发下保证接口的幂等性

分布式事务解决:可靠消息的最终一致性方案-消息重复发送问题与业务接口的幂等性设计

基于幂等表思想的幂等实践