【问题标题】:Why is it that when I have X(long) / (Y*Y*Y)(long) I get Error: Divide by Zero?为什么当我有 X(long) / (Y*Y*Y)(long) 我得到错误:除以零?
【发布时间】:2011-09-23 19:27:09
【问题描述】:

在我的示例中,X 已经很长,Y 也很长。那时我不投。

我真的只想除以一个立方数。 (使用原生库)

这些数字非常大。如果我将它们转换为浮点数并执行此操作,则其值为 Infinite...

System.out.println(formatter.format("%20d", (X/(Y*Y*Y))));

Y 是一个非常大的数字,它不是 0。X 是以毫秒为单位的时间度量。

如果这个问题没有关闭,我将在短时间内发布确切的代码......我现在无法访问它。

上下文:我正在处理 O(n^3) 的大符号计算。

错误:“线程“主”java.lang.ArithmeticException 中的异常:/ 为零”

答案:

假设您不是真的要引用引号,可能的原因是 Y * Y * Y 大于 2 ^ 31。溢出,下半部分 0。我相信只有当 Y 是 2^11 的倍数时才会发生这种情况 (2048) - 但我不确定*

-对我来说就是这种情况,Y 是 2048 的倍数,希望这有助于尝试找到解决方案。

    // Algorithm 3
    for( int n = 524288; n <= 5000000; n *= 2 ){
        int alg = 3;
        long timing;
        maxSum = maxSubSum3( a );
        timing = getTimingInfo( n, alg );
        System.out.println(fmt.format("%20s %20d %20d %20d %20d %20s%n", "Alg. 3", n, timing, timing, timing/(n*n), "time/(n*log(n))"));
    }

【问题讨论】:

  • 请贴出代码。
  • 大概是因为Y 是零吧?如果是这样的话,那么再乘以它本身也不会改变这个事实。
  • 阅读 BigDecimal 的 api 文档。
  • @KRB,您发布的代码可能无法编译(请注意,您使用了字符串文字:"(X/(Y*Y*Y))",而不是数字)。人们在索要代码时向您提出的要求是,您发布的代码是否足够人们可以在他们自己的 PC 上运行的代码,以准确显示您遇到的问题。请问可以发这样的sn-p吗?
  • 可能是一个红鲱鱼,但我不得不问:你真的得到一个错误,比如“线程“主”java.lang.ArithmeticException:/零”之类的错误,还是你得到0 作为答案?如果 YYY > X,那么 0 将是预期的答案,因为这是整数除法。

标签: java math divide-by-zero


【解决方案1】:

假设你的意思不是引号,可能的原因是 Y * Y * Y 大于 2 ^ 31。它溢出,下半部分为 0。

我相信只有当 Y 是 2^11 (2048) 的倍数时才会发生这种情况 - 但我不确定。

通过确保 Y^3 的计算是使用一些可以容纳它的数据类型来完成的,可以避免这种情况。如果小于 200 万,可以用 long 代替。如果没有,您将不得不使用双精度或 BigInteger。鉴于您的其他值以毫秒为单位,我猜浮点数会很好。所以你最终会得到:

System.out.println(formatter.format("%20d", (int)(X/((double)Y*Y*Y))));

您可能还想对输出使用浮点数 - 我假设不是。

【讨论】:

  • Y 是 2048 的倍数。我通过循环的每次迭代将 Y 乘以 2,它从 2048 开始。我认为你正在做一些事情。我该如何解决这个问题。哈哈,我需要这些数字。
  • @KRB:你确定你的 Y 是 2048 的倍数吗?我问是因为 2048 与 137600000 最接近的倍数是 134217728。但是,我怀疑这是问题所在 - MAX_VALUE 长期为 2^63-1,所以我将 2097152 (=2^21) 立方,导致翻转,但是不是除以 0 错误(尽管这可能取决于 JVM)。但是,使用当前时间的毫秒表示并除以 137600000^3 得到 0;因此我想知道您是否将此结果用作另一个计算中的除数,这确实会导致您的错误。
  • 我不使用这个计算的结果,它只是打印出来的。 @GreenMatt
  • 我之前没有看到“如果我将它们转换为浮点数并执行它,它的值是无限的......” - 抱歉。鉴于此,我必须得出结论,要么 Y 为 0,要么您使用显示的格式 - %d - 这将是无效的。您需要将其分解为多行代码,并放入打印、断言或其他一些调试机制,以便您可以看到问题出在哪里。
【解决方案2】:

您肯定不是要将“(X /(Y * Y * Y))”作为字符串文字传递吗?那是一个字符串,其中包含您的 express 而非可编译的 Java 代码,它表示 Java 将执行的计算。这就是问题 1:删除那些引号。

其次,格式化程序与除数无关,因此与您无关,也不是您的问题。

第三,选角与此无关。你的问题正是它所说的:你被零除。我假设你不想那样做。因此,Y 必须为 0。

第四,这里没有使用原生库。都是Java。对了,就是这个意思?

您可能希望使用 BigInteger 对长溢出的非常大的值执行数学运算。但是,这不会使除以零以某种方式不是除以零。

【讨论】:

    【解决方案3】:

    也许您应该尝试使用longfloat 转换:

    ( ( X / Y ) / Y ) / Y
    

    如果Y 是 2 的足够高的幂(2^22 或更高),那么 Y^3 将高于 2^64 2 的幂。long 在 Java 中使用 64 位,不是吗?对吗?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-08
      相关资源
      最近更新 更多