Некоторые вопросы оператора Java по модулю/остатку

Я играл с некоторыми большими значениями с Java, и я столкнулся с чем-то, чего не понимаю. По какой-то причине Java, похоже, любит давать мне ложные данные (хотя гораздо более вероятно, что я говорю ей давать мне ложные данные)

Вот фрагмент, отредактированный для ясности:

        System.out.println(
                "2 == " + (Math.pow(51, 13) % (77))
        );

Что, согласно как Wolfram Alpha (см. ссылку ниже), так и остальному моему алгоритму, неверно.

(Выход:)

  2 == 70.0

http://www.wolframalpha.com/input/?i=51%5E13%20mod%2077

Есть идеи?


person paultag    schedule 21.07.2011    source источник


Ответы (1)


Я считаю, что это из-за проблемы с точностью. doubles являются точными только до 15 или около того цифр. Math.pow(51,13) — это огромное число (~ 20 цифр), поэтому, когда вы попытаетесь изменить его на 77, у вас будут числовые ошибки.

Для арифметики с произвольной точностью взгляните на BigInteger и BigDecimal.

person tskuzzy    schedule 21.07.2011
comment
Я тоже так думал, но у double MAX_VALUE равно (2-2 ^ 52) · 2 ^ 1023, что, я думаю, больше, чем мое число. Мысли? - person paultag; 21.07.2011
comment
Дело не в дальности, а в точности. Так, например, вместо того, чтобы хранить число 0,12345678987654321, double может урезать его до 0,123456789. Точно так же для больших чисел 12345678987654321 может быть усечено до 12345678900000000. Очевидно, что это искажает точность последующего мода. - person tskuzzy; 21.07.2011
comment
Это звучит совершенно здраво. Спасибо! - person paultag; 21.07.2011