简而言之:Java如何比较不同类型的数字?特别是:int,long,float和double。出于此问题的目的,比较意味着>
,<
,>=
和<=
;我理解将==
和!=
与浮点数一起使用的困难和问题。
如果两个数字属于同一类型(包括整数,两个双数等),则比较它们很容易;可能有直接的CPU指令来做,即使不是(古老的CPU?),也有这样做的标准。
比较某些类型的似乎直截了当;如果a
是int
且b
是long
,那么我们可以无损方式将a
转发为long
并进行比较直接(如果a
和b
被撤销,或者我们为int/long
交换float/double
,则类似。我不知道java是否真的这样做了。
但更有争议的是将整数/多头与浮动/双打进行比较。如果我有一个很长的整数值,浮点数不能完全表示,那么它如何舍入到浮点数将影响它与浮点数的比较方式。但是,是一个正确的答案,即使它不清楚它是什么。
例如,如果(这些不是真实示例,但存在真实示例)a=10001
但浮点数只能编码10000f
和10002f
,但两者之间没有任何内容,那么就有一个标准的舍入程序其中(float) a
恰好是这两件事之一。但我们应该拥有的是10000f < a
和a < 10002f
,这不能通过四舍五入然后进行比较来实现。
Java是如何以更智能的方式做到这一点的?或者它是圆的然后犯了一些错误?
答案 0 :(得分:2)
这在Java语言规范中得到了解答。转化次数列在section 5.6.2
中扩展基元转换(第5.1.2节)用于转换或 两个操作数由以下规则指定:
如果任一操作数的类型为double,则另一个操作数转换为double。
否则,如果任一操作数的类型为float,则转换另一个操作数 漂浮。
否则,如果任一操作数的类型为long,则转换另一个操作数 很久。
否则,两个操作数都将转换为int类型。
扩展的原始转换详细信息指定了以下内容(section 5.1.2)。
从int到float,或从long到float,或从long到double的扩展原语转换可能导致精度损失 - 也就是说,结果可能会丢失该值的一些最低有效位。在这种情况下,使用IEEE 754舍入到最接近模式,生成的浮点值将是整数值的正确舍入版本
由此进一步澄清(section 4.2.4)。
Java编程语言要求浮点运算表现得好像每个浮点运算符将其浮点结果四舍五入到结果精度。不精确的结果必须四舍五入到最接近无限精确结果的可表示值;如果两个最接近的可表示值相等,则选择具有最低有效位的值。这是IEEE 754标准的默认舍入模式,称为舍入到最近。
所以,是的,将long
与float
或double
进行比较可能会返回错误的结果,因为有long
个值无法由float
或double
。
答案 1 :(得分:0)
java.lang.BigInteger
和java.lang.BigDecimal
提供了将数学处理扩展到任意精度的功能......当然受限于计算机资源的限制(主要是CPU和内存)