Как я вынуждаю 0.0/0.0 возвратить нуль вместо NaN в компиляторе C MIPSPro?

Как вопрос указывает, я использую компилятор C MIPSPRo, и я переношу операцию, которая возвратит NaN для некоторых наборов данных, где и числитель и denom являются нулем. Как я мешаю этому происходить?

5
задан sbi 1 April 2010 в 20:54
поделиться

4 ответа

В системах SGI с компилятором MIPSPro вы можете настроить обработку различных исключений с плавающей запятой с большой точностью, используя средства из sigfpe.h . Так случается, что деление нуля на ноль является одним из таких случаев:

#include <stdio.h>
#include <sigfpe.h>

int main (void) {
    float x = 0.0f;
    (void) printf("default %f / %f = %f\n", x, x, (x / x));
    invalidop_results_[_ZERO_DIV_ZERO] = _ZERO;
    handle_sigfpes(_ON, _EN_INVALID, 0, 0, 0);
    (void) printf("handled %f / %f = %f\n", x, x, (x / x));
    return 0;
}

Используется:


arkku@seven:~/test$ cc -version
MIPSpro Compilers: Version 7.3.1.3m
arkku@seven:~/test$ cc -o sigfpe sigfpe.c -lfpe
arkku@seven:~/test$ ./sigfpe
default 0.000000 / 0.000000 = nan0x7ffffe00
handled 0.000000 / 0.000000 = 0.000000

Как видите, установка результата _ZERO_DIV_ZERO изменяет результат того же деления. Точно так же вы можете обрабатывать обычное деление на ноль (например, если вам не нужна бесконечность в результате).

Конечно, все это не является стандартным; было бы более переносимо проверять NaN после каждого деления, а еще лучше проверять наличие нулей перед этим. C99 предлагает некоторый контроль над средой с плавающей запятой в fenv.h , но я не думаю, что для этого есть что-то подходящее. В любом случае мой старый MIPSPro не поддерживает C99.

9
ответ дан 18 December 2019 в 08:27
поделиться

Если вы не возражаете внести небольшую ошибку, вы можете добавить небольшое значение в знаменатель, предполагая, что вы выполняете плавающую точечная арифметика. по-видимому, определено несколько небольших значений:

DBL_MIN - наименьшее двойное значение

DBL_EPSILON - наименьшее двойное значение s.t. x + DBL_EPSILON! = x

Я бы попробовал

#include <float.h>
#define EPS DBL_MIN

double divModified(double num, double denom) {
    return num / (denom + EPS);
}
1
ответ дан 18 December 2019 в 08:27
поделиться

Использовать условие if? Также мне интересно, почему вы хотите игнорировать эту математическую невозможность. Вы уверены, что ваш ввод не является неправильным/бессмысленным в этом случае?

9
ответ дан 18 December 2019 в 08:27
поделиться

IEEE 754 (спецификация для чисел с плавающей запятой) говорит, что 0,0 / 0,0 не является числом, то есть NaN . Если вы хотите, чтобы это было что-то еще, безусловно, лучший подход - определить, когда оба операнда равны нулю в предложении if , и вернуть значение, которое вы бы предпочли дать. Возможно так:

#define WonkyDiv(a,b)  ((a)==0.0&&(b)==0.0 ? 0.0 : (a)/(b))

float wonkyResult = WonkyDiv(numerator, denominator);
0
ответ дан 18 December 2019 в 08:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: