如何修复与 BigInteger 和 int 不兼容的操作数

How to fix incompatible operand with BigInteger and int

提问人:bobby 提问时间:4/30/2023 最后编辑:bobby 更新时间:5/1/2023 访问量:261

问:

我试图为 collatz 猜想创建一个程序,我需要它来为更大的数字工作。因此,我尝试使用 BigInteger 类,但它似乎遇到了两种类型的错误:bigint 和 int。

我已经查找了 big int 的问题,它似乎适用于加法和乘法。但是,当尝试在除以 2 时获取余数时,它会返回错误。(在运行时开始时)。

import java.math.BigInteger;
import java.math.Bigdecimal;
import java.util.Objects;
import java.util.Scanner;
public class Main {
    /**
     * @param args
     */
    public static void main(String[] args) {
        boolean repeat = true;
        while (repeat){
            int i = 0;
            Scanner intIn = new Scanner(System.in);
            Scanner strIn = new Scanner(System.in);
            System.out.println("Enter number you want solved, Don't type 0. Use this program with caution");
            BigInteger num = intIn.nextBigInteger();
            while (num.equals(new BigInteger("1")) == false){
                if (num.equals(new BigInteger("1"))){
                  // The issue currently is that the remainder function returns an error, but im not sure exactly what is wrong with it.
                } else if (num.remainder(new BigInteger("2")) == 0) {
                    num = num.divide(new BigInteger("2"));
                } else {
                    num = num.multiply(new BigInteger("3"));
                    num = num.add(new BigInteger("1"));
                }
                i += 1;
            }
            System.out.println("It took " + i + " steps to reach 1. Would you like to do another number? (yes/no)");
            String yn = strIn.nextLine();
            if (Objects.equals(yn, "no")){
                repeat = false;
            }
        }
    }
}

在第 21 行中,错误出在 remainder 函数上。(以防您错过了评论)

Java 数学 BigInteger Collatz

评论

1赞 user16320675 4/30/2023
“checking to see if it is equal” -> 方法(是按位补码,不带任何参数)equals()not()
1赞 Sören 4/30/2023
请不要上传代码/数据/错误的图片。
1赞 user207421 4/30/2023
(1) 不要使用两个扫描仪。你只需要一个,两个是行不通的。(2)你无法与原始类型相提并论。如前所述,使用 。BigIntegersBigInteger.equals()
1赞 Stephen C 4/30/2023
java.lang.Error: Unresolved compilation problem- 这意味着您在修复编译错误之前尝试运行一些代码。别这样。首先修复编译错误。如果你按照自己的方式做,你需要挠头才能弄清楚编译错误到底在哪里!!
2赞 Stephen C 4/30/2023
stackoverflow.com/questions/55791203 是相关的。这同样适用于涉及原始操作数的关系运算符;即 、 、 、 和 一元运算符 、 和 位移运算符。唯一有效的运算符是 和 用于其他(兼容)引用类型。==!=<<=>>=+-~==!=

答:

0赞 Thomas Kläger 5/1/2023 #1

问题是返回另一个,您尝试将其与 int 值 (0) 进行比较。num.remainder(new BigInteger("2"))BigIntegerBigInteger

Java 语言规范 15.21。Equality Operators 指出:

相等运算符可用于比较两个可转换为数值类型的操作数 (§5.1.8),或两个布尔值或布尔值类型的操作数,或两个分别为引用类型或 null 类型的操作数。所有其他情况都会导致编译时错误。

(对引用类型上的相等运算符有一个额外的约束,请参阅最后一个块)。

由于是不可转换为数值类型的引用类型 (5.1.8.Unboxing Conversion 提到只有 、 、 、 和 are) 最后一个子句(所有其他情况都会导致编译时错误)适用。BigIntegerByteShortCharacterIntegerLongFloatDouble

要修复它,请将比较更改为

num.remainder(new BigInteger("2")).equals(BigInteger.ZERO)

请注意,该类有一些对代码有用的常量:BigInteger

BigInteger.ZERO
BigInteger.ONE
BigInteger.TWO

循环会重复使用这些值,因此,如果使用这些常量而不是重复为它们创建新对象,则循环将运行得更快。BigInteger

恕我直言,您甚至应该考虑为值 3 创建另一个局部常量:

BigInteger THREE = BigInteger.valueOf(3);

并使用它,例如在

num.multiply(THREE)

还有一点需要注意:

num.equals(new BigInteger("1")) == false

看起来很奇怪,可以写得更短

!num.equals(BigInteger.ONE)

最后一点(已经在评论中提到):

所有输入仅使用一个。在简单的情况下,使用两个扫描仪似乎可以工作,但在其他情况下(例如,使用输入重定向时)会失败。Scanner

仅使用一个扫描仪可能会导致其他问题,如 Scanner 在使用 next() 或 nextFoo()?后跳过 nextLine() 中可以看出,但这仍然是正确的方法。


15.21.3 中提到的引用类型相等比较还有一个附加条件。引用相等运算符 == 和 !=

如果无法通过强制转换将任一操作数的类型转换为另一个操作数的类型,则为编译时错误 (§5.5)。两个操作数的运行时值必然不相等(忽略两个值均为 null 的情况)。