この日記書くとき以外に曜日感覚がないなあ。
いつの間にか VJ++ から WJView.exe が起動しなくなっていることに気付いた。いつも JDK で作業しているから、どのタイミングで動かなくなったのか見当がつかない。ちょっと困ったな。
ソフトFAXの調子が悪いので、ホームFAXをヨドバシで買ってきた。税込\23kのBrother製熱転写普通紙FAX。安い。自宅用に買うかなあ。
今日のお勉強。Java で 10進数の桁を演算する方法がよくわからない。というか Math.log() にはずいぶん無体な誤差が出るんだけど、普通のヒトはどうしているんだろう?
% cat LogTest.java public class LogTest { public static void main( String[] args ) throws Exception { System.out.println(Math.log(Integer.parseInt(args[0])) / Math.log(10)); } } % java LogTest 100 2.0 % java Test 1000 2.9999999999999996 % java Test 10000 4.0
..てな感じで log10 1000 が 3.0 を返してくれない。もちろん log 自体に計算誤差はあるのは判ってるし、ShuJIT でも同じ結果(log をアセンブラで展開している、らしい)ってことは JLS にある fdlibm とかいう数値演算ライブラリの実装段階からの誤差ってことなんだろう。納得いかないのは、Windows や Linux のC言語用ライブラリにある log 関数なら、 3.0 が返ってくる点だ。そういう実装があるなら、そっちを採用してくれればいいのにねえ。
まあ、それはしかたないとして。じゃあどうすれば意図した通りに動作させられるか?って話。自分でlogをインプリメントするのが正解ってのは、とりあえずどこか遠くの棚に上げておくとして、[JavaHouse-Brewers:6330] Re: 計算精度について で ShuJIT 作者の首藤氏が..
> 浮動小数点数どうしの比較は、倍精度だったら例えば > (a < b) のために ((a * 1.0000000000003) < b) > ^^^^^^^^^^^^^^^ 妥当性にあまり自信なし > などとするべきだと思います。
..と提案されているけど、この話は投げっぱなしになっちゃったようで、普通どうしているのか、は不明なまま。試しに昔自分が書いたインプリメントを探してみると..
/** * double型のvalue0 % value1がだいたい0かどうかを判定する。 * @param value0 割られる数。 * @param value1 割る数。 */ public static boolean isMultiple(double value0, double value1) { return Math.abs((int)(value0 / value1) * value1 - value0) < 1E-8; }
..あーなるほどねえ。直球だ。(←考えてみると間抜けな話だ。でも昔の自分は赤の他人なんで。)
夕方昨日の見積もりを再考。夜中までかかる。
コメントする