我的意思是,例如,我用IEEE-754单精度编码了以下数字:
"0100 0001 1011 1110 1100 1100 1100 1100" (approximately 23.85 in decimal)
上面的二进制数存储在文本字符串中。
问题是,如何在不丢失精度的情况下将这个字符串转换为IEEE-754双精度表示(有点像下面的,但值不同)?
"0100 0000 0011 0111 1101 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1010"
这是用IEEE-754双精度编码的< del >相同的数。
我已经尝试使用下面的算法将第一个字符串先转换回十进制数,但它失去了精度。
num in decimal = (sign) * (1 + frac * 2^(-23)) * 2^(exp - 127)
我在Windows平台上使用Qt C框架。
编辑:我必须道歉,也许我没有把问题表达清楚。我的意思是我不知道真正的值23.85,我只得到了第一个字符串,我想把它转换成没有精度损失的双精度表示。
首先,1用于识别二进制输入。
其次,这个数字并不代表23.85,而是略低。如果将其最后一个二进制数字从 0
翻转为 1
,则该数字仍不能准确表示 23.85,但会稍高一些。这些差异无法在浮点数中充分捕获,但它们可以近似地捕获为双精度值。
第三,你认为你正在失去的东西被称为准确性,而不是精确性。数字的精度总是通过从单精度转换为双精度而增长,而准确性永远无法通过转换提高(不准确的数字仍然不准确,但额外的精度使其更加明显)。
我建议在显示(或记录)数字之前转换为浮点数或四舍五入或添加一个非常小的值,因为增加精度会真正失去视觉外观。
请抵制在强制转换后立即取整并在后续计算中使用取整值的诱惑,这在循环中尤其危险。虽然这似乎可以纠正调试器中的问题,但累积的额外不准确可能会进一步扭曲最终结果。
IEEE-754(以及一般的浮点数)不能以完全精度表示周期性二进制小数。即使它们实际上是具有相对较小的整数分子和分母的有理数,也不是这样。某些语言提供了可能执行此操作的有理类型(它们也是支持无限精度整数的语言)。
因此,你发布的两个数字不是同一个数字。
事实上,它们是:
10111.11011001100110011000000000000000000000000000000000000000 ...10111.11011001100110011001100110011001100110011001101000000000 ...
其中 ...
表示 0
s 的无限序列。
斯蒂芬·卡农在上面的评论中为您提供了相应的十进制值(没有检查它们,但我没有理由怀疑他做对了)。
因此,你想做的转换无法完成,因为单个精度数字没有你需要的信息(你没有办法知道这个数字实际上是周期性的,还是只是看起来像是,因为碰巧有一个重复)。
好的:保留符号位,重写指数(减去旧偏差,再加上新偏差),并在尾数右侧加上零。。。
(正如@Mark所说,你必须单独处理一些特殊情况,即当偏置指数为零或最大值时。
问题内容: 我正在尝试将以下十六进制字符串转换为“ 41630D54FFF68872”到9988776.0(float-64)。 使用单精度float-32,我可以这样做: 但这会引发:java.lang.NumberFormatException:使用上面的64位十六进制时,Infinite或NaN。 如何将十六进制转换为使用64位IEEE-754编码的双精度浮点数? 谢谢 问题答案: 您需要双
由于所有Java浮点数(浮点数和双精度浮点数)在内部都表示为位,因此我想找到一种有效的算法来转换表示该浮点数或双精度浮点数位的字符串,并将其转换为相应的浮点数-我找不到它的内置库函数,所以我求助于自己编写它。 长度为32的二进制字符串表示浮点,其中长度为64的二进制字符串将转换为double。所有浮点数都可以转换为双精度浮点数,而不会损失精度。将忽略空格。 示例 “0 10000000 10010
问题内容: 尝试如下 输出:12.0 但我想获得12.00的精度 请让我知道正确的方法,而不在字符串类中使用format()方法 问题答案: 使用而不是双重: 之所以有效,是因为保持了“精度”,构造函数将其设置为从右边的数字开始,并在中使用它。因此,如果仅将其丢弃,它就会打印出来。
在单精度浮点数下,当我们输入的数字过大时会导致精度丢失。 比如 输入 16777217 实际存储是 16777216;输入 16777219 实际存储 16777220。 我好奇于为什么当输入 16777217 时就是减掉1,而输入 16777219 时就是加一。 这个是对应的单精度浮点数的存储格式 这个是我所列的转换误差的表格 能够看出 输入 16777217 的时候实际存储时 尾数位的第24位
问题内容: 我有一个原始浮点数,需要作为原始双数。简单地将浮标转换为两倍会给我带来额外的精度。例如: 但是,如果我不是强制类型转换,而是将浮点数输出为字符串,然后将字符串解析为双精度,那么我将得到所需的内容: 有没有比String返回更好的方法了? 问题答案: 这并不是说你实际上获得了更高的精度-而是浮标没有准确地代表你最初瞄准的数字。双被精确地表示原始浮子; 显示的是已经存在的“额外”数据。 例
问题内容: 与浮点变量一起使用时出现问题(向下舍入/截断精度部分)。如何正确执行? 游乐场:https : //play.golang.org/p/49TjJwwEdEJ 输出: 我期望的输出是的,但实际产量。 问题答案: 原始问题: Golang中的楼层号不正确 将Math.Floor与float变量一起使用时出现问题(向下舍入/截断精度部分)。我该怎么做呢? 我预计1980 * 0.1 / 1