n == n + 1
ときどきの雑記帖経由、2007-11-25 - プログラミング日記
Pythonクイズ。以下を満たすnの値は何でしょうか?
>>> n = ???
>>> n == n + 1
True
30秒ほど考えて、たぶん浮動小数点だよなあと思って、
>>> 1e20 == 1e20 + 1 True >>> 1e15 == 1e15 + 1 False >>> 1e16 == 1e16 + 1 True >>>
やっぱり。せっかくだから別の言語でもやってみる。
Cで
#include <stdio.h> #ifndef N #define N 1e20 #endif int main(int argc, char *argv[]) { #ifdef USE_DOUBLE double n = N; #else float n = N; #endif printf("n = %f\n", n); printf("n == n + 1 ? %c\n", "FT"[n == n + 1]); return 0; }
$ gcc -Wall main.c $ ./a.out n = 100000002004087734272.000000 n == n + 1 ? T $ gcc -Wall -DUSE_DOUBLE main.c $ ./a.out n = 100000000000000000000.000000 n == n + 1 ? T $ gcc -Wall -DN=1e19 main.c $ ./a.out n = 9999999980506447872.000000 n == n + 1 ? F $ gcc -Wall -DN=1e19 -DUSE_DOUBLE main.c $ ./a.out n = 10000000000000000000.000000 n == n + 1 ? F
Cだと1e19と1e20の間に限界があるようだ。floatでもdoubleでも同じ結果なのは面白い。(もしかしたら何かミスってるかも)
Perlで
$ perl -e 'printf "%s\n", [qw(False True)]->[1e15 == 1e15 + 1]' False $ perl -e 'printf "%s\n", [qw(False True)]->[1e16 == 1e16 + 1]' True
Javaで
public class Main { public static void main(String[] args) { double n = args.length > 0 ? Double.parseDouble(args[0]) : 1e16; System.out.println(n == n + 1); } }
$ javac Main.java $ java Main 1e15 false $ java Main 1e16 true
Javaも同じだ。
Javascriptで
もう結果は見えてる気もするけどやってみると、
$ telnet localhost 4242 repl> 1e15 == 1e15 + 1 false repl> 1e16 == 1e16 + 1 true
やっぱりJavascriptも同じ。
ちなみに、Javascriptをインタラクティブに評価するためにMozReplを使ってます。