Странные арифметические мувы

Решал одну задачку из ЕГЭ, решил сумму кубов сделать через костыль (a * a * a + b * b * b) Получил неправильный ответ Переписал как (int) (Math.pow(a, 3) + Math.pow(b, 3)) и получил верный ответ То есть весь вопрос в том, почему (a * a * a + b * b * b) != (int) (Math.pow(a, 3) + Math.pow(b, 3))

Пы.Сы. Не вижу смысла приводить весь код, потому что загвоздка именно в этом моменте. Но если нужно - пишите, выложу

Гитхаб с кодом (входные данные в ткст): https://github.com/nikitafront/java/tree/main


Ответы (1 шт):

Автор решения: Stanislav Volodarskiy

Один пример из файла:

public class Temp {
    public static void main(String[] args) {            
        int a = -7112;
        int b = -6737;
        System.out.println("a * a * a = " + a * a * a);
        System.out.println("b * b * b = " + b * b * b);
        System.out.println("a * a * a + b * b * b = " + (a * a * a + b * b * b));
        System.out.println("Math.pow(a, 3) = " + Math.pow(a, 3));
        System.out.println("Math.pow(b, 3) = " + Math.pow(b, 3));
        System.out.println("Math.pow(a, 3) + Math.pow(b, 3) = " + (Math.pow(a, 3) + Math.pow(b, 3)));
        System.out.println("(int)(Math.pow(a, 3) + Math.pow(b, 3)) = " + (int)(Math.pow(a, 3) + Math.pow(b, 3)));
    }
}
$ javac Temp.java && java Temp 
a * a * a = 1048423936
b * b * b = -830679537
a * a * a + b * b * b = 217744399
Math.pow(a, 3) = -3.59728828928E11
Math.pow(b, 3) = -3.05773357553E11
Math.pow(a, 3) + Math.pow(b, 3) = -6.65502186481E11
(int)(Math.pow(a, 3) + Math.pow(b, 3)) = -2147483648

Оба тройных произведения переполняются. Их сумма в виде целого числа положительна (это вопрос везения, знак результата может быть любой).

Обе степени не переполняются, так как считаются в double. Их сумма большое отрицательное число. Особенность приведения double -> int в Java в том что когда double слишком мал, он переводится в минимальное целое значение (-2^31).

То есть, целочисленный вариант выдал положительный мусор, вещественный - отрицательный мусор. Но отрицательный мусор не влияет на результат вашей программы - вы ищете некоторый максимум.

→ Ссылка