【发布时间】:2020-02-10 05:37:41
【问题描述】:
在我的通用库中添加将十进制定点数打印为十六进制的功能,并意识到我不是 %100 确定我应该如何表示数字的小数部分。快速谷歌搜索表明我应该:
- 乘以 16
- 将整数部分转换为十六进制并添加到缓冲区中
- 去掉整数部分
- 重复
这里建议https://bytes.com/topic/c/answers/219928-how-convert-float-hex
此方法适用于浮点数(ieee 754 二进制格式),并且可以正常工作。但是,我尝试将其应用于我的十进制定点(按 8 缩放)格式,并且在纸上测试这种方法后,我注意到一些分数(即 .7),这会导致重复模式.B3333...等等。 对我来说,这看起来很不受欢迎。我还想知道如果我尝试将它从字符串读取到我的定点格式中,这是否会导致精度损失。
有什么理由为什么有人不会像任何其他 2s 补码十六进制数一样打印小数部分?即 17535.564453 打印为 447F.89CE5
虽然这是针对十进制定点的,但我正在寻找一种也可用于其他实数格式(例如 ieee 754 二进制)的解决方案。
也许这两种方法还有另一种选择。有什么想法吗?
【问题讨论】:
-
为什么不直接使用
%a格式?见这里:cplusplus.com/reference/cstdio/printf 它的设计目的是精确地表示浮点数,而不会损失精度。 -
@alias 2 原因。问题中提到的#1,这是我不支持的定点格式。尽管我可能也会将此处找到的任何解决方案应用于 IEEE 754 格式。 #2 不能使用任何标准库。这真的不是如何做的问题,而是为什么以及是否有更好的方法的问题。
-
“其中 17535.564453 打印为 447F.89CE5”令人困惑。 17535.53830432891845703125(基数 10)是 447F.89CE5(基数 16)和 17535.564453(基数 10)是 447F.907FFDE...(基数 16)。解释 17535.564453 如何转换为 447F.89CE5。这不符合上面的步骤 1-4。
-
“我还想知道,如果我尝试将它从字符串读取到我的定点格式中,这是否会导致精度损失。” --> 如果代码读入
.B3333...,它将永远不会完成,因为这是一个无限长的输入。如果代码读入_足够的_.B3333...,那么精度损失可以最小化。到现在为止,需要公布多少“十进制定点数”的编码细节。 -
当它是关于定点格式时,为什么用浮点标准 IEEE-754 标记?为什么用浮点标记?
标签: c math floating-point ieee-754 fixed-point