手动将Double转换为Float,反之亦然

3
我可以担任中文翻译,以下是翻译结果:

我知道double是64位,float是32位:

浮点数:

1 bit for the sign
8 bits for the exponent
24 bits for the fraction

双精度浮点数:

1 bit for the sign
11 bits for the exponent
53 bits for the fraction / mantissa

问题是,我们如何手动将它们相互转换?(我知道会丢失精度)。 将双精度转换为单精度只需要进行32位右移吗? 将单精度转换为双精度只需要进行32位左移吗?

  1. "我知道double是64位,而float是32位的:" --> 在许多情况下可能是这样,但并非绝对如此。
  2. "手动将它们互相转换?(我知道会丢失精度)" 将float转换为double不会丢失精度。只有从doublefloat的转换才会有真正的问题。
- undefined
1个回答

5

先不考虑符号,因为两种格式相同。

如果指数域全是1:

  • 数据是正无穷或 NaN。
  • 如果尾数域全是0,则数据是正无穷。返回一个数字,其符号与上述相同,指数域全部为1,尾数域全部为0。
  • 否则,数据是NaN。返回一个数字,其符号与上述相同,指数域全部为1,并且尾数以某种合理的方式更改(标准未完全定义)。

如果指数域既不是全1也不是全0:

  • 将指数域视为二进制数(例如,110111是103)。减去该格式的偏差(IEEE-754 binary32为127,binary64为1023),得到实际指数。
  • 从“1.”开始,然后跟着尾数域的位数,例如“1.00001111000000000000001”。这样可以得到实际的尾数。继续以下操作。

如果指数域全是0:

  • 以1开始,然后减去该格式的偏差。这会给出实际的指数。
  • 从“0.”开始,然后跟着尾数域的位数,例如“0.00001111000000000000001”。这样可以得到实际的尾数。继续以下操作。

如果实际尾数为零,则返回一个数字,其中包括上述的符号、指数域中的所有零和尾数域中的所有零。

如果实际尾数不是以“1.”开头,则将其左移一位(乘以2)并从实际指数中减去1。重复此过程,直到尾数以“1.”开头为止。

如果实际指数等于或超过目标格式的最大有限指数(binary32为127,binary64为1023):

  • 如果超过最大有限指数,则按上述描述返回正无穷。
  • 如果仅等于最大有限指数,则将尾数四舍五入为目标格式中尾数位数的数字(binary32为24,binary64为53)(使用生效的任何舍入规则,通常是近似到最近的偶数)。如果这导致它向上舍入到(二进制)“10.”,则如上返回正无穷。否则,继续以下操作。

如果实际指数等于或小于目标格式的最小正常指数(binary32为−126,binary64为−1022):

  • 将有效数字舍入到目标格式中的有效数字位数。
  • 从有效数字中删除前导的“1.”,并使用“.”后面的位(对于二进制32位为23位,对于二进制64位为52位)来形成有效数字编码。
  • 加上格式的偏移量来计算有偏指数。
  • 返回一个数字,其符号与上述相同,有偏指数为计算出的值,有效数字编码为计算出的值。

否则,结果将是次正常的(可能会四舍五入为零):

  • 令S为最小正常指数减去实际指数。
  • 令P为目标格式中有效数字字段中的位数(对于二进制32位为23位,对于二进制64位为52位)减去S。(P+1是给定次正常指数的目标格式中可用于有效数字的位数。它可以是零或负数,但下面的舍入可能有效地使它变为1。)
  • 将有效数字乘以2P并将其舍入为整数(使用正在生效的任何舍入规则)。
  • 返回一个数字,其符号与上述相同,指数字段全为零,有效数字字段为刚才所述的舍入有效数字(表示为二进制整数)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接