我有一个家庭作业来模拟浮点转换,例如:
int y = /* ... */;
float x = (float)(y);
。 。 。但显然没有使用类型转换。没关系,我不会有任何问题,除非我找不到任何具体的、具体的定义来说明此类转换到底应该如何运行。
我已经编写了一个运行得相当好的实现,但它偶尔不太匹配(例如,它可能在指数中放入值 3 并用 1 填充尾数,但“基本事实”将指数值为 4,尾数用零填充)。事实上,两者是等价的(某种程度上,通过无限级数)是令人沮丧的,因为位模式仍然是“错误的”。
当然,我得到了模糊的东西,比如来自分散网站的“向零舍入”,但老实说,我的搜索一直被 C 新手问题所困扰(例如,“什么是 Actor ?”,“我什么时候使用它?”)。因此,我找不到适用于显式定义指数和尾数的一般规则。
帮忙?
最佳答案
由于这是家庭作业,我将仅发布一些关于我认为棘手的部分的注释 - 当整数的大小大于 float 的精度时进行舍入。听起来您已经有了获取指数和尾数的基础知识的解决方案。
我假设您的浮点表示形式是 IEEE 754,并且舍入的执行方式与 MSVC 和 MinGW 的执行方式相同:使用“银行家舍入”方案(老实说,我不确定是否需要该特定舍入方案按照标准;这就是我测试的对象)。剩下的讨论假设要转换的 int 大于 0
。负数可以通过处理其绝对值并在末尾设置符号位来处理。当然,无论如何,0
都需要特殊处理(因为没有msb可找到)。
由于尾数有 24 位精度(包括最高位的隐含 1
),因此整数最大为 16777215
(或 0x00ffffff
>) 可以准确表示。除了通过位移将数据放到正确的位置并根据位移计算正确的指数之外,没有什么特别的事情要做。
但是,如果 int 值的精度超过 24 位,则需要进行舍入。我使用以下步骤进行了舍入:
- 如果丢弃位的最高位为
0
,则无需执行任何操作。尾数和指数可以保留。 - 如果丢弃位的最高位为
1
,并且剩余丢弃位有一个或多个位设置,则尾数需要递增。如果尾数溢出(超过 24 位,假设您尚未删除隐含的 MSB),则尾数需要右移,并且指数递增。 - 如果丢弃位的最高位为 1,并且其余丢弃位均为
0
,则仅当最低有效位为1 时,尾数才会递增仅
。尾数溢出的处理与情况2类似。
由于尾数增量仅在全部为 1
时才会溢出,因此如果您没有携带尾数的 msb(即,如果您已经删除了它,因为它会被删除)在最终的浮点表示中),那么尾数增量溢出的情况可以简单地通过将尾数设置为零并增加指数来修复。
关于c - 显式 int32 -> float32 转换的规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9288241/