おきらく 豆知識のコーナー

JavaがCOBOLに負けるはずがない!


何が負けるかって?  
今の仕事で取り扱っているものに現行のCOBOLシステムとの連動がある。
「Java言語はCOBOLに比べ計算精度が低く、業務ロジック上問題がある」などとのたまう。

( ゚Д゚)ハァ?

さすがは元コボラー。言うことが違いますね。(藁



javaにおける各ビルトインオブジェクトの有効範囲は以下の通り
名前
バイト数
最大値
最小値
byte
1
127
-128
short
2
32767
-32768
char
2
65535
0
int
4
2147483647
-2147483648
long
8
9223372036854775807
-9223372036854775808
float
4
3.4×10^38
1.4×10^(-45)
double
8
1.8×10^308
4.9×10^(-324)

確かに、浮動小数点外の範囲(整数値)では平均的なCOBOLの有効桁数(20桁程度)に負ける。
浮動小数点では、扱える数は大きいが有効数字が少ないので、正確に演算できない。やはりJavaの負けか?


ちょっと待てよ!
よく使う変数の有効桁数は少ないほうが速いに決まってるじゃねえか!言語規定で正しく定められているだけ
優秀だろう?C言語だと、CPU依存だぜ?intが2byteにもなりゃ、4byteにもなる。一般にそのCPUのバス幅が
intに割り当てられるわけだし。

それに、javaにはそういう長整数を扱うためのクラスがある。java.math.BigIntegerとか、java.math.BigDecimalである。
それぞれが扱える最大の数は、以下の通り。
名前
バイト数
有効最大桁数
BigInteger
可変
2147483647
BigDecimal
可変
2147483647

うらぁ!!スーパーぶっちぎりで、Javaの勝ちだ!! 21億桁!!!!!
日本の国家予算でさえ、14桁だ。何年までいけるんだ?国家予算を60兆として、求める数をχとして
とりうる最大の数は、9で埋められた最大桁数だから、10^(2^31 + 1) - 1
χ = 10^(2^31 + 1)-1 / 6.0 ×10^14

両辺の常用対数をとり、10^(2^31+1) より1は十分小さいので、無視して

logχ= log10^(2^31+1) - log (6.0 ×10^14)
= 2147483649- 14.779
= 2147483634.221
2147483634
よって、
 χ = 10^2147483634

10^2147483634乗年 地球の寿命が100億年として10^2147483623回は地球が生まれ変わっても大丈夫だ!
そんなことより対数の計算が合っているかどうかが心配だ!

で、実際にそんな桁数が本当に使えるのか?上の表の最大値等はBigIntegerなどのソースを解析した結果であり
明記されているわけではない。
BigIntegerは 内部で、intの配列を持ち、各桁を記憶している。
配列の最大容量は、Integer.MAX_VALUEと規定されているから
Integet.MAX_VALUE = 2^31 - 1 = 2147483647なわけだ。


こういうときは、実験してみるに限る。ウダウダ悩むより手を動かすほうがいい。
で、以下のようなテストコードで試してみた
 
import java.lang.*;
import java.math.*;
import java.io.*;

public class math{
public static void main(String s[]) throws Exception
{
PrintWriter p = new PrintWriter(System.out);
p.println(Integer.MAX_VALUE + "");
for(int i = 1;i<Integer.MAX_VALUE ; i = i<<1){
BigDecimal b = new BigDecimal("+1e"+ i );
p.println("i:" + i );
p.println((b.toString().length()) + "桁");
p.flush();
}
Thread.sleep(1000);

}
}


ループカウンタをインクリメントしていると、21億回も廻ってしまうので
1ビットづつシフトさせてみた。
で、結果はどうかというと、
Decimal.png
<Pentium3 1GHz メモリ 1GB のマシンでテスト>

1048578桁の演算に時間がかかりすぎている。当たり前なんだろうけど。
CPUを3時間22分にわたり100%使用しても、オブジェクトが作れない。
(実際には4時間17分に作成できた)
65537桁あたりまでは一瞬で応答があったので5万桁ぐらいまでは実用に耐えるだろう。
しかし、5万桁と言われてもピンとこないな…。


ブラウザのBACKでお戻り下さい