Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何对两个数字实例使用模?_Java_Numbers_Modulo - Fatal编程技术网

Java 如何对两个数字实例使用模?

Java 如何对两个数字实例使用模?,java,numbers,modulo,Java,Numbers,Modulo,我遇到了一个场景,其中我有两个Number实例,我需要检查其中一个是否是另一个的倍数。 我尝试使用模来检查,例如: public static boolean isMultipleOf(Number a, Number b) { return a % b == 0; } 但是编译器不喜欢它: 运算符“%”不能应用于“java.lang.Number”, “java.lang.Number” 我明白为什么会这样,但我的问题是,实现这一点最简单的方法是什么? 实际值可以是任何类型的数字,我

我遇到了一个场景,其中我有两个
Number
实例,我需要检查其中一个是否是另一个的倍数。
我尝试使用模来检查,例如:

public static boolean isMultipleOf(Number a, Number b) {
    return a % b == 0;
}
但是编译器不喜欢它:

运算符“%”不能应用于“java.lang.Number”, “java.lang.Number”

我明白为什么会这样,但我的问题是,实现这一点最简单的方法是什么?
实际值可以是任何类型的数字,我希望避免检查每个值的实际数字类型,然后才执行操作

有什么想法吗?

谢谢

您可以这样做:

public static boolean isMultipleOf(Number a, Number b) {
    return a.longValue() % b.longValue() == 0;
}

当然,这假设
a
b
在数学上是整数(短、整数或长)。您可以使用
doubleValue()
,但要注意浮点代数比较…

您可以使用
doubleValue
方法将参数转换为
double
并应用
%
,例如:

private static boolean isMultipleOf(Number a, Number b){
    return (a.doubleValue() % b.doubleValue()) == 0.0;
}
它还可以与
int
float
一起使用,例如:

public static void main(String[] args) throws Exception{
    System.out.println(isMultipleOf(20, 10));
    System.out.println(isMultipleOf(20.0, 10));
    System.out.println(isMultipleOf(20, 10.0));
    System.out.println(isMultipleOf(20.0, 10.0));
}
以上打印
true
4次

更新

如果您处理的是巨大的数字,则可以使用
BigDecimal
class'
余数
方法,例如:

private static boolean isMultipleOf(Number a, Number b){
    return new BigDecimal(a.doubleValue()).remainder(new BigDecimal(b.doubleValue())).doubleValue() == 0.0;
}
不,没有类型检查你是做不到的 A仅提供转换为原语的方法,并且每个原语都不足以给出准确的答案

doubleValue不起作用 由于
double
只有53位精度,因此当输入是需要63位精度的
long
时,它会给出错误的答案:

System.out.println(wrongIsMultipleOfUsingDouble(6969696969696969696L, 3L));
// prints `false`, but should be `true`
System.out.println(wrongIsMultipleOfUsingDouble(7777777777777777777L, 2L));
// prints `true`, but should be `false`.
longValue不起作用 显然,由于截断,它不起作用

System.out.println(wrongIsMultipleOfUsingLong(5.0, 2.5));
// prints `false`, but should be `true`     
System.out.println(wrongIsMultipleOfUsingLong(4.5, 2.0));
// prints `true`, but should be `false`.
类型检查仅适用于已知类型。 虽然OP喜欢避免类型检查,但这确实是接近可接受解决方案的唯一方法

static boolean wrongIsMultipleOfUsingTypeChecking(Number a, Number b) {
    // pseudo-code for simplicity
    if (a, b instanceof (AtomicInteger | AtomicLong | Byte | Integer | Long | ...)) {
        return (a.longValue() % b.longValue()) == 0;
    } else if (a, b instanceof (Double | DoubleAccumulator | DoubleAdder | Float) {
        return (a.doubleValue() % b.doubleValue()) == 0;
    } else if (a, b instanceof (BigInteger | BigDecimal)) {
        return a.remainder(b) == ZERO;
    } else {
        throw new RuntimeError("I give up");
    }
}
这在大多数情况下都很好,但它仍然不起作用,因为它不能处理Number的第三方子类,比如

仅限于JSON数字? 现在OP声明使用
Number
,因为数字来自JSON。这些数字通常只有
long
double
,因此类型检查方法就足够了

但是,也支持将数字解释为BigDecimal:

  • Org.JSON已经
  • 格森有
  • Jackson支持
    BigDecimal
    字段
  • JavaEE7的
    javax.json
    (JSR353)具有

BigDecimal同时覆盖了
double
long
的范围,并具有解决OP问题的实际值。如果我们只想使用单个类执行算术,而BigDecimal的价格不被认为是一个大问题,那么这是一个可行的选择。

您不能,不能,不能这样做。放弃试图概括不同类型的
数字
;它真的不是为了能做那样的事情而设计的。每个人都试着去做,但每个人都失败了。不要尝试。使用
数字
可以做的唯一一件事就是在可能的情况下将其转换为原始数字类型,即使这样,您也无法知道是否降低了精度。@LouisWasserman我只使用
数字
,因为我希望能够使用
null
,而原始数字不允许这样做。显然,我需要转换为原语(编译器不允许我这样做),问题是“最简单的方法是什么”,似乎使用
doubleValue
是。这不一定会产生有效的结果
long
值在转换为
double
时会四舍五入,这会弄乱
%
结果。为什么要空值?空数字没有意义。我建议重新设计你的整个程序,这样你就只能用一种类型来表示你的数字。那么?将它们都转换为BigDecimal,并普遍使用。@kennytm添加了一个应该与BigDecimal一起使用的版本。谢谢,我接受它。我不会使用大数字,所以你的第一个选项就可以了。@DarshanMehta不,我说的是数字
a
b
已经是
BigDecimal
,以及
a=newbigdecimal(“3E+1000”)
b=newbigdecimal(“2E+1000”)
。谢谢你深刻的回答。使用
BigDecimal
对我来说可能是一种过度使用,因为我们将使用的数字只有两倍长。但它是教育性的!
System.out.println(wrongIsMultipleOfUsingLong(5.0, 2.5));
// prints `false`, but should be `true`     
System.out.println(wrongIsMultipleOfUsingLong(4.5, 2.0));
// prints `true`, but should be `false`.
static boolean wrongIsMultipleOfUsingTypeChecking(Number a, Number b) {
    // pseudo-code for simplicity
    if (a, b instanceof (AtomicInteger | AtomicLong | Byte | Integer | Long | ...)) {
        return (a.longValue() % b.longValue()) == 0;
    } else if (a, b instanceof (Double | DoubleAccumulator | DoubleAdder | Float) {
        return (a.doubleValue() % b.doubleValue()) == 0;
    } else if (a, b instanceof (BigInteger | BigDecimal)) {
        return a.remainder(b) == ZERO;
    } else {
        throw new RuntimeError("I give up");
    }
}