2

Number.longValue()メソッドの仕様によると...

指定された数値の値を long として返します。これには、丸めまたは切り捨てが含まれる場合があります。

ただし、BigInteger(and BigDecimal) はこのメソッドをオーバーライドし、それが表す数値の整数部分の下位 64 ビットを返します。BigIntegerたとえば、ドキュメントから:

[...]この BigInteger が大きすぎて long に収まらない場合、下位 64 ビットのみが返されます。[...]

This may include rounding or truncation. 」は、メソッドが実際に何を返す必要があるかについて何も述べていないか、実装またはドキュメントにバグがあると主張します。

あなたは同意しますか、それとも私の推論に誤りがありますか?


コード例:

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
4

3 に答える 3

4

のドキュメントは次のようにBigInteger.longValue()続きます。

この変換により、BigInteger 値の全体的な大きさに関する情報が失われ、反対の符号の結果が返される可能性があることに注意してください。

これにより、 によって定義された動作が再定義 (または明確化) されNumber.longValue()ます。誤解を招くこともありますが、これで問題ありません。たとえばjava.util.Set、メソッドの動作を再定義しますadd(重複を制限することにより)。a を渡すと、Collection任意の値が保持されると予想される場合がありますが、具体的な実装ではこの動作が再定義されています。

更新:の動作を確認しLong.valueOf(Long.MAX_VALUE).intValue()ました。そして、-1 を出力します。したがって、浮動小数点数に関しては、「丸めまたは切り捨て」による可能性があると思います。それ以外の場合、Numberクラスは変換の方法を完全に実装者に任せます。そうです-それについては何も言いません。それが悪いとは言いませんが、誤解を招きやすいのは確かです。

于 2010-11-17T12:16:37.577 に答える
2

あなたの質問がわかりません。これは、特定の数値型の範囲外の数値を表現しようとするたびに得られるガベージとどのように違うのですか?

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

版画

9223372036854775807 -> -1

無効な入力を渡すと無効な出力が得られることを API に通知させたいですか?

于 2010-11-17T12:18:30.777 に答える
1

「これには、丸めまたは切り捨てが含まれる可能性があります」という文言が、、、およびのjavadoc に表示されるため、longValue()場合によっては「切り捨て」が重要な上位ビットの損失を含むことを意図していることは明らかです。shortValue()charValue()byteValue()Number

問題は、「切り捨て」という用語が慣習的に下位ビットの損失を意味することです。(30 年前の数値解析コースでの記憶です。ウィキペディアも同意しています。)

対照的に、JLS 5.1.3では、同じプロセス (整数プリミティブ型を絞り込む場合) が次のように説明されています。

符号付き整数から整数型 T への縮小変換では、下位 n ビットを除くすべてのビットが単純に破棄されます。ここで、n は型 T を表すために使用されるビット数です。

はい、javadoc が間違っていることに同意します。バグレポートを提出してください。

ノート

バグレポートを提出するという私の提案はおそらく無駄だと思ったので、私は最初にこれを削除しました (ドキュメントのバグレポートに関する私の過去の経験に基づいて)。しかし、@aioobeバグレポートを提出しました... (バグ ID: 7000825 )

于 2010-11-17T13:37:49.177 に答える