如果我们使用float,则数字可以有多个表示,因此浮点除法的结果可能会产生按位不同的浮点数。但是如果分母是2的幂呢?
AFAIK除以2的幂只会移动指数,留下相同的尾数,总是产生按位相同的浮点数。是吗?
float a = xxx;
float result = n/1024f; // always the same result?
---更新----------------------
很抱歉我对于浮点数的IEEE黑魔法缺乏了解:),但我在谈论Guvante提到的那些数字:没有代表某些十进制数字,'不准确'的浮点数。对于这篇文章的其余部分,考虑到Guvante对这些词的定义,我将使用“准确”和“不准确”。
为简化起见,假设分子总是一个“准确”的数字。另外,让我们除以2的任何幂,但总是为1024.另外,我每次都以相同的方式进行操作(相同的方法),所以我说的是在不同的执行中得到相同的结果(对于相同的输入,当然)。
我问这一切是因为我看到不同的数字来自相同的输入,所以我想:如果我只使用'准确'浮点数作为分子并除以1024我只会改变指数,仍然有'准确的'浮动。
你问了一个例子。真正的问题是:我有一个模拟器有时产生0.02999994,有时相同输入产生0.03000000。我想我可以将这些数字乘以1024,得到一个'整数'('精确'浮点数),对于这两个数字是相同的,然后除以1024得到一个'精确'的圆形浮点数。
我被告知(in my other question)我可以转换为十进制,舍入并转换为浮动,但我想知道这种方式是否有效。
答案 0 :(得分:5)
如果我们使用浮点数
,则数字可以有多个表示
这个问题似乎是以不正确的前提为基础的;作为浮点数具有多个表示的唯一数字是零,可以表示为“正零”或“负零”。除了零之外,给定数字只有一个表示形式为浮点数,假设您正在谈论“双”或“浮点”类型。
或许我误解了。您所指的问题是否允许编译器以比可用于存储的32或64位更高的精度执行浮点运算?在某些情况下,这会导致分裂和乘法产生不同的结果。
答案 1 :(得分:4)
由于人们通常没有完全掌握浮点数,我会快速查看你的一些要点。浮点数中的每个特定位组合表示唯一编号。但是,因为该数字具有基数2小数部分,所以不存在某些十进制数的表示。例如1.1
。在这些情况下,您采用最接近的数字。 IEEE 754-2008指定舍入到最近,即使在这些情况下也是如此。
真正的困难在于你将两个“不准确”的数字组合在一起。这会引入问题,因为每个中间步骤都涉及舍入。如果使用两种不同的方法计算相同的值,则可以得出微妙的不同值。通常,当您想要相等时,可以使用epsilon处理。
现在回答你真正的问题,你能否除以2的幂,避免引入任何额外的'不准确'?通常你可以,但是与所有浮点数一样,非正规数和其他奇数情况都有它们自己的逻辑,显然如果你的尾数溢出你就会有困难。再次注意,在任何一个过程中都没有引入任何数学错误,只需要用有限的精确度进行数学运算,这需要间歇性地舍入结果。
编辑:回答新问题
你所说的可以奏效,但几乎相当于四舍五入。另外,如果你只是在寻找平等,你应该像前面提到的(a - b) < e
一样使用episilon来获得一些小值e
(0.0001
可以在你的例子中使用)。如果您打算打印出一个漂亮的数字,而您正在使用的框架并不是您喜欢的,那么一些舍入将是描述您的解决方案的最直接方式,这总是一个优势。