Java-вычисление с целыми и длинными значениями возвращает разные значения с круглыми скобками или без них. Зачем? - PullRequest
0 голосов
/ 08 марта 2019

Это простой пример проблемы:

public class IntVsLong {

    public static void main(String[] args) {
        int a = 3;
        int b = 3;
        long n = 549382313570L;
        String s = "epsxyyflvrrrxzvnoenvpegvuonodjoxfwdmcvwctmekpsnamchznsoxaklzjgrqruyzavshfbmuhdwwmpbkwcuomqhiyvuztwvq";

        System.out.println(a * n/s.length() + b); //returns 16481469410
        System.out.println(a * (n/s.length()) + b); //returns 16481469408
    }

}

Первая ситуация без скобок возвращает 16481469410. Вторая ситуация с круглыми скобками возвращает 16481469408. Почему?

Ответы [ 2 ]

5 голосов
/ 08 марта 2019

Это потому, что порядок оценки другой, а целочисленная математика округляется.Для примера с меньшими числами, чтобы показать точку.

3 * (5 / 2) = 3 * (2) = 6

без скобок

3 * 5 / 2 = 15 / 2 = 7

операции оцениваются слева направо без скобок, и когда вы достигнете оператора деления, вы потеряетенекоторая информация, потому что целые числа не могут содержать дробные числа.Чем раньше вы потеряете эту информацию в целом , тем менее точным будет ваш окончательный результат.

1 голос
/ 08 марта 2019

Если оба операнда имеют целочисленный тип, в Java оператор / представляет целочисленное деление, то есть напоминание о делении отбрасывается. В вашем случае разница между результатами равна 2, что означает, что напоминание о n/s.length() операции больше, чем 2 / a и, очевидно, меньше 1. Так что в случае a * n/s.length() это напоминание умножается на a и дает вам это превышение 2 в ответ.

...