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

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


person Xavier    schedule 13.02.2011    source источник
comment
Похоже, вам нужен сигнальный NaN (SNaN), но я подозреваю, что это невозможно.   -  person Gabe    schedule 13.02.2011


Ответы (2)


В справочнике по набору инструкций 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

person templatetypedef    schedule 13.02.2011

Защита в float или double заключается в том, чтобы сделать результат 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);

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

person Peter Lawrey    schedule 13.02.2011
comment
Мне нравится эта идея, но как насчет умножения бесконечности на ноль? Вы бы сделали то же самое во время умножения? - person templatetypedef; 13.02.2011