algorithm - 基于 IEEE 754 手动将十进制浮点转换为位表示的最简单方法,无需使用任何库

标签 algorithm floating-point bit-manipulation ieee-754

我知道有多种方法可以使用书面库读取 IEEE 754 float 的每一位。

我不希望这样,我希望能够手动将十进制 float 转换为基于 IEEE 754 的二进制表示形式。

我了解 IEEE 754 的工作原理,并且我只是尝试应用它。

我在这里问这个问题只是想看看我的方法是正常的还是愚蠢的,我也想知道PC如何快速做到这一点。


如果给我一个字符串中的十进制 float ,我需要弄清楚E是什么以及M是什么。

  1. 取出两部分:整数部分i和小数部分f

  2. 处理f。我不断乘以2并得到整数部分(0或1)并删除整数部分然后重复,直到它变成0

  3. i转换为位。这很容易,我只需不断地 mod 2div 2 即可获得 i 的所有位。

例如,转换f部分

0.390625 * 2 = 0.78125 0
0.78125 * 2 = 1.5625 1
0.5625 * 2 = 1.125 1
0.125 * 2 = 0.25 0
0.25 * 2 = 0.5 0
0.5 * 2 = 1 1
0

在本例中,0.390625 的临时位为 0 1 1 0 0 1


现在,我有了 if 的位。

如果 i 的所有位均为 0,则在 f 的位上,我将其向左移动,直到第一个 1 消失,根据M默认隐藏 1。我得到M,然后给出转移到E的值,当然考虑到E的基线。

如果i不为0,那么我连接两个位部分并计算需要执行多少次shift_right才能使连接的位为1,然后将此值赋予E


我想我的步骤都没有错。但我觉得非常麻烦。

有没有简单、干净的方法?

PC 是如何做到的?

最佳答案

查看 Frama-C 中的文件 src/lib/floating_point.mlsrc/lib/floating_point.mli 。它们实现了单精度和 double 从十进制表示形式到 float 的转换(由于 double rounding 问题,您无法从后者获得前者),无需任何外部库。这些文件受 LGPL 2.1 管辖。此实现是几篇从 this one 开始的博客文章的主题。并继续this one .

这可能接近最简单的转换函数,因为在编写这个函数时,我没有性能限制,只希望保持代码尽可能简单和正确,而不希望依赖于现有的库例如MPFR。

...
type parsed_float = {
  f_nearest : float ;
  f_lower : float ;
  f_upper : float ;
}

val single_precision_of_string: string -> parsed_float
val double_precision_of_string: string -> parsed_float
...

关于algorithm - 基于 IEEE 754 手动将十进制浮点转换为位表示的最简单方法,无需使用任何库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22962040/

相关文章:

algorithm - 请帮我选择一个哈希

c - 以位为单位增加大小的有效条件

c - Win32 "C"未处理的异常在错误的位置中断

math - sqrt(x+a) - sqrt(x) 的数值稳定评估

floating-point - 如何在 Rust 中使用带有 f64 的 HashMap 作为键?

c++ - 我不明白为什么我在按位或短字符和字符时得到这个结果

c++ - 为什么字符串中的最后一个符号在 'std::remove' 之后加倍?

c++ - 如何左移最低有效零?

c - 单行表达式分支并清除 bool 标志?

java - 问题插入heapsort