c - existe - limites no infinito definição




Definir divisão por zero como infinito (2)

Eu quero definir o resultado da divisão por zero como o INF duplo.

Existem algumas discussões sobre o comportamento padrão em C / C ++ para divisão por zero. Nenhuma pergunta (que eu li) pergunta explicitamente como definir a divisão por zero para se tornar infinito em C. Se isso faz sentido ou não, prefiro não discutir. Eu só quero defini-lo dessa maneira para um arquivo com várias funções C nele e precisar da sintaxe dele.


A divisão do ponto flutuante por zero é indefinida pelo padrão C.

(IEEE754 - comum mas não omnipresente - define a / 0.0 para ser +INF se a for positivo, -INF se a for negativo e NaN se a for também zero).

Sua melhor aposta é definir uma função que modela o operador de divisão e implementar seu comportamento ali.


Se você precisar desse comportamento, use números de ponto flutuante, que podem representar o infinito e fornecer o comportamento desejado. Note que tecnicamente isso é um comportamento indefinido, mas na prática a maioria dos compiladores ( todos os compiladores mainstream para arquiteturas padrão) implementam a semântica do IEEE 754, por exemplo, GCC .

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

Saída:

inf

Esse é um comportamento que pode ser invocado desde que seja claramente documentado pelos compiladores. No entanto, ao escrever código portátil, certifique-se de testar essas suposições dentro de seu código (por exemplo, testando se a macro de pré-processamento __STDC_IEC_559__ , bem como as macros específicas do compilador estão definidas).

Se, por algum motivo, você precisar desse comportamento para valores inteiros, o único recurso é criar seu próprio tipo. Algo assim:

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};
}

… Em uma implementação real, você empacotaria as diferentes bandeiras em vez de ter um bool separado para cada uma, é claro.





c