将十进制定点/浮点格式打印为十六进制[关闭]

问题描述 投票:0回答:1
在我的通用库中增加了将十六进制的十进制定点数打印为十六进制的功能,并意识到我不是%100知道我应该如何表示数字的小数部分。快速的Google搜索建议我应该:

    乘以16
  1. 将整数部分转换为十六进制并将其添加到缓冲区中
  2. 去除整数部分
  3. 重复
  • 如此处建议https://bytes.com/topic/c/answers/219928-how-convert-float-hex

    此方法适用于浮点数(即eeee 754二进制格式),可以很好地工作。但是,我尝试将其采用为十进制定点格式(按8缩放),在纸上测试此方法后,我注意到某些分数(即

    。7),这会导致 .B3333 ...等。在我看来,这是非常不可取的。我还想知道,如果我尝试将其从字符串读取为定点格式,是否会导致精度下降。

    有人为什么不像其他任何2s补码十六进制数字那样打印分数部分吗?即

    17535.564453

    打印为447F.89CE5的地方虽然这是针对十进制定点的,但我正在寻找一种也可用于其他实数格式(例如ieee 754二进制)的解决方案。

    也许这两种方法还有另一种选择。有什么想法吗?

  • c math floating-point ieee-754 fixed-point
    1个回答
    2
    投票
    尽管问题询问定点,但是C标准在其有关浮点%a格式的信息中有一些有用的信息。 C 2018 7.21.6.1 8说:

    …如果缺少[用户请求的]精度,并且FLT_RADIX不是2的幂,则精度可以足以区分类型为double

    285)值,除了尾随零可能是省略;…

    脚注285说:

    精度

    p足以区分源类型的值,如果16 p-1

    > b n其中b FLT_RADIXn是以源类型的有效位数表示的基数-b位的数目…要直观地看到,请在实数行上将0到1的十进制定点数可视化。对于每个这样的数字

    x

    ,请可视化一个段,该段开始于前一个定点数的一半下一个定点数。除端点外,该段中的所有点比上一个或下一个数字更靠近x。现在,考虑所有单十六进制数字j / 16在哪里。它们位于某些细分市场中。但是,如果有100个段(从两位十进制数开始),则大多数段不包含那些单十六进制数之一。如果增加十六进制数字p的数量,直到16 p-1> b n,则十六进制之间的间隔数字小于段的宽度,并且每个段都包含一个十六进制数字。这表明使用

    p

    十六进制数字足以区分使用b n十进制数字生成的数字。 (这是足够的,但可能比必要的还多。)这意味着存在恢复原始十进制数字所需的所有信息,并且要避免从恢复原始十进制数字的准确性上损失,只需对从十六进制到十进制正确。如果不考虑前导零,则“像其他十六进制数字一样”打印分数是不够的。十进制数字“ 3.7”和“ 3.007”不同,因此分数部分不能仅格式化为“ 7”。如果采用约定将小数部分**(包括尾随零)转换为十六进制,则此方法可行。例如,如果十进制定点数在小数点后有四个十进制数字,则将3.7和3.007的小数部分视为7000和0070并将其转换为十六进制将保留所需的信息。转换回时,会将十六进制转换为十进制,将其格式化为四位数,然后将其插入十进制定点数中。在需要速度的情况下,这可能是一个合适的解决方案,但不能很好地代表人类使用。

    当然,如果只希望将信息保留在数字中,以便可以传输或存储,然后再恢复,则最好以最容易计算的转换方式(例如格式化)简单地传输代表数字的位。所有原始位都为十六进制。


    -1
    投票

    由于浮点数在内部是二进制的,所以不能精确表示0.7。这样您就不会得到无限的重复。您将得到准确的53位(14个十六进制数字为4 * 14 = 56位,所以这是限制)。实际上,将浮点数写为十六进制的主要原因是获得真实值的精确表示。

    将十六进制的十进制分数好像是一个整数本质上是没有意义的(例如,您丢掉了多少个前导零?),即使您将数字写为0x447F + 0x89CE5 / 0xF4240,实际上也不会捕获精确值,该精确值是分母为2的幂的分数。

    © www.soinside.com 2019 - 2024. All rights reserved.