C 将零除定义为无穷大

C 将零除定义为无穷大,c,C,我想将被零除的结果定义为double INF 有一些关于C/C++中被零除的默认行为的讨论。(我读过的)没有问题明确地问如何定义C中的零除为无穷大。这是否有意义,我不想讨论。我只想用这种方式为一个包含多个C函数的文件定义它,并需要它的语法。如果需要这种行为,请使用浮点数,它可以表示无穷大,并提供所需的行为。请注意,技术上这是未定义的行为,但实际上大多数编译器(标准体系结构的所有主流编译器)都实现IEEE 754语义,例如 输出: inf 这是可以依赖的行为,因为编译器已经清楚地记录了它。但是,

我想将被零除的结果定义为double INF


有一些关于C/C++中被零除的默认行为的讨论。(我读过的)没有问题明确地问如何定义C中的零除为无穷大。这是否有意义,我不想讨论。我只想用这种方式为一个包含多个C函数的文件定义它,并需要它的语法。

如果需要这种行为,请使用浮点数,它可以表示无穷大,并提供所需的行为。请注意,技术上这是未定义的行为,但实际上大多数编译器(标准体系结构的所有主流编译器)都实现IEEE 754语义,例如

输出:

inf
这是可以依赖的行为,因为编译器已经清楚地记录了它。但是,在编写可移植代码时,请确保在代码中测试这些假设(例如,通过测试是否定义了预处理器宏
\uu STDC\u IEC\u 559\uu

如果出于某种原因,您需要整数值的这种行为,唯一的办法就是创建您自己的类型。大概是这样的:

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};
}
typedef结构{
int值;
bool是inf;
布尔是乌南;
}外联;
外接内接外接内接(内接一){
返回(ext_int){i,false,false};
}
ext_int make_nan(){
返回(ext_int){0,false,true};
}
ext\U int make\U inf(整数符号){
返回(ext_int){(符号>0)-(符号<0),真,假};
}
分机分机(分机a、分机b){
如果(a.is|nan | b.is|nan){
返回make_nan();
}
如果(b.value==0){
返回make_inf(a.value);
}
//TODO:插入其他案例。
返回(ext_int){a.value/b.value,false,false};
}

…在实际的实现中,您需要打包不同的标志,而不是为每个标志单独设置一个
bool

浮点除零是C标准未定义的

(IEEE754——常见但并非无处不在——将
a/0.0
定义为
+INF
如果
a
为正,
-INF
如果
a
为负,
NaN
如果
a
也为零)


最好的办法是定义一个模拟除法运算符的函数,并在那里实现您的行为。

表面上看,这听起来不可能,但可能取决于您的控制级别。例如:能否用函数调用替换所有除法运算?简言之,你试过什么?:)浮点除零已经导致
INF
。如果你想用同样的方法定义整数,你必须打破这个标准,因为整数除法会产生一个整数,而这个整数不能表示
INF
。在除法之前捕捉一个零除数可能更容易处理整数除法。另一种方法是设置恢复机制。如果代码试图避免
-1.0/0.0
成为
-INF
?听起来你也希望它是
+INF
。根据标准,浮点除零仍然是未定义的行为,尽管IEEE754确实以正分子的方式定义了它。
if(b.is|nan | b.is|INF){return make|nan()
看起来是错误的。你想要
if(a.is|nan | b.is|nan){…
?代码也需要更多的案例。UB代表
a=INT\u MIN,b=-1
。@chux这是一个非常快速的编写,测试有限。其目的显然不是生产代码(太长了)但是,这只是一个例子。也就是说,条件的目的是确保
x/inf
返回
NaN
。你是对的,那是错的。根据需要,你不一定需要自己的新结构,只需要自定义函数。
INT\u MIN
INT\u MAX
相对很少使用;它说“好吧,现在这些都是无穷大”不是不合理的。出于好奇,你能想到任何一个编译器,它有一个无穷大的浮点值,但不计算1/0。它是无穷大吗?虽然它是正式的UB,但似乎无穷大值的存在强烈暗示着1/0=inf。
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};
}