2013-11-28 1 views
1

Я caluclating разницу между двумя цветовыми гистограмм, которые являются 3 двумерными массивами:Почему оператор * дал неверный результат и Math.pow() правильно

deltaH является double.

int[][][] t1 = item.getCh(); 
        int[][][] t2 = comparedItem.getCh(); 
        for(int i = 0; i < t1.length; i++) 
         for(int j = 0; j < t1[i].length; j++) 
          for(int p = 0; p < t1[i][j].length; p++) 
           deltaH = deltaH + ((t1[i][j][p] - t2[i][j][p]) * (t1[i][j][p] - t2[i][j][p])); 

В результате этого выше, я получил отрицательные числа, которые математически невозможны. Когда вместо того, чтобы с помощью * я использовал метод Math.pow():

int[][][] t1 = item.getCh(); 
         int[][][] t2 = comparedItem.getCh(); 
         for(int i = 0; i < t1.length; i++) 
          for(int j = 0; j < t1[i].length; j++) 
           for(int p = 0; p < t1[i][j].length; p++) 
            deltaH = deltaH + Math.pow(t1[i][j][p] - t2[i][j][p],2); 

я получил правильные результаты. Почему это так?

+5

Ваши номера не подходят в 'int'. – SLaks

+0

@SLaks Тем не менее мы имеем x * x> = 0, даже если эти числа не имеют смысла. – Yoda

+1

Каков тип 'deltaH'? – Szymon

ответ

4

Когда вы умножаете два int с, вы можете получить переполнение. Функция Math.pow преобразует свой аргумент в двойную сперва - без риска переполнения, приводящего к отрицательным числам, если у вас есть double (хотя вы все равно можете переполнить ... но на гораздо большем количестве).

Это, в сущности, комментарий @Slaks. Я просто расширил его.

EDIT быстрый фрагмент кода показывает, что это правда:

for(ii = 0; ii >= 0; ii++) { 
    jj = ii * ii; 
    if(jj < 0) break; 
} 
System.out.printf("%d; %d\n", ii, jj); 

распечатывает

46341; -2147479015