回答編集履歴
3
main()をvoidにしてはいけません。
answer
CHANGED
@@ -101,7 +101,7 @@
|
|
101
101
|
printf(">\n\n");
|
102
102
|
}
|
103
103
|
|
104
|
-
|
104
|
+
int main()
|
105
105
|
{
|
106
106
|
long denom;
|
107
107
|
double recip;
|
@@ -152,6 +152,7 @@
|
|
152
152
|
decode_double("Reciprocal", recip);
|
153
153
|
decode_double("R x D", recip * denom);
|
154
154
|
|
155
|
+
return 0;
|
155
156
|
}
|
156
157
|
```
|
157
158
|
実行すると、標準入力からTicksPerMinuteの値を読み込みます。コンパイラによる最適化を避けるためにこうしています。
|
2
2箇所訂正、1箇所微修正。
answer
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
まず、``1.6666666666667e-9`` という表示は計算の際の丸め (英語のround offの訳語です。「丸目」は差し金です) による誤差の結果ではありません。一般に、小数部を持つ2進数を有限桁の10進数に正確に変換~~することはできません~~しようとすると不必要に長くなってしまいがちです。どこかで表示を打ち切らなければな
|
1
|
+
まず、``1.6666666666667e-9`` という表示は計算の際の丸め (英語のround offの訳語です。「丸目」は差し金です) による誤差の結果ではありません。一般に、小数部を持つ2進数を有限桁の10進数に正確に変換~~することはできません~~しようとすると不必要に長くなってしまいがちです。どこかで表示を打ち切らなければならないため、打ち切った桁の表示が不正確になっているにすぎません。実際、ためしに同じ数を小数点以下~~17~~18桁まで表示してみると、やっぱり``...6667``になります。通常は``double``の精度は53ビットしかありませんから (後述)、10進での小数点以下~~17~~18桁目なんかにはなんの意味もないのです。とにかくこれは計算による丸め誤差ではありません。
|
2
2
|
|
3
3
|
では丸め誤差がどこで発生するかというと、``1.0 / TicksPerMinute`` という計算を**2進数で**行った結果に誤差が発生します。
|
4
4
|
|
@@ -157,4 +157,6 @@
|
|
157
157
|
実行すると、標準入力からTicksPerMinuteの値を読み込みます。コンパイラによる最適化を避けるためにこうしています。
|
158
158
|
|
159
159
|
---
|
160
|
-
2023-06-20 1箇所訂正、1箇所微修正。
|
160
|
+
2023-06-20 1箇所訂正、1箇所微修正。
|
161
|
+
|
162
|
+
2023-06-21 2箇所訂正、1箇所微修正。
|
1
1箇所訂正、1箇所微修正。
answer
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
まず、``1.6666666666667e-9`` という表示は計算の際の丸め (英語のround offの訳語です。「丸目」は差し金です) による誤差の結果ではありません。一般に、小数部を持つ2進数を有限桁の10進数に正確に変換することはできません。どこかで表示を打ち切らなければないないため、打ち切った桁の表示が不正確になっているにすぎません。実際、ためしに同じ数を小数点以下17桁まで表示してみると、やっぱり``...6667``になります。通常は``double``の精度は53ビットしかありませんから (後述)、10進での小数点以下17桁目なんかにはなんの意味もないのです。とにかくこれは計算による丸め誤差ではありません。
|
1
|
+
まず、``1.6666666666667e-9`` という表示は計算の際の丸め (英語のround offの訳語です。「丸目」は差し金です) による誤差の結果ではありません。一般に、小数部を持つ2進数を有限桁の10進数に正確に変換~~することはできません~~しようとすると不必要に長くなってしまいがちです。どこかで表示を打ち切らなければないないため、打ち切った桁の表示が不正確になっているにすぎません。実際、ためしに同じ数を小数点以下17桁まで表示してみると、やっぱり``...6667``になります。通常は``double``の精度は53ビットしかありませんから (後述)、10進での小数点以下17桁目なんかにはなんの意味もないのです。とにかくこれは計算による丸め誤差ではありません。
|
2
2
|
|
3
3
|
では丸め誤差がどこで発生するかというと、``1.0 / TicksPerMinute`` という計算を**2進数で**行った結果に誤差が発生します。
|
4
4
|
|
@@ -68,7 +68,7 @@
|
|
68
68
|
|
69
69
|
見ての通り、うまくいくのは丸めモードが`FE_TONEAREST` (最近接偶数丸め) の場合だけです。`FE_UPWARD` (正の無限大への丸め)、`FE_DOWNWARD` (負の無限大への丸め)、`FE_TOWARDZERO` (0への丸め) では丸め誤差は相殺されません。また、C#では`double`から整数への変換の際には0方向へ丸める ([参照](https://learn.microsoft.com/ja-jp/dotnet/csharp/language-reference/builtin-types/numeric-conversions)) ので、モードが `FE_DOWNWARD` や `FE_TOWARDZERO` だと、結果を整数として使いたいときに意図しない結果になる可能性があります。
|
70
70
|
|
71
|
-
`FE_TONEAREST` ではうまくいく理由ですが、このモードでは仮数部の丸め誤差の絶対値が常に`2^{-53}`以下である (ほかのモードでは`2^{-52}`未満と、より大きくなり得る) こと、また丸め方向がひとつの方向に固定されない
|
71
|
+
`FE_TONEAREST` ではうまくいく理由ですが、このモードでは仮数部の丸め誤差の絶対値が常に`2^{-53}`以下である (ほかのモードでは`2^{-52}`未満と、より大きくなり得る) こと、また丸め方向がひとつの方向に固定されないため計算を繰り返す中で誤差が均されやすいこと、があると考えられます。
|
72
72
|
|
73
73
|
ひとまずこんなところで。これは意見交換ではないなー。
|
74
74
|
``` C
|
@@ -154,4 +154,7 @@
|
|
154
154
|
|
155
155
|
}
|
156
156
|
```
|
157
|
-
実行すると、標準入力からTicksPerMinuteの値を読み込みます。コンパイラによる最適化を避けるためにこうしています。
|
157
|
+
実行すると、標準入力からTicksPerMinuteの値を読み込みます。コンパイラによる最適化を避けるためにこうしています。
|
158
|
+
|
159
|
+
---
|
160
|
+
2023-06-20 1箇所訂正、1箇所微修正。
|