方法在double参数上执行不正确的计算

时间:2018-01-06 15:26:50

标签: java math

首先,对不起,如果这是一个微不足道的问题。我是初学者,已经坚持了好几个小时。

下面我尝试创建一个具有一系列if else语句的unitizer方法。它们按降序写入,每次检查一个值是否可以除以给定的数字,如果是,则执行除法,舍入值并在结果中添加适当的单位。

在这个问题中,我试图删除所有不必要的代码,因此我在这里展示的只是整合器方法的一个片段。

为什么unitizer方法以小时为单位输出值,当值应以秒为单位时?

为澄清,预期值约为4秒。

private void changeStyleViaThemeXml() {
  try {
     Theme theme = Theme.load(getClass().getResourceAsStream(
           "/org/fife/ui/rsyntaxtextarea/themes/dark.xml"));
     theme.apply(textArea);
  } catch (IOException ioe) { // Never happens
     ioe.printStackTrace();
  }
}

控制台输出:

public class simplified 
{

    public static void main(String[] args) 
    {

            int i = 5;
            double n = Math.pow(2, (double) i);
            System.out.println(a6(n)); // correctly displays the expected value.
            System.out.println(unitizer(a6(n)));

        }

        public static double a6 (double n)
        {
            return Math.pow(2, n); // this value is in nanoseconds.
        }

        public static String unitizer (double x)
        {
            String time = "";

            if (x/(60*60*1000*1000*1000) >= 1) 
            {
                x = Math.round(x/(60*60*1000*1000*1000) * 100.0) / 100.0;
                time = x + "hr ";
            }

            return time;
        }   

}

1 个答案:

答案 0 :(得分:3)

表达式int60*60*1000*1000*1000个溢出。这意味着,实际结果3,600,000,000,000太大,无法存储为int值,因此会“减少”(mod 2^31)到817,405,952

这可以通过在“更大”的算术中评估所述表达来解决,例如long。有一个很好的小修饰符,它将强制执行:

60L*60*1000*1000*1000
  ^

特别是,它提示编译器将前面的文字60解释为long值,因此整个计算将在long算术中完成。
这个修饰符不区分大小写;但我更喜欢大写L,因为小写字母l很容易被数字1弄错。

通过此更改,代码将不会输入if - 语句,因为值x不会超过一小时。很可能省略的unitizer代码将处理这种情况。

最后一点,java有一个内置的TimeUnit枚举,也可以进行这些转换。但是,它在long算术中执行,而不是double算术,因为此特定问题需要它。