1

のようなものを返す可能性がresultあるため、falseになる可能性がありますか?タイトルよりも一般的に:4 / 2.01.99999999

int a = // any valid int
int b = // any valid int
boolean result = (a/(double)b) >= a/b;

これが可能であれば、誰かがとの例を提供できaますbか?これが不可能な場合、これを証明するJavaまたは浮動小数点の仕様はありますか?

私は数分前にこのロジックを書きましたが、突然それが壊れることを心配しました。私はそれを破ることができませんでしたが、それがすべてのJVMで保証されているかどうか疑問に思っています。

4

3 に答える 3

5

aおよびbが正intの値の場合、a/(double)b >= a/b

intの値が。の他のオペランドとの比較のためa/bに変換されるなど、理解されているセマンティクスとともに、次の前提条件を使用します。double>=

敷地内:

  • の範囲intは[-2,147,483,648、2,147,483,648)です。
  • doubleIEEE75464ビットバイナリです。
  • 丸めモードは、最も近い値に丸められます。
  • すべての浮動小数点演算、特に除算はIEEE754に準拠しています。
  • 整数a/bはゼロに向かって切り捨てられます。

表記:

  • aはの数学的な値ですa
  • bはの数学的な値ですb
  • a / bなどの数式は、。などの計算式とは異なり、正確a/bです。
  • Lを。に対して生成された値としますa/(double)b
  • Rを。に対して生成された値としますa/b

証拠:

  • すべてのint値はで表すことができるdoubleため、IEEE754では変換intdouble正確にする必要があります。
  • したがって、aとb(double) a正確(double) b生成し、最も近いに正しく丸められたa / bを生成します。a/(double)bdouble
  • Rはゼロに向かって切り捨てられたa/bであり a / b正であるため、Rfloor(a / b)です。
  • a / bの最大値は2,147,483,647/1=2,147,483,647です。この大きさ以下の各整数は、正確にとして表すことができdoubleます。
  • Ldouble最も近いa / bです。丸めによってLが減少すると、次に低い値に減少しdoubleます。この大きさのすべての整数が表現可能であるため、floor(a / b)が表現可能であり、Lは少なくともfloor(a / b)です。
  • したがって、L≥Rです
  • Rからへの変換doubleは正確であるため、LからRへの比較は数学的なL≥R同じ結果>=生成します
于 2013-03-12T01:47:35.773 に答える
2

負の数の場合、a = -10、b=3では失敗します。

正の入力の場合のみ、安全だと思います。

xをaをbで割った実数の結果とします。

まず、xがintとして表現できる場合を考えてみましょう。また、doubleとして表すこともでき、両方の計算でxが返されます。

ここで、xがintではないとします。問題は、xとa /(double b)の丸め誤差の差の絶対値がa/bの切り捨て誤差を超える可能性があるかどうかです。できない。

打ち切り誤差t=x --a/bは少なくとも1/bでなければなりません。xはInteger.MAX_VALUE/bより大きくすることはできないため、t/xは少なくとも1/Integer.MAX_VALUEです。これは、正しく丸められたdouble計算の最大丸め誤差よりもはるかに大きくなります。

于 2013-03-12T01:44:12.160 に答える
0

4 / 2.02.0浮動小数点除算は正確であるため、戻る必要があります。

ただし、負の数を指定すると、比較が失敗する可能性があります。-1/2 = 0一方、に注意してください-1.0/2.0 = -0.5

于 2013-03-12T00:45:27.657 に答える