><https://twitter.com/orange_in_spacehttps://pawoo.net/@orange_in_space
バグってる!!!!><;(符号無視してるね><;)
ちなみに名前空間><
1/3*3が1になる版decimal作った><;
decimal justBelowOne_dec = 1.0m - new decimal(1, 0, 0, false, 28);Console.WriteLine(justBelowOne_dec == (1.0m / 3.0m * 3.0m));これもちゃんと(?) trueになったし、decimalでも「精度の限度で1に一番近くて1より小さい値」を1.0とみなすという処理を挟めば、実数っぽいふるまいになりそう・・・?><;
同じ事をC#のdecimalでやるならば、decimal justBelowOne = 1.0m - new decimal(1, 0, 0, false, 28);らしい・・・><(MS Copilotさんがそう言ってる><;)
つまり、計算するたびに値が justBelowOneであるかをチェックして、 justBelowOneであれば1.0にするって処理を挟んだ数値型を作れば、まるで実数空間のように0.99999...... = 1.0な数値型が作れる?><;
C#の場合long bits = BitConverter.DoubleToInt64Bits(1.0d);double justBelowOne = BitConverter.Int64BitsToDouble(bits - 1);ってする事によってdoubleで1.0から最小単位だけ小さい値が得られて、それとの比較であれば、つまり(1.0d / 49d * 49d) == justBelowOneはtrueになるっぽい><オレンジの発想自体はあってた><;
・・・・ということはオレンジの最初の発想である「その精度で1.0に最も近い値は1.0ってことにすればいいんじゃね?><」は、成り立つのかな?><;
ていうかさっきの記事にそのまんまの内容が追記されてるじゃん!!!!!><;
GPT-4oさんの解説のまとめ部分だけ引っ張ってくると
"・IEEE 754規格は、数値の丸め方法も標準化しており、通常は「最近接丸め」が使われます。・0.3333333333333333 は double 型の内部表現で最も近い値に丸められ、それに 3.0 を掛けた結果も丸められて 1.0 になります。・これにより、 0.3333333333333333 * 3.0 が 1.0 になるのです。"
マジで知らなかった><; 超恥ずかしい><;
GPT-4oさんに聞いたらものすごく詳しく解説してくれた><説明全部省いて結論だけで言うと、C# に限らず、IEEE754で倍精度浮動小数点数型で1/3*3すれば(結果的に)1になるらしい><
浮動小数点数の比較、なんもわからん><
正直すまんかった><(?)
double a = 1.0d;double b = a / 3.0d;double c = 1.0d;Console.WriteLine((b * 3.0d) == c);
もtrueでした><;
当たり前かもだけど、(1.0d / 3.0d * 3.0d) == (1.0d - double.Epsilon)はちゃんとtrueだった><1.0d == (1.0d - double.Epsilon)もtrueだった・・・><;
1/3がしたい時はdouble使おう?><(?)
https://mstdn.nere9.help/@orange_in_space/112584909300084571"decimalに限らずfloatでも1.0/3.0*3.0の答えの値(定数)を1.0と見なすような仕組みだけあればいいんでは?><"
C# のdoubleはそうだよってこと・・・?><;
!!!!!!!><;
C# のdoubleでいうと、1.0 - Double.Epsilon;みたいなのも1.0として扱えばおk?><;
思考の /dev/null