2016-08-23 17 views
0

私は見て、かなり理解していない質問。倍精度変数の乗算

まず、我々は任意の値を作成:その後、

int x = random(); 
int y = random(); 
int z = random(); 

(intは32ビットである) を続行:

double dx = (double) x; 
double dy = (double) y; 
double dz = (double) z; 

(ダブルが64ビットである)

質問が言うことでしたが次の文がの場合は常に true(1を返します)。

a. dx+dy+dz==dz+dy+dx 

b. dx*dy*dz==dz*dy*dx 

への回答(a)に「はい、二重の正確な表現の範囲内で」 (そう、それであるか、それは常に真実ではないのですか?とし、それは常にない場合には、

(b)に対する答えは「いいえ、たとえばdx = Tmax、dy = Tmax-1、dz = Tmax-2」 の3つの値の例を参考にしたいと思います。私は試してみて、それは同じ結果であることが判明した(しかし、私は間違っていた可能性が高い - /)

私はそれらの答えが正しい理由を理解したいです

ありがとう!

答えて

1

浮動小数点演算では、は決してと等しいかどうかをテストする必要があります。典型的な例は0.1 + 0.2 != 0.3です。 (詳細については、http://0.30000000000000004.com/を参照してください。特に言語があなたを隠すかどうかを確認するには、0.1と0.3を二重で正確に表すことができないため、これがどのように発生するかをよく説明してください)。特定の範囲内で互いに十分接近しているかどうか、通常は「許容差」と呼ばれます。

IEEE 754の定義を参照してください:それは、二重で「正確に表現する」ことができるものを指定することが無意味だから、私は、(A)への答えに反対https://en.wikipedia.org/wiki/Double-precision_floating-point_format

を - すべての入力が二重表現であれば与えられたランダムなビット(x、y、z)、それは定義上、正確な表現です。さらに、「はい、しかしいくつかの条件の下でのみ」と答えるのは疑わしいですが、「はいつもですか?その場合の答えは「いいえ」です。

(a)の1つの反例は以下のとおりです。私は浮動小数点数がある相対精度しか持たないことを考慮して構築しました。したがって、非常に小さい数値を非常に大きな数値に追加することで違いはありません。その小さな数字を十分大きくしてください。

  • 1e16 + 1 + 1 = 10000000000000000
  • 1 + 1 + 1e16 = 10000000000000002

(B)、Iがランダムに試みた最初の反例た:

  • 0.1 * 0.1 * 0.7 = 0.007000000000000001
  • 0.7 * 0.1 * 0.1 = 0.006999999999999999