Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9328

[JavaScript] 16進数表現の罠

$
0
0
先日のPHP版のついでに。 似たような事情ではありますが、こちらはわりと歴史的な現象のようで。 しかし今まで気にしたこともなかった驚愕の事実。 大きい値が浮動小数扱いな件 underflow.js console.log((0xfedcba98765438ff).toString(16)); console.log((0xfedcba9876543cff).toString(16)); fedcba9876543800 fedcba9876544000 符号+仮数部の53bitで下側が消滅します。 さらに、四捨五入というか零捨一入で上側まで破壊される問題もあり。 そもそもintがsigned 32bitな件 msb.js console.log(1<<31); -2147483648 しかし16進数表記はより大きい値でも受け入れるので、ややこしい事態に… なんか壊れてる件 broken.js console.log((0x40000000<<1).toString(16)); // 80000000 になってほしいのに console.log((0x80000000>>1).toString(16)); // c0000000 になってほしいのに console.log((0x80000000|1).toString(16)); // 80000001 になってほしいのに -80000000 -40000000 -7fffffff 論理演算自体は正常 ok.js console.log(0x40000000<<1); // 80000000 → -2147483648 console.log(0x80000000>>1); // c0000000 → -1073741824 console.log(0x80000000|1); // 80000001 → -2147483647 -2147483648 -1073741824 -2147483647 toString(16) が符号外して処理されるようで。 16進表記が符号なしで解釈されるなら、必然的な仕様といえるでしょう。 というわけで… 32bit前提なら、int→16進文字列変換さえ正常化すれば何とか。 dexhex32.js var dechex32=function(src){ // 16bitずつ文字列化作戦 var h=(src>>16)&0xffff; var l=src&0xffff; // 上側が0なときは下側だけ表示 if(!h)return l.toString(16); // 上側があるとき下側は必ず4桁 return h.toString(16)+('000'+l.toString(16)).slice(-4); }; console.log(dechex32(0x40000000<<1)); console.log(dechex32(0x80000000>>1)); console.log(dechex32(0x80000000|1)); 80000000 c0000000 80000001

Viewing all articles
Browse latest Browse all 9328

Trending Articles