Могу ли я заставить Java выдавать исключение при выполнении сравнения между числами с плавающей запятой, когда один из них оказывается NaN? - PullRequest
5 голосов
/ 13 февраля 2011

Я потратил около 2 часов на отслеживание ошибки сегодня, и я обнаружил бы, что гораздо быстрее, если бы java выдал исключение при сравнении NaN с плавающей точкой.Было бы хорошо, если бы я мог защитить себя от этого в будущем.Любая помощь приветствуется.

Ответы [ 2 ]

5 голосов
/ 13 февраля 2011

Ссылка на набор команд JVM специально запрещает байтовым кодам, которые выполняют математические операции с плавающей запятой, генерировать исключения и жестко указывает, как они должны работать, когда NaN является операндом.Если есть способ сделать это, вам потребуется либо явным образом генерировать исключения для NaN, либо использовать собственный компилятор для вставки этих проверок.

Один из вариантов, который может быть полезен, - это написатьфункция как это:

public static float check(float value) {
    if (Float.isNaN(value))
        throw new ArithmeticException("NaN");
    return value;
}

С этим вы можете написать код для этого эффекта:

float f = check(myOtherFloat / yetAnotherFloat);

Это тогда сделает вычисление и выдаст ошибку.В идеале с коротким именем функции оно не будет слишком навязчивым.

W

2 голосов
/ 13 февраля 2011

Защита с плавающей запятой или двойной должна сделать результат NaN или false.Если вы хотите обнаружить NaN, вам лучше не указывать значение, например 0/0.Когда вы делаете деление, отметьте 0 как делитель и скажите исключение, если оно есть.Вы можете обернуть это вспомогательным методом, чтобы упростить.

public static double div(double a, double b) {
    if(b == 0) throw new IllegalArguementException();
    return a / b;
}

Если я знаю, что значение может быть только 0 или больше, я часто добавляю смещение типа

double d = a / (b + 1e-9);

Это никогда не приводитЕсли Na = b> = 0. Если a == 0, d == 0. Предвзятое смещение зависит от ситуации.

...