2013-01-03 3 views
20

Почему этот код не выбрасывает ArithmeticException? Посмотрите:Разделение Java на ноль не бросает исключение ArithmeticException - почему?

public class NewClass { 

    public static void main(String[] args) { 
     // TODO code application logic here 
     double tab[] = {1.2, 3.4, 0.0, 5.6}; 

     try { 
      for (int i = 0; i < tab.length; i++) { 
       tab[i] = 1.0/tab[i]; 
      } 
     } catch (ArithmeticException ae) { 
      System.out.println("ArithmeticException occured!"); 
     } 
    } 
} 

Я понятия не имею!

+0

так, как я могу изменить свой код, чтобы получить ArithmeticException? (Я не хочу менять тип массива на int)? – Katie

+3

Это дублируется http://stackoverflow.com/questions/5291606/why-does-1-0-give-error-but-1-0-0-returns-inf – Seba

+2

'если (вкладка [I ] == 0) throw new ArithmeticException(); '. – assylias

ответ

13

Почему вы не можете просто проверить это самостоятельно и выбросить исключение, если это то, что вы хотите.

try { 
     for (int i = 0; i < tab.length; i++) { 
      tab[i] = 1.0/tab[i]; 

      if (tab[i] == Double.POSITIVE_INFINITY || 
        tab[i] == Double.NEGATIVE_INFINITY) 
       throw new ArithmeticException(); 
     } 
    } catch (ArithmeticException ae) { 
     System.out.println("ArithmeticException occured!"); 
    } 
+4

Вам нужно также проверить Double.isNaN(). –

10

0.0 - двойной литерал, и это не считается абсолютным нолем! Никакого исключения, поскольку считается, что двойная переменная достаточно велика, чтобы удерживать значения, представляющие почти бесконечность!

+0

Нет, 0.0 действительно равно 0, а спецификация с плавающей запятой IEEE определяет результат как специальное значение " положительной бесконечности ", а не просто очень большое значение. –

17

Это потому, что вы имеете дело с числами с плавающей запятой. Деление на ноль возвращает Infinity, что похоже на NaN (не число).

Если вы хотите предотвратить это, перед использованием его необходимо проверить tab[i]. Тогда вы можете бросить свое собственное исключение, если оно вам действительно нужно.

51

IEEE 754 определяет 1.0/0.0 как бесконечность и -1.0/0.0, как -Infinity и 0.0/0.0, как NaN.

BTW Плавающая точка также имеет -0.0 и поэтому 1.0/ -0.0 is -Infinity.

Целочисленная арифметика не имеет ни одного из этих значений и вместо этого выбрасывает исключение.

Чтобы проверить все возможные значения, включая NaN, 0.0, -0.0, которые могут производить не конечное число, вы можете сделать следующее.

if (Math.abs(tab[i] = 1/tab[i]) < Double.POSITIVE_INFINITY) 
    throw new ArithmeticException("Not finite"); 
+0

PeterLawrey: так как я могу изменить свой код, чтобы получить исключение ArithmeticException? (Я не хочу менять тип массива на int) – Katie

+2

@Katie вы можете проверить 'if (tab [i] == 0.0) {throw new ArithmeticException();}' before 'tab [i] = 1.0/tab [i]; ' – codeMan

+2

BTW' 0.0 == -0.0', поэтому вам не нужно проверять наличие двух значений. –

5

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

Если вы разделите на 0.0, результатом будет INFINITY.

1

при делении на ноль

  1. Если разделить два раза на 0, JVM покажет бесконечность.

    public static void main(String [] args){ double a=10.00; System.out.println(a/0); } 
    

    консоли: Infinity

  2. Если разделить ИНТ на 0, то JVM бросит Арифметика исключение.

    public static void main(String [] args){ 
        int a=10; 
        System.out.println(a/0); 
    } 
    

    консоли: Exception in thread "main" java.lang.ArithmeticException:/by zero