é¡åã®éããªãã§ãããååã®è¨äºãPHP以外全員不正解ãã«å¯¾ãã¦ããã¦ãï¼ããé æ´ããã®ã§ã¾ã¨ãã¦ã¿ã¾ãã
Cã®ãã®åä½ããå¯ä¸ç¡äºçµ¶å¯¾ã®ãã®ã§ããã¨ããæ ¹æ ã¯ã©ãã«ããã®ã§ãããã? strtod ã«ããã°ã
If the subject sequence has the decimal form and at most DECIMAL_DIG (defined in
) significant digits, the result should be correctly rounded. If the subject sequence D has the decimal form and more than DECIMAL_DIG significant digits, consider the two bounding, adjacent decimal strings L and U, both having DECIMAL_DIG significant digits, such that the values of L, D, and U satisfy L <= D <= U. The result should be one of the (equal or adjacent) values that would be obtained by correctly rounding L and U according to the current rounding direction, with the extra stipulation that the error with respect to D should have a correct sign for the current rounding direction. DEICMAL_DIGã¨ããã®ã¯C99ã§è¿½å ãããå®æ°ã§ãglibcã使ã£ãã·ã¹ãã ã ã¨å¤å17ã§ãã Sparcä¸ã®ã·ã¹ãã ã§ã¯20ã¨ãããã®ãããã¿ããã§ããã¾ãããã¯ãã¦ããããã®æ°ãè¶ããæ¡æ°ãæã¤æ°å¤ã«é¢ãã¦ã¯ã should be one of the (equal or adjacent) values that would be obtained by correctly rounding L and U according to the current rounding direction ã¨ã¯ããã¾ãããæè¿å¤ä¸¸ãã«ããªããã°ãªããªãã¨ã¯ã©ãã«ãæ¸ãã¦ãã¾ãããã§ãããå ã®ä¾ã«ããããã« DECIMAL_DIGãè¶ããæ¡æ°ãæåååããã¨ãã«æè¿å¤ä¸¸ãã§ãªãããã¨ãã£ã¦å³ãã°ã§ããã¨ããå¤æãä¸ããã¨ã¯ã§ããªãã¨æãã¾ãã
ときどきの雑記帖リターンズ - では異議を唱えてみよう
ãªãã»ã©ããããªä»æ§ãããã¨ã¯ç¥ãã¾ããã§ããããããã¨ããããã¾ããã§ã¯ãåè¨èªããã®ä»æ§ãæºããã¦ããå¯è½æ§ãããã®ãã©ããã調ã¹ã¦ã¿ã¾ãããã
Rubyã®missing/strtod.cãèªãã ã¨ãããæµ®åå°æ°ç¹æ°ã®10é²è¡¨è¨ã®19æ¡ç®ããå ã¯0ã¨ã¿ãªãã¦18æ¡ã¾ã§ãå¦çãã¦ããã¨ç解ãã¾ãããã¾ããPerlã¯18æ¡ç®ã§å¶æ°ä¸¸ã*1ãã¦10é²17æ¡ã¨ãã¦ããããã§ã*2ã
ãã¦ããããã¯C99ã®DECIMAL_DIGãããã¤ã®å ´åã«ç¸å½ããã®ã§ããããããIf the subject sequence has the decimal form and at most DECIMAL_DIG (defined in
$ perl -e 'printf("%21.0f\n",36893488147419108000);' 36893488147419103232
10é²ã§æå¹æ°å17æ¡ã®æ°ã64bitæµ®åå°æ°ç¹æ°ã«ä¸¸ãã¦ã¿ã¾ããããã®æ°ãto nearestã§ä¸¸ããã¨ããã36893488147419111424ã®æ¹ãè¿ãã§ããããæ£ãã丸ãããã¦ãã¾ãããã¤ã¾ããDECIMAL_DIGã§æç®ããã¨16以ä¸ã¨ãããã¨ã«ãªãã¾ãã
ã§ã¯Rubyã¯ã©ãã§ãããããååè¨äºã®ç°å¢ã¨ã¯ç°ãªãã®ã§ãããåé¡ã®åºãç°å¢ãæ¢ãã¦ã¿ã¾ããã
$ uname -mrs FreeBSD 6.1-RELEASE-p10 i386 $ ruby -v ruby 1.8.5 (2006-08-25) [i386-freebsd6] $ ruby -e 'printf("%21.0f\n",36893488147419108000.0);' 36893488147419103232
ãã®ç°å¢ã§ã¯Perlã¨åãçµæã«ãªãã¾ããã®ã§ãDECIMAL_DIGã§è¨ãã°ãã¯ã16以ä¸ã ã¨ãããã¨ããããã¾ãã
調ã¹å§ããæç¹ããããã¨äºæ³å¤ãªã®ã§ãããããã¯ãã¯ãå®è£ ãã¾ããã¨è¨ãããã§ãããã°ã¨è¨ãã¨ã ãã¨ãããæ¹ãããããããã¾ãããããã£ã¨ä¸æãå®è£ ãããã®ã¯ç¢ºãã§ãããã
ãã®ãããªçµæã¨ãªãåå ã¯PerlãRubyãå ±éã§ã巨大ãªæµ®åå°æ°ç¹æ°ãªãã©ã«ãå¦çããã®ã«ï¼å é¨çãªæå¹æ¡æ°åã®æ´æ°ï¼Ã10nã¨ãã¦è¨ç®ãã¦ããããã§ãããå é¨çãªæå¹æ¡æ°åã®æ´æ°ããè¨ç®éä¸ã§ä¸åº¦IEEE64bitæµ®åå°æ°ç¹æ°ã¨ãã¦ä¿åããã¦ãã¾ãã¨ä»®æ°é¨ã®53bitã§ã¯10é²17æ¡ã18æ¡ã¯ã«ãã¼ã§ããããã®æç¹ã§ä¸¸ãããã¦ãã¾ãã®ã§ãã丸ããããçµæãå¾ãã10nåãã¦ããæ¬æ¥ã®æ°ã丸ããçµæã¨ã¯ç°ãªã£ã¦ãã¾ãã¾ãã
æå¾ã«å¿µã®ããæ¸ãã¦ããã¨ãããã£ãã¼ï¼çããPHPãåã£ããï¼ãã£ããã¼ï¼ã§ããªããèããâ¦ãã¨ããç¨åº¦ã®ãã¿ã§ãã®ã§ãä»ã®è¨èªã®æ¹ã ã¯ãã¾ãæ·±å»ã«åãåããªãã§æ¬²ããã§ã*3ãPHPã®ãã¡ãªã¨ãããªãã¦è ãã»ã©ããããã§ãããããã¾ã«ã¯åããã¦ããã¦ãã ããã
追è¨ï¼LLéã§æããã¾ããããããªãèªåã®æ¥è¨ã®URLãåºã¦ãã¦ãããã¾ãããï¼ï¼ã¾ããããã
追è¨2ï¼æ¬ä»¶ãruby1.9ã«åãè¾¼ã¾ããäºå®ã ããã§ã(via http://d.hatena.ne.jp/masugata/20070822#p2)
èªåã¨ãã¦ã¯èª°ãèå³ãæããªããããç´°ããå 容ã ã¨æã£ã¦ããã®ã§ãã¡ããã¨ä¿®æ£ãã¡ããRubyã³ãã¥ããã£ã¯åãã¨æãã¾ããPHPã®äººãçãã£ã¨Cã½ã¼ã¹ã³ã¼ããèªããããã£ã¦å¼ã³ããã¦ããããã§ããã
*1:æªããã§ããã½ã¼ã¹ã³ã¼ãã«ããæ¸ãã¦ããã¾ã
*2:å°ãªãã¨ãç§ã®ç°å¢ã§ã¯ããã§ã
*3:ãã®æã®è©±ã大好ããªæ¹ãªãæ¢ãã¾ãããã©