【问题标题】:Different results of different, but equal math operations on float in Java [duplicate]Java中浮点数的不同但相等的数学运算的不同结果[重复]
【发布时间】:2014-06-09 19:18:47
【问题描述】:

关于floatint 数据类型的Java 数学运算的问题。

我必须计算两个日期之间的年差。

代码:

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Object date = obj.getInfoItem().getInfoValue();

Date today = new Date();
Date birthDate = null;
float dateDiff;
int age0, age1;

try {
        // unify the date format
        birthDate = format.parse(date.toString());
        today = format.parse(format.format(today));
} catch (ParseException e) {
        e.printStackTrace();
}

// calculate the age in years with round    
dateDiff = today.getTime() - birthDate.getTime();
age0     = (int)((dateDiff / (24 * 60 * 60 * 1000)) / 365);
age1     = (int)(dateDiff / (365 * 24 * 60 * 60 * 1000));

由于Java中的日期差是以毫秒为单位计算的,因此我们必须在计算后做一些内务工作,并将收到的结果从毫秒转换为年。

代码执行后,我在调试器中得到如下结果:

dateDiff = 8.4896639E11  
age0 = 26  
age1 = 577

age0 是正确的结果。

既然age0age1 上的两个运算在数学上是相等的,为什么结果不同? 为什么操作«(float / (a\*b\*c)) / d»和«(float / (a\*b\*c\*d))»之间存在差异,其中abcdint

【问题讨论】:

  • 这个 365 * 24 * 60 * 60 * 1000 是整数溢出。
  • 进一步扩展,如果您想使用常量值在浮点数中进行计算,您应该将常量显式设置为浮点数。 IE。 365f * 24f * 60f * 60f * 1000f.
  • «365f * 24f * 60f * 60f * 1000f» 修复了该问题。谢谢!

标签: java datetime precision date-arithmetic date-difference


【解决方案1】:

扩展 Sotirios 的评论:整数文字 36524601000 都具有 int 类型。因此,将使用int 类型执行乘法。由于数学结果是 31536000000,最大可能的int 是 2147483648,结果溢出,结果会回绕。因此,结果将是int,其值等于 31536000000 模 232,即 1471228928。只有这样,它才会转换为 float 以划分为 dateDiff。将L 附加到任何整数文字的末尾将修复它,因为现在至少有一个乘法将使用long 执行。但是将365 更改为365.0(或365f)可能更清楚。 (实际上,@Chill 建议在所有常量上使用 f 对我来说是最好的,尽管这并不是真正必要的。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-20
    • 2013-01-31
    • 2015-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多