Swift 中的浮点十六进制表示法

5
我不明白浮点数在Swift中如何用十六进制符号表示。苹果的文档显示0xC.3p0等于十进制的12.1875。请问有人可以帮我理解如何进行这种转换吗?我知道小数点之前的十六进制值0xC等于十进制的12,但是小数点后面的3p0让我困惑不解。
5个回答

12

根据文档:

浮点数字面量
...
十六进制浮点数文字由0x前缀、可选的十六进制小数和十六进制指数组成。十六进制分数由小数点后跟一系列十六进制数字组成。指数由大写或小写字符p作为前缀,后跟一系列表示在指数前的值乘以2的幂的十进制数字。例如,0xFp2代表15×22,它的值为60。同样,0xFp-2代表15×2-2,它的值为3.75。

在您的情况下

  0xC.3p0 = (12 + 3/16) * 2^0 = 12.1875

另一个例子:

  0xAB.CDp4 = (10*16 + 11 + 12/16 + 13/16^2) * 2^4 = 2748.8125

这种格式与%aprintf格式非常相似(例如,参见http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html)。它可以用于直接指定浮点数的二进制IEEE 754表示,有关详细信息,请参见为什么Swift使用基数2来表示十六进制浮点数值的指数?


很好的答案。十六进制字面量对于浮点数的最大优点是它们总是准确的,而许多十进制值在浮点数中无法精确表示。另外,如果你要得到一个翻译器,请确保它能说波切语。 - rickster
如果你想成为一个真正的极客,请注意星球大战的参考。 - Demircan Celebi
@Martin,你的另一个例子有错误-0xC是12而不是13,0xD是13;)但最终结果是正确的。 - matm

5

Interpret 0xC.3p0 using the place value system:

C (or 12) is in the 16^0 place
3 is in the 16^-1 place (and 3/16 == 0.1875)
p says the exponent follows (like the e in 6.022e23 in base 10)
0 is the exponent (in base 10) that is the power of 2 (2^0 == 1)

所以把它们结合起来

0xC.3p0 = (12 + (3/16)) * 2^0 = 12.1875

文档对我来说似乎是相互矛盾的。首先它说:“十六进制浮点文字由0x前缀、可选的十六进制小数部分和十六进制指数组成。”然后它又说:“指数由大写或小写的“p”前缀后跟一系列十进制数字组成……”这听起来像是文档编辑错误。我的猜测是指数与表达式的其余部分一样采用16进制。 - Duncan C
1
测试显示指数是以10为底,但它表示2的幂。因此,p10代表的是2^10而不是2^16 - vacawama
为什么Swift十六进制浮点数表示法的指数是2的幂?在十进制中,科学计数法采用10的幂,这会将值上移或下移一定数量的十进制数字。如果指数也是十六进制,那么它将通过一定数量的十六进制数字将值上移或下移。这样更清晰和一致。 - Duncan C

1
为了总结我所读到的内容,你可以看到以下的表述:
0xC.3p0 = (12*16^0 + 3*16^-1) * 2^0 = 12.1875

从马丁R的上面的例子中:

0xAB.CDp4 = (10*16^1 + 11*16^0 + 12*16^-1 + 13*16^-2) * 2^4 = 2748.8125

0

0xC是12,就像你说的一样。小数部分是((1/16)*3)*10^0。

所以你需要取出小数部分并除以16。然后你需要将它乘以2的幂次方,这个幂次方是在p之后的数字。


0

十六进制-(0-9,A=10,B=11,C=12,D=13,E=14,F=15)p0表示2^0 例如:- 0xC = 12(前缀0x表示十六进制) 在小数部分中,如0xC.3p0,我们将数字除以16的幂

因此,在这里,它是3/16 = 0.1875 所以0xC.3p0 = (12 + (3/16) ) 2^0

如果是0xC.43p0,那么对于4,我们将使用4/(16),对于3,我们将使用3/(16 ^2),如果小数部分增加,则类似。 例如:0xC.231p1 = (12 + 2/16 + 3/(256) + 1/(16^3)) 2^1 = 24.27392578125


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接