「.NETのfloat.Epsilon定数は計算機イプシロンではない」を編集中

ナビゲーションに移動 検索に移動

警告: ログインしていません。編集を行うと、あなたの IP アドレスが公開されます。ログインまたはアカウントを作成すれば、あなたの編集はその利用者名とともに表示されるほか、その他の利点もあります。

この編集を取り消せます。 下記の差分を確認して、本当に取り消していいか検証してください。よろしければ変更を保存して取り消しを完了してください。

最新版 編集中の文章
12行目: 12行目:
  
 
== 解決 ==
 
== 解決 ==
「奥村晴彦『C言語による最新アルゴリズム事典』技術評論社,1991年,ISBN4-87408-414-1,2400円」という書籍に[[計算機イプシロン]]を動的に求める[[アルゴリズム]]が詳細に解説されており、また[[ソースコード]]は公式サイトにおいても配布されている。この本は非常に面白いので迷わず買え。個人的にはこの手の技術書を買う際に目次と技術評論社という名前だけで信頼して買うようになった一冊である。
+
<source lang="csharp">
 
 
https://oku.edu.mie-u.ac.jp/~okumura/algo/
 
 
 
速攻で[[C言語]]からC#に[[移植]]した(ほぼ[[コピペ]]しただけ)。
 
 
 
<syntaxhighlight lang="csharp">
 
 
     using System;
 
     using System;
  
    class MainClass
 
    {
 
        static float Foo(float x) { return x; }
 
 
        static float MachineEpsilon()
 
        {
 
            int b, p;
 
            float x, y, eps;
 
 
            x = y = 2;
 
            while (Foo(x + 1) - x == 1) x *= 2;
 
            while (Foo(x + y) == x) y *= 2;
 
            b = (int)(Foo(x + y) - x);
 
            p = 1; x = b;
 
            while (Foo(x + 1) - x == 1) { p++; x *= b; }
 
            eps = 1;
 
            while (Foo(1 + eps / 2) > 1) eps /= 2;
 
            eps = Foo(1 + eps) - 1;
 
 
            return eps;
 
        }
 
 
        public static void Main(string[] args)
 
        {
 
            Console.WriteLine("epsilon = {0}", MachineEpsilon());
 
        }
 
    }
 
</syntaxhighlight>
 
 
計算機イプシロンの定番の[[アルゴリズム]]といえば、変数をひたすら2で割り続け、ゼロになった瞬間のひとつ前を捉えるというもの。「1以上」という条件はコンピューターの指数と仮数の組み合わせで表現される浮動小数点数では、1未満だと指数部だけを使ってどこまでも小さくなってしまうためであり、なんとしても仮数部を使おうということらしい。
 
<syntaxhighlight lang="csharp">
 
 
         static double MachineEpsilon()
 
         static double MachineEpsilon()
 
         {
 
         {
             double eps = 1.0d;
+
             double eps = 1.0;
  
 
             do
 
             do
 
             {
 
             {
                 eps /= 2.0d;
+
                 eps /= 2.0;
 
             }
 
             }
 
             while ((double)(1.0 + eps) != 1.0);
 
             while ((double)(1.0 + eps) != 1.0);
 
 
             return eps;
 
             return eps;
 
         }
 
         }
</syntaxhighlight>
+
</source>
 
 
== 備考 ==
 
実行環境(主に[[CPU]]の違い)により計算結果が変化する点に注意すること。
 
[[アーキテクチャ]]がいっぱいある[[Xamarin]]系は要注意。
 
  
 
[[category: .NET]]
 
[[category: .NET]]
 
[[category: Mono]]
 
[[category: Mono]]
 
[[category: Xamarin]]
 
[[category: Xamarin]]

MonoBookへの投稿はすべて、他の投稿者によって編集、変更、除去される場合があります。 自分が書いたものが他の人に容赦なく編集されるのを望まない場合は、ここに投稿しないでください。
また、投稿するのは、自分で書いたものか、パブリック ドメインまたはそれに類するフリーな資料からの複製であることを約束してください(詳細はMonoBook:著作権を参照)。 著作権保護されている作品は、許諾なしに投稿しないでください!

このページを編集するには、下記の確認用の質問に回答してください (詳細):

取り消し 編集の仕方 (新しいウィンドウで開きます)