2009-10-20 47 views
8

に変換します。16進数が「4072508200000000」で、IEEE-754ダブルフォーマットの浮動小数点数(293.03173828125000) JavaScript変数に入れます。IEEE-754ダブルの16進表現の文字列をJavaScriptの数値変数

私はいくつかのマスキングとpow()の呼び出しを使用する方法を考えることができますが、より簡単な解決法はありますか?

クライアント側の解決策が必要です。

これが役立ちます。これは、IEEE-754の16進符号化を入力し、仮数と指数の分析を得ることを可能にするウェブサイトです。

http://babbage.cs.qc.edu/IEEE-754/64bit.html

人々は常に依頼する傾向があるので、なぜ「なぜ?」ここにあります:私はGoogleのPROCOLバッファ(いるProtobuf)の既存の不完全な実装を記入しようとしています。

+0

個人的には、正規表現を使って16進数の値を別々の部分に切り詰めることから始めます。次に、それらを整数として評価し、最後にそれらを浮動小数点数に戻そうとします。それは、Javascriptランタイムが途中でビットを失うことがないようにする必要があるので、難しいことになるようです。 – Pointy

+0

最大限の移植性を実現するには、IEEE-754の倍音をビッグエンディアンまたはリトルエンディアンのいずれかにすることが重要です。どのコンベンションが16進数入力で使用されているか分かっているならば、pow()を使ったクライアント側の解決策は移植可能でなければなりません。何らかの型打ちアプローチを使用することに決めた場合、最初に倍精度のクライアントプラットフォームのエンディアンをチェックする必要があります。 –

+0

@Jim Lewis:私には、大小のエンディアンを教えてくれる旗があります。 – Nosredna

答えて

10

私は良い方法が分かりません。それは確かにここでは、ハードな方法を行うことができ、完全にはJavaScript内単精度の例です:

js> a = 0x41973333 
1100428083 
js> (a & 0x7fffff | 0x800000) * 1.0/Math.pow(2,23) * Math.pow(2, ((a>>23 & 0xff) - 127)) 
18.899999618530273 

生産の実装では、フィールドのほとんどは一般的に何のための特別な解釈を指定することで実現し、魔法の値を持っていることを考慮すべきです最大であったか最小であったでしょうか。したがって、NaNと無限を検出してください。上記の例では、ネガを確認する必要があります。 (a & 0x80000000)

更新:私は倍のためにもそれを持っています。内部JS表現が二重であるため、上記の手法を直接拡張することはできません。したがって、その定義によって、長さ52のビットストリングを処理することができ、32以上はシフトできません。

[OK]をダブルクリックすると、の下位8桁または32ビットの文字列としてが最初に切り捨てられます。それらを個別のオブジェクトで処理します。次に:

js> a = 0x40725082  
1081233538 
js> (a & 0xfffff | 0x100000) * 1.0/Math.pow(2, 52 - 32) * Math.pow(2, ((a >> 52 - 32 & 0x7ff) - 1023)) 
293.03173828125 
js> 

これはOPのものなので、上記の例はそのままです。より難しいケースは、低32ビットに値がある場合です。ここ0x40725082deadbeefの変換、完全な精度ダブルは以下のとおりです。

js> a = 0x40725082 
1081233538 
js> b = 0xdeadbeef 
3735928559 
js> e = (a >> 52 - 32 & 0x7ff) - 1023 
8 
js> (a & 0xfffff | 0x100000) * 1.0/Math.pow(2,52-32) * Math.pow(2, e) +   
    b * 1.0/Math.pow(2, 52) * Math.pow(2, e) 
293.0319506442019 
js> 

あなたがくくり出すことはできますが、それは形式にどのように関連するか見ることができますので、私はそれをこのように残してきたいくつかの明白な部分式があります。

+0

私の最後の例は0x40725082deadbeefのリンク先サイトに同意します。 – DigitalRoss

+0

非常に良い。ありがとう。 – Nosredna

+0

a = 0のとき、なぜこのコード(第2の例)は '1.1125369292536007e-308'を返しますか? – etuardu

4

DigitalRossのソリューションにすばやく追加しました。私が行ったようにGoogleを介してこのページを検索してくれたユーザーのためのものです。

別に私は上の入力をみたい+/-無限大とNaNのためのエッジケースから、あなたも考慮に結果の符号を取る必要があります。

s = a >> 31 ? -1 : 1 

あなたはその後、sを含むことができ、最終的な乗算で正しい結果を得ることができます。

リトルエンディアンのソリューションについては、abのビットを逆にしてスワップする必要があります。

1

新しいTyped Arraysメカニズムは、あなたがこれを行うことができます(そしておそらくプロトコルバッファを実装するための理想的なメカニズムです):

var buffer = new ArrayBuffer(8); 
var bytes = new Uint8Array(buffer); 
var doubles = new Float64Array(buffer); // not supported in Chrome 

bytes[7] = 0x40; // Load the hex string "40 72 50 82 00 00 00 00" 
bytes[6] = 0x72; 
bytes[5] = 0x50; 
bytes[4] = 0x82; 
bytes[3] = 0x00; 
bytes[2] = 0x00; 
bytes[1] = 0x00; 
bytes[0] = 0x00; 

my_double = doubles[0]; 

document.write(my_double); // 293.03173828125 

これは、リトルエンディアンのマシンを想定しています。

残念ながらChromeにはFloat64Arrayはありませんが、Float32Arrayはあります。上の例は、Firefox 4.0.1で動作します。

関連する問題