C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

クラス内にFunctionを作る方法

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■89977 / inTopicNo.1)  クラス内にFunctionを作る方法
  
□投稿者/ かめかめ (1回)-(2019/01/26(Sat) 21:56:44)

分類:[.NET 全般] 

    Public Class xxxClass

        Property L As Single
        Property R As Single

        Property T As Single
        Property B As Single

    End Class


というクラスを作り

Dim aaa as New xxxClass
と宣言したとします

それで
aaa.L
aaa.R
aaa.T
aaa.B
全て0になっているかどうか調べるFucntionをクラス内に作りたいのですが
どのようにしたら良いですか?



引用返信 編集キー/
■89978 / inTopicNo.2)  Re[1]: クラス内にFunctionを作る方法
□投稿者/ キングダム (1回)-(2019/01/26(Sat) 23:58:20)
No89977 (かめかめ さん) に返信

こんな感じのメソッドを作ればよいかと

Function IsAllZero() As Boolean
    Return {L, R, T, B}.All(Function(value) Math.Abs(value - 0F) < Single.Epsilon)
End Function

引用返信 編集キー/
■89979 / inTopicNo.3)  Re[2]: クラス内にFunctionを作る方法
□投稿者/ かめかめ (3回)-(2019/01/27(Sun) 11:33:14)
ありがとうございます。

そのような方法があったのですね。
ちなみに
Return {L, R, T, B}.All(Function(value) value = 0F)

というようにしないのはなぜなのですか?

引用返信 編集キー/
■89982 / inTopicNo.4)  Re[3]: クラス内にFunctionを作る方法
□投稿者/ キングダム (2回)-(2019/01/27(Sun) 13:56:50)
No89979 (かめかめ さん) に返信

浮動小数点数を比較するときは有効な最小値を決めて
比較する2つの値の差が最小値以下だったらその差を誤差として2つの数字を
同じとみなすというやり方が一般的です

有効な最小値にはマシンイプシロンがよく使われるので
Math.Abs(value - 0F) < Single.Epsilon
こうしました

しかし、回答後に調べたところでは
Single.Epsilonとマシンイプシロンは違うものでした

Single.Epsilonは0より大きい最小値で
マシンイプシロンは1より大きい最小値と1との差です

Single.Epsilonは比較の最小値を決めるときに
これよりは大きな値にしないと意味ないよというもののようで
これ自体を比較の最小値にするのは不適切みたいです

Single型は単精度浮動小数点数を表して
単精度浮動小数点数のマシンイプシロンは2^-23なので

Math.Abs(value - 0F) < 0.0000001192093F

でいんじゃないかなと思いました
引用返信 編集キー/
■89987 / inTopicNo.5)  Re[4]: クラス内にFunctionを作る方法
□投稿者/ 魔界の仮面弁士 (2022回)-(2019/01/28(Mon) 16:27:21)
No89979 (かめかめ さん) に返信
>> Return {L, R, T, B}.All(Function(value) Math.Abs(value - 0F) < Single.Epsilon)
> Return {L, R, T, B}.All(Function(value) value = 0F)
> というようにしないのはなぜなのですか?

既にキングダム さん本人から訂正が入っているので蛇足ではありますが、
No89978 の判定式のまま処理してしまうと、結果的には
上記 No89979 の判定式と同じ意味になってしまいます。
(許容値は Single.Epsilon より大きな値でないといけません)


ちなみに、「メモリ上完全にゼロな Single 値」であることを保証したい場合には、
『.All(Function(value) value = 0F)』ではなく、
『.SelectMany(AddressOf BitConverter.GetBytes).All(Function(b) b = 0)』などとします。
※Single 値が「0.0F」ではなく「-0.0F」だった場合に、異なる結果となります。



■No89982 (キングダム さん) に返信
> 有効な最小値にはマシンイプシロンがよく使われるので
> Math.Abs(value - 0F) < Single.Epsilon

ちなみに ARM プロセッサの場合は、Single.Epsilon が 0.0 と等しくなってしまうそうな…。
https://docs.microsoft.com/en-us/dotnet/api/system.single.epsilon



> 単精度浮動小数点数のマシンイプシロンは2^-23なので
> Math.Abs(value - 0F) < 0.0000001192093F

上記の右辺で使われている値は、「2 ^ -23 よりも大きな最小の Single 値」に相当する
0.0000001192093037616359652020037174224853515625 な値ですね。有効桁数の問題から
0.0000001192093F というリテラル表記になりますけど。
(Single 値の有効桁数は 10進数換算で 7.2247 桁分しかないため)


一方、「(1より大きい最小値)から 1 を引いた値」である「2 ^ -23」自体の値は、
上記の右辺よりも「2 ^ -46」だけ少ない値となります。
具体的には「0.00000011920928955078125」≒「0.00000011920929F」です。

引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ