这个浮点数的小数部分的前32位是什么?

15

我正在查看维基百科上的SHA256伪代码

具体来说,我正在查看以下部分。

//Initialize variables
//(first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):
h0 := 0x6a09e667

我正试图弄清楚h0是如何生成的。从注释中我知道这应该是2的平方根的小数部分。我相信可以通过输入以下内容来获取2的平方根的小数部分。以下所有代码均来自Python repl。

>>> math.modf(math.sqrt(2))[0]
0.41421356237309515

在文件顶部声明了所有常量的表示都是大端字节序。我知道我的环境是小端字节序,因为我打印了这个。

>>> import sys
>>> sys.byteorder
'little'

根据我手动更改h0中的十六进制值,小端表示应为0x67e6096a。

>>> int(0x67e6096a)
1743128938

我现在遇到了瓶颈。我尝试过多种操作,但没有一种能得到这个结果。我不知道如何获得浮点数小数部分的前32位。我知道我的0.41421356237309515(float)结果可以以某种方式转换为1743128938(int),但我真的不知道该怎么做。请问获取浮点数小数部分前32位所需的步骤是什么?请只给出Python解答。

谢谢。

3个回答

18
  1. 使用Windows计算器计算sqrt(2) (1.4142135623730950488016887242097)
  2. 取小数部分 (0.4142135623730950488016887242097)
  3. 乘以2的32次方 (1779033703.9520993849027770600526)
  4. 将整数部分用十六进制表示 (6A09E667)

完成。 (向OP致歉,没有提供Python答案,但我希望方法很清晰。)


2
好的,这不是一个Python的答案,但它确实向我展示了我的问题。我发现我犯的错误是试图将小数部分乘以10^n,其中n是一个整数,是最大的n,其中sqrt(2)的小数部分*(10^n)仍然可以包含在无符号4字节整数中。然后我取得那个结果并进行强制转换(向下取整)以获得一个整数。哈哈,我真是太傻了。 - Stephen Cagle

13

对于十六进制常量,字节序并不重要;每个数字都是一个半字节,最低有效半字节最后出现。但如果你处理大小不同的指针,则字节序很重要。如果确实需要使用字节顺序,则可以使用struct模块来帮助完成。无论如何,您已经成功地检索了小数部分;将其转换为十六进制很容易,只需简单地乘以并截断即可得到整数:

>>> hex(int(math.modf(math.sqrt(2))[0]*(1<<32)))
'0x6a09e667'

因为Python将十六进制常量处理为“半字节流”,而不是短整型、整型或长整型(或其他类型),所以我不必担心字节顺序?这难道不会使Python的十六进制字面常量始终成为大端序吗?如果这是一个愚蠢的问题,那我很抱歉,因为我很容易被搞混。 :) - Stephen Cagle
有点是,但这与Python无关。这只是我们书写数字的顺序。请注意,这个顺序是从阿拉伯书写中继承而来的,那里的文本是从右到左排列的;从这个角度来看,它是小端的。然而,它并没有被分成字节,因此字节交换并不相关。 - Yann Vernier

6

Python可以将IEEE 754浮点数据以十六进制值的形式精确显示出来。它包括隐含的前导1,十六进制中的尾数和指数值:

>>> math.sqrt(2).hex()
'0x1.6a09e667f3bcdp+0'

根据需要进行切片,例如:

>>> '0x'+math.sqrt(2).hex().split('.')[1][:8]
'0x6a09e667'

有趣的是,我不知道你可以使用十六进制来表示浮点数。今天学到了很多。 - Stephen Cagle
我们还注意到这是一个截断值而不是四舍五入的值。添加 2 ** -33 将把它舍入为 0x6a09e668。 - Yann Vernier

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