Определить деление на ноль как бесконечность - PullRequest
12 голосов
/ 18 июня 2019

Я хочу определить результат деления на ноль как двойной INF.

Есть некоторые обсуждения поведения по умолчанию в C / C ++ для деления на ноль. Ни один вопрос (который я читал) не спрашивает явно, как определить деление на ноль, чтобы оно стало бесконечностью в C. Имеет ли это смысл или нет, я бы не стал обсуждать. Я просто хочу определить его таким образом для одного файла с несколькими функциями C, и мне нужен синтаксис для него.

Ответы [ 2 ]

13 голосов
/ 18 июня 2019

Если вам требуется такое поведение, используйте числа с плавающей запятой, которые могут представлять бесконечность, и обеспечивают желаемое поведение.Обратите внимание, что технически это неопределенное поведение , но на практике большинство компиляторов ( все основные компиляторы для стандартных архитектур) реализуют семантику IEEE 754, например, GCC .

int main() {
    float f = 42;
    float g = f / 0.0f;
    printf("%f\n", g);
}

Вывод:

inf

Это поведение, на которое можно положиться , поскольку оно четко задокументировано компиляторами.Однако при написании переносимого кода убедитесь, что вы проверяете эти предположения внутри своего кода (например, проверяя, определены ли макросы препроцессора __STDC_IEC_559__, , а также макросы для конкретного компилятора ).

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

typedef struct {
    int value;
    bool is_inf;
    bool is_nan;
} ext_int;

ext_int make_ext_int(int i) {
    return (ext_int) {i, false, false};
}

ext_int make_nan() {
    return (ext_int) {0, false, true};
}

ext_int make_inf(int sign) {
    return (ext_int) {(sign > 0) - (sign < 0), true, false};
}

ext_int ext_div(ext_int a, ext_int b) {
    if (a.is_nan || b.is_nan) {
        return  make_nan();
    }
    if (b.value == 0) {
        return make_inf(a.value);
    }
    // TODO: insert other cases.
    return (ext_int) {a.value / b.value, false, false};
}

… в реальной реализации вы бы упаковывали разные флаги, вместо того, чтобы иметь, конечно, отдельный bool для каждого.

8 голосов
/ 18 июня 2019

Деление с плавающей точкой на ноль не определено стандартом C.

(IEEE754 - обычный, но ни в коем случае не повсеместный - определяет a / 0.0 как +INF, если a положительно, -INFесли a отрицательно и NaN, если a также равно нулю).

Лучше всего определить функцию, которая моделирует оператор деления, и реализовать там свое поведение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...