回答編集履歴
4
有効桁の説明追加
test
CHANGED
@@ -33,3 +33,13 @@
|
|
33
33
|
Zuishinさんが別回答のコメントでおっしゃっている通り、`AMax * (double)ARatio`の結果はdoubleで、`AMax * ARatio`の結果はfloatです。([参考URL](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#11473-binary-numeric-promotions))
|
34
34
|
|
35
35
|
計算結果は正しくは29.0000009536743ですが、floatの精度では表現できない数値なので、丸められて29となります。
|
36
|
+
|
37
|
+
---
|
38
|
+
|
39
|
+
もしかして、全部floatで計算したほうが、途中でfloatをdoubleに変換して計算したときより、結果が正確に見えるのはなぜか、という質問でしょうか。
|
40
|
+
それは、最初にfloatで計算してしまってるので、途中でdoubleにしてもfloatでの有効桁までしか信用できないためです。
|
41
|
+
|
42
|
+
floatの有効桁は10進数で7桁+α、doubleの有効桁は15桁+αです。
|
43
|
+
最初にfloatで計算してしまっているので、その結果は7桁までしか信用できません。
|
44
|
+
その計算結果を後からdoubleにして15桁の有効桁で計算しても、15桁まで信用できるわけではなく、変わらず7桁までしか信用できません。
|
45
|
+
doubleは15桁まで信用できる前提で表示するので、29.0000009536743のように表示されて正しくないように見えますが、先頭7桁だけ見れば、29という正しい結果になっていることが分かると思います。
|
3
また質問が変わっていたので、そちらに合わせて修正
test
CHANGED
@@ -1,13 +1,3 @@
|
|
1
|
-
Zuishinさんが別回答のコメントでおっしゃっている通り、`AMax * (double)ARatio`の結果はdoubleで、`AMax * ARatio`の結果はfloatです。([参考URL](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#11473-binary-numeric-promotions))
|
2
|
-
|
3
|
-
計算結果は正しくは29.0000009536743ですが、floatの精度では表現できない数値なので、丸められて29となります。
|
4
|
-
|
5
|
-
---
|
6
|
-
以下は、修正前の質問に対する回答になります。
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
1
|
float型で表現可能な29の次に大きい数値を求めて、double型に変換すれば、似たような結果にはなります。([参考URL](https://stackoverflow.com/questions/9485943/calculate-the-unit-in-the-last-place-ulp-for-doubles))
|
12
2
|
```c#
|
13
3
|
using System;
|
@@ -36,3 +26,10 @@
|
|
36
26
|
それなのにfloat値だけ`29`と表示されてしまうのは、`ToString()`の仕様が原因となります。
|
37
27
|
|
38
28
|
`ToString()`に数値書式指定文字列を与えない場合のデフォルトは`"G"`であり([参考URL](https://docs.microsoft.com/ja-jp/dotnet/api/system.single.tostring?view=net-6.0))、`"G"`に精度を指定しない場合のデフォルトは[floatの場合7桁](https://docs.microsoft.com/ja-jp/dotnet/standard/base-types/standard-numeric-format-strings#general-format-specifier-g)なので、`29`と表示されます。
|
29
|
+
|
30
|
+
---
|
31
|
+
追記への回答
|
32
|
+
|
33
|
+
Zuishinさんが別回答のコメントでおっしゃっている通り、`AMax * (double)ARatio`の結果はdoubleで、`AMax * ARatio`の結果はfloatです。([参考URL](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#11473-binary-numeric-promotions))
|
34
|
+
|
35
|
+
計算結果は正しくは29.0000009536743ですが、floatの精度では表現できない数値なので、丸められて29となります。
|
2
新しい質問への回答
test
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
Zuishinさんが別回答のコメントでおっしゃっている通り、`AMax * (double)ARatio`の結果はdoubleで、`AMax * ARatio`の結果はfloatです。([参考URL](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#11473-binary-numeric-promotions))
|
2
|
+
|
3
|
+
計算結果は正しくは29.0000009536743ですが、floatの精度では表現できない数値なので、丸められて29となります。
|
4
|
+
|
5
|
+
---
|
6
|
+
以下は、修正前の質問に対する回答になります。
|
7
|
+
|
8
|
+
|
9
|
+
|
10
|
+
|
1
11
|
float型で表現可能な29の次に大きい数値を求めて、double型に変換すれば、似たような結果にはなります。([参考URL](https://stackoverflow.com/questions/9485943/calculate-the-unit-in-the-last-place-ulp-for-doubles))
|
2
12
|
```c#
|
3
13
|
using System;
|
1
両者が同じ数値であることの明示、余計な愚痴の削除
test
CHANGED
@@ -22,8 +22,7 @@
|
|
22
22
|
|
23
23
|
ただ、見ての通り、floatで表現可能な29の次に大きい数値をdoubleに変換しても29.0000019073486にしかならないので、29.0000009536743になるというのは何かの間違いではないでしょうか。
|
24
24
|
|
25
|
+
なお、ここで求めたfloat値とdouble値は、誤差なく完全に同じ数値です。
|
25
|
-
|
26
|
+
それなのにfloat値だけ`29`と表示されてしまうのは、`ToString()`の仕様が原因となります。
|
27
|
+
|
26
28
|
`ToString()`に数値書式指定文字列を与えない場合のデフォルトは`"G"`であり([参考URL](https://docs.microsoft.com/ja-jp/dotnet/api/system.single.tostring?view=net-6.0))、`"G"`に精度を指定しない場合のデフォルトは[floatの場合7桁](https://docs.microsoft.com/ja-jp/dotnet/standard/base-types/standard-numeric-format-strings#general-format-specifier-g)なので、`29`と表示されます。
|
27
|
-
|
28
|
-
・・・とここまで書いて確認したら、質問が書き換えられていてショックです。
|
29
|
-
もったいないのでそのまま回答として出しておきます。
|