此方法适用于浮点数(即eeee 754二进制格式),可以很好地工作。但是,我尝试将其采用为十进制定点格式(按8缩放),在纸上测试此方法后,我注意到某些分数(即
。7),这会导致 .B3333 ...等。在我看来,这是非常不可取的。我还想知道,如果我尝试将其从字符串读取为定点格式,是否会导致精度下降。
有人为什么不像其他任何2s补码十六进制数字那样打印分数部分吗?即17535.564453
打印为447F.89CE5的地方虽然这是针对十进制定点的,但我正在寻找一种也可用于其他实数格式(例如ieee 754二进制)的解决方案。也许这两种方法还有另一种选择。有什么想法吗?
%a
格式的信息中有一些有用的信息。 C 2018 7.21.6.1 8说:…如果缺少[用户请求的]精度,并且脚注285说:FLT_RADIX
不是2的幂,则精度可以足以区分类型为double
的285)值,除了尾随零可能是省略;…
精度> b n其中b 是p足以区分源类型的值,如果16 p-1
FLT_RADIX
,n是以源类型的有效位数表示的基数-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并将其转换为十六进制将保留所需的信息。转换回时,会将十六进制转换为十进制,将其格式化为四位数,然后将其插入十进制定点数中。在需要速度的情况下,这可能是一个合适的解决方案,但不能很好地代表人类使用。当然,如果只希望将信息保留在数字中,以便可以传输或存储,然后再恢复,则最好以最容易计算的转换方式(例如格式化)简单地传输代表数字的位。所有原始位都为十六进制。
由于浮点数在内部是二进制的,所以不能精确表示0.7。这样您就不会得到无限的重复。您将得到准确的53位(14个十六进制数字为4 * 14 = 56位,所以这是限制)。实际上,将浮点数写为十六进制的主要原因是获得真实值的精确表示。
将十六进制的十进制分数好像是一个整数本质上是没有意义的(例如,您丢掉了多少个前导零?),即使您将数字写为0x447F + 0x89CE5 / 0xF4240,实际上也不会捕获精确值,该精确值是分母为2的幂的分数。