result
是否为假,因为4 / 2.0
可能返回类似1.99999999
的东西?比标题更普遍:
int a = // any valid int
int b = // any valid int
boolean result = (a/(double)b) >= a/b;
如果这是可能的,谁能提供一个a
和b
的例子?如果这是不可能的,有任何java或浮点规范证明这一点吗?
我几分钟前写了这个逻辑,突然担心它会崩溃。我一直无法打破它,但我想知道它是否保证跨所有jvm。
如果a
和b
是int
的正值,则a/(double)b >= a/b
.
我使用了以下前提,以及理解的语义,例如a/b
的int
值将被转换为double
,以便与>=
的另一个操作数进行比较。
前提:
-
int
的取值范围为[-2,147,483,648,2,147,483,648)。 -
double
是IEEE 754 64位二进制文件。 - 舍入模式为四舍五入。
- 所有浮点运算,特别是除法,都符合IEEE 754。
- 整数
a/b
向零截断。
标记:
-
a为
a
的数学值。 -
b为
b
的数学值。数学表达式,如a/b,是精确的,与计算表达式如a/b
不同。 - 设L为
a/(double)b
产生的值。 - 设R为
a/b
产生的值。
证明:
- 所有
int
的值都可以在double
中表示,因此IEEE 754要求将int
精确地转换为double
。 因此, - 最大的a/b为2147483647/1 = 2147483647。这个数量级及以下的每个整数都可以精确地表示为
double
。L - 是
double
最近的<我> /<我> 。如果L通过舍入减少,它将减少到下一个低double
。由于这个数量级的所有整数都是可表示的,所以floor(a/b)是可表示的,因此L至少是floor(a/b)。 - 因此L≥R。
- R到
double
的转换是精确的,所以用>=
比较L到R的结果与数学上L≥R的结果相同。 我>我>我>我>我>
(double) a
和(double) b
精确地产生a和b, a/(double)b
产生a/b,正确地四舍五入到最接近的double
。自<<li> em> R <我> / b 截断向零,和<我> / b 是正的, R 是地板(<我> / b )。对于负数,a = -10, b = 3失败
只要是正面输入,我想你是安全的。
设x为a除以b的实数结果
首先考虑x可以表示为int的情况。它也可以表示为双精度体,并且两次计算都返回x。
现在假设x不是int型。问题是x和a/(double b)之间舍入误差差的绝对值是否会超过a/b的截断误差。它不能。
截断误差t = x - a/b必须至少为1/b。x不能大于整数。所以t/x至少是1/Integer.MAX_VALUE/b。
4 / 2.0
必须返回2.0
,因为浮点除法是精确的。
负数可能会导致比较失败。注意-1/2 = 0
和-1.0/2.0 = -0.5
.