以下假设您在通常的舍入到最近模式下使用标准 IEEE-754 浮点运算,这些运算很常见(有一些例外)。
如果 double 值在 float 值的正常范围内,那么当 double 舍入为 float 时发生的唯一变化是有效数(值的小数部分)从 53 位舍入到 24 位。这将导致最多 1/2 ULP(最小精度单位)的误差。浮子的 ULP 是不大于浮子的 2 的最大幂的2 -23倍。例如,如果浮点数为 7.25,则不大于它的 2 的最大幂为 4,因此其 ULP 为 4*2 -23 = 2 -21,约为 4.77e-7。所以区间 [4, 8) 中的 double 转换为 float 时的误差最多为 2 -22,约为 2.38e-7。再举一个例子,如果浮点数约为 0.03,则不大于它的 2 的最大幂是 2 -6,因此 ULP 为 2 -29,转换为 double 时的最大误差为 2 -30。
这些都是绝对错误。相对误差小于 2 -24,即 1/2 ULP 除以可能的最小值(特定 ULP 的区间中的最小值,因此限制它的 2 的幂)。例如,对于 [4, 8) 中的每个数字 x,我们知道该数字至少为 4 并且误差最多为 2 -22,因此相对误差最多为 2 -22 /4 = 2 -24。(误差不能正好是 2 -24因为在将 2 的精确幂从 float 转换为 double 时没有误差,所以只有当 x 大于 4 时才会有误差,所以相对误差小于,不等于, 2 -24.) 当您对正在转换的值有更多了解时,例如,它比 4 更接近 8,您可以更紧密地限制错误。
如果数字超出浮点数的正常范围,则错误可能会更大。最大有限浮点值为 2 128 -2 104,大约为 3.40e38。当您将 1/2 ULP(float 的;double 具有更精细的 ULP)的 double 转换为 float 时,将返回无穷大,当然,这是一个无限的绝对误差和一个无限的相对误差。(大于最大有限浮点数但小于 1/2 ULP 的 double 将转换为最大有限浮点数,并具有与上一段中讨论的相同的错误。)
最小正正常浮点数为 2 -126,约为 1.18e-38。此(含)1/2 ULP 内的数字将转换为它,但小于此的数字将转换为特殊的非规范化格式,其中 ULP 固定为 2 -149。绝对误差最多为 1/2 ULP, 2 -150。相对误差将很大程度上取决于被转换的值。
上面讨论了正数。负数的误差是对称的。
如果 double 的值可以精确地表示为 float,则转换没有错误。
将输入数字映射到新的区间可以减少特定情况下的错误。作为一个人为的例子,假设你所有的数字都是区间 [2 48 , 2 48 +2 24 ) 中的整数。然后将它们转换为浮点数会丢失所有区分值的信息;它们都将转换为 2 48。但是将它们映射到 [0, 2 24 ) 将保留所有信息;每个不同的输入都将转换为不同的结果。
哪种地图最适合您的目的取决于您的具体情况。