3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

先日の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

3
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?