差分
編集の要約なし
C#においてfloat型(Single型)の[[絶対値]]をfloat.Epsilon定数と比較している箇所の挙動がどうもおかしい。
== 原因 ==
[[ググって]][[MSDN]]を見るとサラッと絶望的なひとことメモが。
The value of the F:System.Single.Epsilon property is not equivalent to machine epsilon,
要約すると「浮動小数点演算の丸の相対誤差の上限(丸め誤差発生時にズレるであろう最大値)」であり「[[計算機イプシロン]]」ではない。
まじかよ。名前紛らわしすぎだろ。 == 解決 ==「奥村晴彦『C言語による最新アルゴリズム事典』技術評論社,1991年,ISBN4-87408-414-1,2400円」という書籍に[[計算機イプシロン]]を動的に求める[[アルゴリズム]]が詳細に解説されており、また[[ソースコード]]は公式サイトにおいても配布されている。この本は非常に面白いので迷わず買え。は公式サイトにおいても配布されている。この本は非常に面白いので迷わず買え。個人的にはこの手の技術書を買う際に目次と技術評論社という名前だけで信頼して買うようになった一冊である。
https://oku.edu.mie-u.ac.jp/~okumura/algo/
using System;
static float Foo(float x) { return x; }
static float EpsilonMachineEpsilon()
{
int b, p;
public static void Main(string[] args)
{
Console.WriteLine("epsilon = {0}", EpsilonMachineEpsilon());
}
}
</sourcesyntaxhighlight> 計算機イプシロンの定番の[[アルゴリズム]]といえば、変数をひたすら2で割り続け、ゼロになった瞬間のひとつ前を捉えるというもの。「1以上」という条件はコンピューターの指数と仮数の組み合わせで表現される浮動小数点数では、1未満だと指数部だけを使ってどこまでも小さくなってしまうためであり、なんとしても仮数部を使おうということらしい。<syntaxhighlight lang="csharp"> static double MachineEpsilon() { double eps = 1.0d; do { eps /= 2.0d; } while ((double)(1.0 + eps) != 1.0); return eps; }</syntaxhighlight> == 備考 ==実行環境(主に[[CPU]]の違い)により計算結果が変化する点に注意すること。[[アーキテクチャ]]がいっぱいある[[Xamarin]]系は要注意。
[[category: .NET]]
[[category: Mono]]
[[category: Xamarin]]