我有一个问题,我试图重建现有系统中使用的公式,一个输入和一个输出的相当简单的公式:
y = f(x)
经过一番困惑后,我们设法找出了适合我们观察到的数据点的公式:
正如你所看到的,我们的理论模型非常适合观察到的数据:
除非我们绘制残差(即y = f(x) - actualY
),否则我们会看到残差中出现一些线:
很明显,这些线是在我们的公式中应用了一些中间舍入的结果,但在哪里并不明显。最终我们意识到原来的系统(我们试图逆向工程的系统)正在将值存储在一种中间Decimal
数据类型中:
- 分数精度为8位
- 使用0.5舍入舍入模型:
我们可以通过以下方式模拟分数中的 8 位精度:
multiply by 128 (i.e. 2^8)
apply the round
divide by 128 (i.e. 2^8)
将上面的等式更改为:
这显着减少了残差:
现在,以上所有内容都与我的问题无关,除了:
现在我想在Single Precision
使用浮点数的编程语言(和 Excel)中模拟浮点数Double Precision
。我想这样做是因为我认为这是需要的。
在上面的示例中,我认为原始系统使用的是Decimal data type with fixed 8-bit fractional precision using 0.5 round-up rules
. 然后我必须找到一种方法来用Double
数学模拟该计算模型。现在我认为原始系统正在使用Single
精确数学,我想使用Double
.
如何使用双精度模拟单精度舍入?
在我当前的模型中,我再次有属于常规线性模式的残差 - 这是四舍五入的标志:
问题是随着我的输入变量变得更大,错误变得更大,并且只可见。我意识到这可能是由于所有浮点数都归一化为IEEE 754 “科学记数法”这一事实引起的。
即使我错了,我仍然想尝试一下。
即使我不想尝试,我仍然在问这个问题
如何
Single
使用 模拟精确舍入Doubles
?
在我看来,我仍然可以应用“在 8 个小数位后舍入”的概念(尽管Single
精度浮点是 24 位),只要我可以首先“规范化”该值。例如
1234567898.76543
需要转换为(类似于):
1.23456789876543 E-09
然后我可以将我的“轮到第 24 位”(即 2^24 = 16,777,216)
floor(1.23456789876543E-09 * 16777216 + 0.5) / 16777216;
那么,问题是我可以应用什么组合sign
, abs
, ln
, exp
(或其他函数),以便我可以“规范化”我的值,将其舍入到第 n 个二进制位置,然后“去规范化”它?
注意:我意识到 IEEE 表示将二进制1
作为最高有效位。我可能不需要复制该行为以获得正确的结果。因此,这不是交易破坏者,也不是暗示整个方法失败的理由。