将具有 IEEE-754 双精度数的十六进制表示形式的字符串转换为 JavaScript 数值变量
假设我有一个十六进制数“4072508200000000”,并且我希望将其表示的 IEEE-754 双精度格式的浮点数 (293.03173828125000) 放入 JavaScript 变量中。
我可以想到一种使用一些屏蔽和调用 pow() 的方法,但是有没有更简单的解决方案?
需要一个客户端解决方案。
这可能会有所帮助。该网站可让您输入 IEEE-754 的十六进制编码并获得尾数和指数的分析。
http://babbage.cs.qc.edu/IEEE-754/64bit.html
因为人们总是倾向于问“为什么?”,原因如下:我正在尝试填写 Google Procol Buffers (protobuf) 的现有但不完整的实现。
Suppose I have a hex number "4072508200000000" and I want the floating point number that it represents (293.03173828125000) in IEEE-754 double format to be put into a JavaScript variable.
I can think of a way that uses some masking and a call to pow(), but is there a simpler solution?
A client-side solution is needed.
This may help. It's a website that lets you enter a hex encoding of an IEEE-754 and get an analysis of mantissa and exponent.
http://babbage.cs.qc.edu/IEEE-754/64bit.html
Because people always tend to ask "why?," here's why: I'm trying to fill out an existing but incomplete implementation of Google's Procol Buffers (protobuf).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我不知道有什么好的办法。这当然可以通过困难的方式完成,这是一个完全在 JavaScript 中的单精度示例:
生产实现应该考虑大多数字段都具有魔术值,通常通过为最大或最小的值指定特殊解释来实现。因此,检测 NaN 和无穷大。上面的例子应该是检查负数。 (a & 0x80000000)
更新:好的,我也有双打。您不能直接扩展上述技术,因为内部 JS 表示形式是 double,因此根据其定义,它最多只能处理长度为 52 的位串,并且根本无法移位超过 32。
好的,要执行 double 操作,您首先将低 8 位数字或 32 位截断为字符串;使用单独的对象处理它们。然后:
我保留了上面的例子,因为它来自OP。更困难的情况是低 32 位有值。以下是 0x40725082deadbeef(全精度双精度)的转换:
您可以分解出一些明显的子表达式,但我这样保留了它,以便您可以了解它与格式的关系。
I don't know of a good way. It certainly can be done the hard way, here is a single-precision example totally within JavaScript:
A production implementation should consider that most of the fields have magic values, typically implemented by specifying a special interpretation for what would have been the largest or smallest. So, detect
NaN
s and infinities. The above example should be checking for negatives. (a & 0x80000000)Update: Ok, I've got it for double's, too. You can't directly extend the above technique because the internal JS representation is a double, and so by its definition it can handle at best a bit string of length 52, and it can't shift by more than 32 at all.
Ok, to do double you first chop off as a string the low 8 digits or 32 bits; process them with a separate object. Then:
I kept the above example because it's from the OP. A harder case is when the low 32-bits have a value. Here is the conversion of 0x40725082deadbeef, a full-precision double:
There are some obvious subexpressions you can factor out but I've left it this way so you can see how it relates to the format.
对于像我一样通过 Google 找到此页面的人来说,这是 DigitalRoss 解决方案的快速补充。
除了我希望输入的 +/- Infinity 和 NaN 的边缘情况之外,您还需要考虑结果的符号:
然后您可以在最终的乘法中包含
s
以获得正确的结果。我认为对于小端解决方案,您还需要反转
a
和b
中的位并交换它们。A quick addition to DigitalRoss' solution, for those finding this page via Google as I did.
Apart from the edge cases for +/- Infinity and NaN, which I'd love input on, you also need to take into account the sign of the result:
You can then include
s
in the final multiplication to get the correct result.I think for a little-endian solution you'll also need to reverse the bits in
a
andb
and swap them.新的类型化数组机制允许您这样做(并且可能是实现协议缓冲区的理想机制):
这假设代码正在运行小端机器。
(例如:Windows或Android,而MacOS / iOS始终以大端运行)。
了解更多:
关于什么是“类型化”数组,请参阅:类型化数组
关于 Float64 详细信息,请参阅:Float64 数组
The new Typed Arrays mechanism allows you to do this (and is probably an ideal mechanism for implementing protocol buffers):
This assumes the code is running a little-endian machine.
(eg: Windows or Android, whereas MacOS / iOS are always running in big-endian).
Read more:
About what is a "typed" Array, see: Typed Array
About Float64 specifics, see: Float64 Array