teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

3

main()をvoidにしてはいけません。

2023/06/21 05:10

投稿

ikedas
ikedas

スコア4441

answer CHANGED
@@ -101,7 +101,7 @@
101
101
  printf(">\n\n");
102
102
  }
103
103
 
104
- void main()
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箇所微修正。

2023/06/20 21:48

投稿

ikedas
ikedas

スコア4441

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~~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箇所微修正。

2023/06/20 09:01

投稿

ikedas
ikedas

スコア4441

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箇所微修正。