JavaScriptã®ãããæ¼ç®ã®ä»çµã¿ãç解ãã
ã¯ããã«
JavaScriptã®æ°å¤è¡¨ç¾ã¯IEEE754ã®64ãããã®å精度åæµ®åå°æ°ã§ããããããæ¼ç®ã¯ã©ã®ããã«å®ç¾©ããã¦ããã®ã§ãããããä»åã¯ãã®ãããæ¼ç®ã«ã¤ãã¦è§£èª¬ãã¾ãããã®ä»æ§ã¯10年以ä¸åããå¤ãããªãã®ã§ãããæ¹ãã¦ãã®é¨åãæ¸ç±ãªã©ã§ã©ã®ããã«è§£èª¬ãã¦ããããè¦ãã¨ãand, or ãªã©ã®ãããæ¼ç®ãæç§æ¸çã«æ¸ããã¦ããã ãã§ãä»»æã®æ°å¤ã«å¯¾ãã¦ã©ãå®ç¾©ããããã«ã¤ãã¦ã¯ã»ã¨ãã©èª¬æããã¦ãã¾ããã
JavaScript以å¤ã®è¨èªã§ã¯ï¼
JavaScriptã«ã¤ãã¦èª¬æããåã«ãä»ã®è¨èªã§ã¯ã©ããªã£ã¦ããã§ãããããããã§ã¯ãã¡ãã£ã¨æãæãã¦å®éã«å®è¡ããçµæã®ã¿ã示ãã¾ãããã¼ã¸ã§ã³ã«ãã£ã¦ã¯çµæãéãããç¥ãã¾ããã
ã¾ãã¯ãä¸çªåç´ãª 0 ã¨ã® orã調ã¹ã¦ã¿ã¾ãããã¤ã¾ã x | 0 ã®çµæã§ãã
x | C (gcc) | Java | Ruby | Perl |
-123 | -123 | -123 | -123 | 18446744073709551493 |
9876543210 | 1286608618 | 9876543210 | 9876543210 | 9876543210 |
123.45 | Compile Error | Compile Error | NoMethodError | 123 |
9.87e+12 | Compile Error | Compile Error | NoMethodError | 9870000000000 |
9.87e+200 | Compile Error | Compile Error | NoMethodError | 18446744073709551615 |
Cã¨Javaã§ã¯æµ®åå°æ°ã«å¯¾ãã¦ã®ãããæ¼ç®ã¯ã³ã³ãã¤ã«ã¨ã©ã¼ã«ãªãã¾ããä¸æ¹ãRubyã¯ã¡ã½ãã '|' ãå®ç¾©ããã¦ããªãã¨ããå®è¡æã¨ã©ã¼ã«ãªãã¾ããã
Perlã®çµæã¯ç¬ç¹ã§ãã-123 | 0ã®çµæã®18446744073709551493㯠2^64-123ã¨ä¸è´ãã¾ãã9.87e+200 | 0 㯠2^64-1ã§ãã
ã¡ãªã¿ã«ãEmacsLispã§ãæµ®åå°æ°ä¸ã®ãããæ¼ç®(logand, logior, logxorãªã©)ã¯å®è¡æã¨ã©ã¼ã«ãªãã¾ãã
次ã«ãã·ããæ¼ç®ãè¦ã¦ã¿ã¾ãã15 << n ã®çµæã§ãã
n | C (gcc) | Java | Ruby | Perl |
27 | 2013265920 | 2013265920 | 2013265920 | 2013265920 |
40 | 16492674416640 | 16492674416640 | 16492674416640 | 16492674416640 |
70 | 0 (warn) | 960 | 17708874310761169551360 | 960 |
-1 | -2147483648 (warn) | -2147483648 | 7 | 9223372036854775808 |
-2 | -1073741824 (warn) | -1073741824 | 3 | 13835058055282163712 |
-123 | 480 (warn) | 480 | 0 | 480 |
2.5 | Compile Error | Compile Error | 60 | 60 |
1.23e+100 | Compile Error | Compile Error | RangeError | 9223372036854775808 |
Cè¨èªã¨Javaã§ã¯æ°å¤15ã¯64ãããæ´æ°ã¨ãã¦ã³ã³ãã¤ã«ãã¦ãã¾ãã
ãã®ããã«ãå¤ãã®è¨èªã§ã¯ãããæ¼ç®ã¯æ´æ°ã«å¯¾ãã¦å®ç¾©ããã¾ããã32ããã以ä¸ã®æ°ãªã©ã«ã¤ãã¦ã¯ãè¨èªãã¨ã«åä½ãç°ãªãããã§ãã
JavaScriptã®ãããæ¼ç®
ã§ã¯ãJavaScriptã®å ´åã¯ã©ããªããã¿ã¦ã¿ã¾ãããã以ä¸ã®ããã«ãªãã¾ãã
x | 0
x | JavaSript |
-123 | -123 |
9876543210 | 1286608618 |
123.45 | 123 |
9.87e+12 | 165153792 |
9.87e+200 | 0 |
15 << n
n | JavaScript |
27 | 2013265920 |
40 | 3840 |
70 | 960 |
-1 | -2147483648 |
-2 | -1073741824 |
-123 | 480 |
2.5 | 60 |
1.23e+100 | 15 |
JavaScriptã§ã¯æ°å¤ã¯IEEE754ã®64ãããã®å精度åæµ®åå°æ°ã§è¡¨ç¾ããã¾ãããããæ¼ç®ãæå³ã®ãããã®ã«ããã«ã¯ãä»ã®è¨èªã§ãè¦ãããã«ãæ´æ°å¤ã«å¤æããå¿ è¦ãããã¾ããæ´æ°å¤ã¨ãã¦64ãããã®æ´æ°åã¯IEEE754ã¨ã³ã³ããªã¯ããã¾ãã®ã§ä½¿ãã¾ãããçµå±ãJavaScriptã§ã¯32ãããã®æ´æ°ã«å¤æãã¦ãããæ¼ç®ãè¡ãã¾ããããã¯ãååæ¼ç®ã§ãªãã©ã³ããæ°å¤ã§ãªãå ´åã«ã¯ãæ°å¤ã«æé»ã«åå¤æãã¾ããããããæ¼ç®ãããã¨åæ§ã§ãããæ¼ç®ãæå¹ã«ãªãããã«32ãããæ´æ°åã«æé»ã«åå¤æãè¡ãããã¨ãããã¨ã§ãã
ä»»æã®æ°å¤ã32ãããæ´æ°ã«å¤æããè¦åã¯ECMA262è¦æ ¼æ¸ã«è¨è¿°ããã¦ãã¾ããJavaScriptã§ã»ã¼ãã®ã¾ã¾è¨è¿°ããã¨ä»¥ä¸ã®ããã«ãªãã¾ãã
function ToInt32(x) { x = Number(x); if (!isFinite(x) || x === 0) { return 0; } var p32 = 4294967296; // = 2^32 var p31 = 2147483648; // = 2^31 var neg; if (x < 0) { neg = true; x = -x; } var x = Math.floor(x) % p32; if (x > p31) { x -= p32; } return neg ? -x : x; }
ã¡ãã£ã¨è¤éã«è¦ãã¾ãããã¼ãã«è¿ãæ´æ°ã«ä¸¸ãã¦ãããã 2^32 ã§å²ã£ãä½ãã§ãã32ãããç®ã符å·ã¨ãã¦æ±ãç¹ã注æããã ãã§ããã¾ããx === 0㧠0ãè¿ãã¦ããã®ã¯ã¼ãã«ã符å·ããã -0 ã®ã¨ã㯠+0 ã«ããã¨ããæå³ã§ãã
符å·ãªãã®32ãããæ´æ°ã«å¤æããã®ãåæ§ã«ä»¥ä¸ã®ããã«ãªãã¾ãã
function ToUint32(x) { x = Number(x); if (!isFinite(x) || x === 0) { return 0; } var p32 = 4294967296; // = 2^32 var neg; if (x < 0) { neg = true; x = -x; } x = Math.floor(x); if (neg) { x = -x; } x = x % p32; return (x < 0) ? p32 + x : x; }
ToInt32ã¨ToUint32ã«ã¯ä»¥ä¸ã®æçå¼ãæç«ãã¾ãã
ToInt32(ToUint32(x)) == ToInt32(x) ToUint32(ToInt32(x)) == ToUint32(x)
&, |, ^, ~ ãããæ¼ç®
ToInt32ã使ã£ã¦JavaScriptã®ãããæ¼ç®ã¯ä»¥ä¸ã®ããã«å®ç¾©ããã¾ãã[&]ã®ããã«ã«ãã³ã§æ¬ã£ãã®ã¯JavaScriptã®&ã§ã¯ãªãããçã®ãã¡ã¿ãªãªãã¬ã¼ã¿ã¨ããåºå¥ãããããã§ãã
x & y ::= ToInt32(ToInt32(x) [&] ToInt32(y)) x | y ::= ToInt32(ToInt32(x) [|] ToInt32(y)) x ^ y ::= ToInt32(ToInt32(x) [^] ToInt32(y)) ~x ::= ToInt32([~]ToInt32(x))
ã¤ã¾ããxã¨yãToInt32ãã¦ãããæ¼ç®ãé©ç¨ãã¦ã符å·ã¤ã32ãããã«ããã¨ãããã¨ã§ãã
ä¾ã§ããã x | 0 ã®å¤ã¯ãToInt32(x)ã®å¤ãã®ãã®ã§ãããã¨ãåãã¾ãã
<<, >>, >>> ã·ããæ¼ç®
ã·ããæ¼ç®ãåæ§ã«ä»¥ä¸ã®ããã«å®ç¾©ããã¾ãããªãã¬ã¼ã¿ã®å³å´ã®å¤ã¯0x1Fã§ãã¹ã¯ããããã¨ã«æ³¨æãã¦ãã ããã
x << y ::= ToInt32(ToInt32(x) [<<] (ToUint32(y) [&] 0x1F)) x >> y ::= ToInt32(ToInt32(x) [>>] (ToUint32(y) [&] 0x1F)) x >>> y ::= ToUint32(ToUint32(x) [>>>] (ToUint32(y) [&] 0x1F))
ããã¤ã確èªãã¦ã¿ã¾ãã
15 << 40 = 15 << (ToUint32(40) & 0x1F) = 15 << (40 & 0x1F) = 15 << 8 = 3840 15 << -1 = 15 << (ToUint32(-1) & 0x1F) = 15 << (4294967295 & 0x1F) = 15 << 31 = -2147483648 15 << -123 = 15 << (ToUint32(-123) & 0x1F) = 15 << (4294967173 & 0x1F) = 15 << 5 = 480
æ°å¤ã®åå¤æãJavaScriptã§è¨è¿°ãã
ECMA262è¦æ ¼æ¸ã«è¨è¿°ããã¦ããToInt32ã¨ToUint32é¢æ°ãJavaScriptã§æ¸ãã¦ã¿ã¾ãããããããæ¼ç®ã使ãã¨ä»¥ä¸ã®ããã«ç°¡æ½ã«è¨è¿°ã§ãã¾ãã
function ToInt32(x) { return x | 0; } function ToUint32(x) { return x >>> 0; }
ã¾ããToUint16ã¨ããé¢æ°ãå®ç¾©ããã¦ãã¾ããããã¯ãString.fromCharCode()é¢æ°ã§UTF16ã®Unicodeããæååãçæããã¨ãã«ä½¿ããã¾ãããããå©ç¨ããã¨ToUint16é¢æ°ã¯æ¬¡ã®ããã«å®è£ ã§ãã¾ããæååãçæããããã³ã¹ãããããé¢æ°ãªã®ã§å®ç¨çã§ã¯ããã¾ãããã
function ToUint16(x) { return String.fromCharCode([x]).charCodeAt(0); }
ã¾ã¨ã
JavaScriptã®æ°å¤ã¯ä»æ§çã«ã¯64ãããå精度ã®æµ®åå°æ°ã§ããããã«å¯¾ãã¦ãããæ¼ç®ã¯32ãããã®æ´æ°ã«å¤æãã¦é©ç¨ããã¾ãã32ããããã大ããæ´æ°ãæµ®åå°æ°ï¼ã¾ãã¯è² ã®æ°ãªã©ï¼ã«å¯¾ãã¦ãããæ¼ç®ãè¡ãã¨ãã¯ãToInt32ãToUint32ãªã©ã®æé»ã®åå¤æãå®è¡ããã¾ãããã®ãã¨ã¯ç¥ããªãã¦ãã»ã¨ãã©åé¡ã¯ãªããã¨ã ã¨æãã¾ãããä»æ§ã§ãã¡ãã¨å®ç¾©ããã¦ããã¨ãããã¨ã¯è¦ãã¦ãããã§ãããã