Java Number或BigInteger和BigDecimal中的Bug(或者在这些API文档中的Bug)?

Java Number或BigInteger和BigDecimal中的Bug(或者在这些API文档中的Bug)?,java,biginteger,bigdecimal,Java,Biginteger,Bigdecimal,根据Number.longValue()的规范,该方法应 以长字符串形式返回指定数字的值。这可能涉及舍入或截断 但是,biginger(和BigDecimal)会覆盖此方法,并返回它所表示的整数部分的64个低位。从biginger的文档中,例如: […]如果此BigInteger太大,无法放入长整数,则只返回低位64位。[…] 我声称“这可能涉及舍入或截断。”没有说明该方法实际应该返回什么,或者,在实现或文档中存在错误 你会同意,还是我的推理有错误 示例代码: import java.math

根据
Number.longValue()
的规范,该方法应

以长字符串形式返回指定数字的值。这可能涉及舍入或截断

但是,
biginger
(和
BigDecimal
)会覆盖此方法,并返回它所表示的整数部分的64个低位。从
biginger
的文档中,例如:

[…]如果此BigInteger太大,无法放入长整数,则只返回低位64位。[…]

我声称“这可能涉及舍入或截断。”没有说明该方法实际应该返回什么,或者,在实现或文档中存在错误

你会同意,还是我的推理有错误


示例代码:

import java.math.BigInteger;
import static java.math.BigInteger.*;

public class Main {
    public static void main(String[] args) {

        BigInteger i = valueOf(Long.MAX_VALUE);

        // Result: Long.MAX_VALUE, just as expected.
        Number n1 = i;
        System.out.println(n1 + " -> " + n1.longValue());

        // I expect to get the "rounded" value Long.MAX_VALUE
        Number n2 = i.add(ONE);
        System.out.println(n2 + " -> " + n2.longValue());

        // I expect to get the "rounded" value Long.MAX_VALUE
        Number n3 = i.multiply(TEN);
        System.out.println(n3 + " -> " + n3.longValue());
    }
}
输出:

9223372036854775807 -> 9223372036854775807
9223372036854775808 -> -9223372036854775808
92233720368547758070 -> -10

biginger.longValue()
的文档包括:

请注意,此转换可能会丢失有关BigInteger值的总体大小的信息,并返回带相反符号的结果

这将重新定义(或澄清)由
Number.longValue()
定义的行为。这很好,尽管有时会产生误导。例如,
java.util.Set
重新定义了
add
方法的行为(通过约束重复项)。如果您传递一个
集合
,您可能希望它包含任何值,但具体的实现已经重新定义了这种行为


更新:我检查了
Long.valueOf(Long.MAX\u VALUE).intValue()的行为。它打印的是-1。所以我假设“舍入或截断”只是一种可能性,关于浮点数。否则,
Number
类将转换方式完全留给实现者。所以是的,它没有告诉任何关于它的事情。我不会说它有那么糟糕,但它肯定是误导性的。

我看不出你的问题,当你试图表示一个超出特定数字类型界限的数字时,这与你得到的垃圾有什么不同

final Number n = Long.MAX_VALUE;
System.out.println(n + " -> " + n.intValue());
印刷品

9223372036854775807 -> -1
您想让API告诉您,如果您传递无效的输入,您将得到无效的输出吗?

的javadocs中出现了“这可能涉及舍入或截断”的措辞,用于其目的是在某些情况下包括重要高阶位的丢失

真正的问题是术语“截断”通常意味着低阶位的丢失。(这就是我在30年前的数值分析课程中对它的记忆

相比之下,描述相同的过程(缩小整型基元类型时)如下所示:

有符号整数到整数类型T的缩小转换只会丢弃除n个最低阶位以外的所有位,其中n是用于表示类型T的位数

所以是的,我同意javadoc是不正确的。提交错误报告

注意


我最初删除了它,因为我认为我提出的提交bug报告的建议可能是徒劳的(基于我过去在文档bug报告方面的经验)。但是@aioobe已经提交了一份bug报告。。。(Bug ID:)

我不同意。
Collection
中的
add
文档明确指出,“支持此操作的集合可能会对可添加到此集合的元素设置限制。特别是,某些集合将拒绝添加空元素,而其他集合将对可添加的元素类型设置限制。”@好的,收集的例子不是最好的。查看我的更新。最重要的是,如果它表示的值大于
Long.MAX\u值,我希望
biginger.longValue
返回
Long.MAX\u值
。或者,我想让
Number.longValue
的文档说“返回一些long,表示这个值”,也许它应该说“这可能涉及舍入或二进制截断”我从来没有听说过“二进制截断”这个术语。你有这方面的证明人吗?(顺便说一句,我不想从描述中删除普通的截断,因为所有浮点
数字都使用这种方式)我用二进制截断得到的是被删除的低位64位左边的任何东西。是的,小数可以是四舍五入的,也可以是数字截断的,但您希望发生的是统计截断()。我可能会说,“以长的形式返回指定数字的值”捕获发生的情况,从65位开始,只使用最左边的64位。