繁体   English   中英

双精度浮点数

[英]double precision floating point

我正在尝试读取二进制八字节浮点数并将它们转换为十进制。 我能够毫无问题地读取和转换英文单词无符号 8 位 ASCII。 如果双精度的字节顺序与 1 字节字符的字节顺序相同,我应该能够复制我在其自己的专用软件中查找的头文件的值。 以下是其中一个标头类实际上在其标头中包含的内容,这是从为此目的的专用软件中获得的:“第 3 类

  utdate:      2022.051500

      ut:         7.089062

     lst:        15.180985

 norchan:         1.000000

 noswvar:         1.000000

 nophase:         1.000000

 cycllen:         1.000000

 samprat:        30.000000

cl11type:         PROTO12M

"

以下是我使用 python 脚本提取字节的这部分标题的位字符串:“ Class 3 Header Observing Parameters

01000000 10011111 10011000 00110100 10111100 01101010 01111110 11111010

01000000 00011011 11111100 10111000 00001000 10111011 11101011 00010001

01000000 00101110 00101101 01001011 01010010 01111100 11001000 01000000

00111111 11110000 00000000 00000000 00000000 00000000 00000000 00000000

00111111 11110000 00000000 00000000 00000000 00000000 00000000 00000000

00111111 11110000 00000000 00000000 00000000 00000000 00000000 00000000

00111111 11110000 00000000 00000000 00000000 00000000 00000000 00000000

01000000 00111110 00000000 00000000 00000000 00000000 00000000 00000000

01001101 00110010 00110001 01001111 01010100 01001111 01010010 01010000 "

我能够重现数学,我认为,它进入了“1.000000”的领域。 数学是:+1 * 2^(1023-1023) * (1 + .0) = +1 * 2^0 * 1.0 = 1 * 1.0 = 1.000000

我无法重现我认为应该进入 30.000000 字段的数学:+1 * 2^(1027-1023) * (1 + .1970324836974592) = +1 * 2^4 * 1.1970324836974592 = 16 * 1.1970324836974592 = 19.152519739159347。

我试图在 10-10000 范围内的许多值上重现双精度计算,而我的结果总是大约是该值的三分之二。

有人可以使用这些位串演示正确的计算,或者确认位串必须不正确吗? (我无法理解它们是如何不正确的,因为使用这种字节提取,我在前面的标头类中匹配了 9 个唯一的 8 或 16 个字符的 ASCII 字符串......

(这是我尝试的第一个,即 2022 年:

2^(1033-1023) * (1 + .4389476917477114) = 1024 * 1.4389476917477114 = 1473.482436349656474

在这里,1473 相当于 2022 年的 3/4……)

谢谢

我不确定您为什么将它们转换为二进制,但您所拥有的只是 8 字节双精度浮点数。 您可以按原样转换它们。

bits = """\
01000000 10011111 10011000 00110100 10111100 01101010 01111110 11111010 
01000000 00011011 11111100 10111000 00001000 10111011 11101011 00010001
01000000 00101110 00101101 01001011 01010010 01111100 11001000 01000000
00111111 11110000 00000000 00000000 00000000 00000000 00000000 00000000
00111111 11110000 00000000 00000000 00000000 00000000 00000000 00000000
00111111 11110000 00000000 00000000 00000000 00000000 00000000 00000000
00111111 11110000 00000000 00000000 00000000 00000000 00000000 00000000
01000000 00111110 00000000 00000000 00000000 00000000 00000000 00000000
01001101 00110010 00110001 01001111 01010100 01001111 01010010 01010000"""

import struct

for line in bits.splitlines():
    by = bytes(reversed([int(k,2) for k in line.split()]))
    print(by)
    z = struct.unpack('d',by)[0]
    print(z)

输出:

b'\xfa~j\xbc4\x98\x9f@'
2022.0515
b'\x11\xeb\xbb\x08\xb8\xfc\x1b@'
6.996795784444445
b'@\xc8|RK-.@'
15.088465287906843
b'\x00\x00\x00\x00\x00\x00\xf0?'
1.0
b'\x00\x00\x00\x00\x00\x00\xf0?'
1.0
b'\x00\x00\x00\x00\x00\x00\xf0?'
1.0
b'\x00\x00\x00\x00\x00\x00\xf0?'
1.0
b'\x00\x00\x00\x00\x00\x00>@'
30.0
b'PROTO12M'
7.484008430422714e+63

以下是您解开这些数字的方法。 让我们看一下 30,即

403E000000000000
0100 0000 0011 1110 0000....

这里有三个字段:符号、指数、尾数:

0  100 0000 0011  1110 0000...
-- -------------  ------------
S  exponent       mantissa

符号位为正。 指数为 0x403,即指数为2**4 在“小数点”另一侧的尾数左端有一个假定的“一位”,所以我们得到的分数是 1.111。 如果我们将它乘以2**4 ,我们得到 11110,即 30。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM