在使用 float 以外的其他类型进行编码时,是否应该使用“>=”而不是“==”来更加安全?
Should you use '>=' instead of '==' to be extra safe when coding with other types than float?
使用浮点数时应该使用
a <= 0.0
而不是
a == 0.0
以确保您获得所需的行为,因为在使用浮点变量时 round-off errors 存在问题。
但是当使用像 int
这样的其他变量类型时,这样做是否有用?就像你有一个 for 循环遍历 int
变量(如索引),当它到达一个数字时它应该做一些事情。当它应该产生相同的输出时,您是否应该将比较设置为 >=
而不是 ==
?就像在以下情况下可能不会评估 ==
的情况一样:
for (int i = 0; i < 10; i++)
{
if (i == 5)
{
break;
}
}
并且 "safer" 改为执行以下操作:
for (int i = 0; i < 10; i++)
{
if (i >= 5)
{
break;
}
}
如果在编码方面两者之间没有区别 "safe" 是否存在任何性能或可读性差异或其他可以让人们在编码方式之间做出选择的因素?
试图 google 这个,但找不到任何说明。但这可能与搜索运算符的问题有关。
我是不是太偏执了才会问这个?
答案是,这取决于。如果你有这样的循环:
for (int i = 0; i < 10; i++)
{
if (i == 5)
{
break;
}
}
那么 i
跳过 5
就没有危险了。
另一方面,如果您有这样的事情:
volatile int i;
void interrupt(void)
{
i++;
}
void foo(void)
{
for (i = 0; i < 10; i++)
{
if (i == 5)
{
break;
}
}
}
然后 i
可能会在程序的正常流程之外发生变化(例如,由于中断)。在这种情况下 >=
是谨慎的。
题目前提错误;盲目地使用 a <= 0.0
而不是 a == 0.0
不是浮点数的有效做法。有关主题的处理,请参阅 How dangerous is it to compare floating point values?。
尽管如此,在某些情况下,使用不等式关系运算符 "more hardened" 比使用相等运算符 反之亦然 。一般来说,我建议不要这样做,因为它可能会给你一种 错误的安全感;例如,在您使用 i==5
vs i>=5
的问题示例中,编译器可能能够证明它们是相同的,并在需要时针对另一个进行优化。这意味着它不一定会采取任何措施来保护您免受堆栈溢出或中微子或任何其他原因的影响,这些原因 i
的值可能会在语言定义的语义之外变为 0..5 以外的值。
也有一些情况下,不等式的使用不是由不等式定义的,尤其是涉及指针的情况。如果 pos
和 end
都是指针,那么只要它们都有效,pos==end
就是定义良好的。但是如果它们都是空的,而 pos==end
是明确定义的并且是真的,pos>=end
是未定义的行为。同样,如果它们都指向不同的数组(特别是如果 end
指向一个不属于您的数组的哨兵),pos==end
将始终为 false,但 pos>=end
是未定义的行为。
我还发现当你知道 i>5
在逻辑上是不可能的时候写 if (i>=5)
是一种误导——它让 reader 停下来思考它是否可能,如果不可能,为什么你是这样写的,而不是 if (i==5)
.
Like could there ever be a case where the == is not evaluated
不,使用 ==
是安全的。整数表示准确使用的整数类型范围内的所有值。没有惊喜。
Should you then set the comparison to be >= instead of ==
由于结果相同,您可以两者都做,但我会发现 >=
令人困惑。所以为了可读性,我更喜欢 ==
is there any performance . . . that can make one choose between the ways to code
你不能通过查看 C 代码来判断。这取决于所使用的系统 (CPU)。不过,总的来说,我怀疑您是否会体验到任何重大差异。
使用浮点数时应该使用
a <= 0.0
而不是
a == 0.0
以确保您获得所需的行为,因为在使用浮点变量时 round-off errors 存在问题。
但是当使用像 int
这样的其他变量类型时,这样做是否有用?就像你有一个 for 循环遍历 int
变量(如索引),当它到达一个数字时它应该做一些事情。当它应该产生相同的输出时,您是否应该将比较设置为 >=
而不是 ==
?就像在以下情况下可能不会评估 ==
的情况一样:
for (int i = 0; i < 10; i++)
{
if (i == 5)
{
break;
}
}
并且 "safer" 改为执行以下操作:
for (int i = 0; i < 10; i++)
{
if (i >= 5)
{
break;
}
}
如果在编码方面两者之间没有区别 "safe" 是否存在任何性能或可读性差异或其他可以让人们在编码方式之间做出选择的因素?
试图 google 这个,但找不到任何说明。但这可能与搜索运算符的问题有关。
我是不是太偏执了才会问这个?
答案是,这取决于。如果你有这样的循环:
for (int i = 0; i < 10; i++)
{
if (i == 5)
{
break;
}
}
那么 i
跳过 5
就没有危险了。
另一方面,如果您有这样的事情:
volatile int i;
void interrupt(void)
{
i++;
}
void foo(void)
{
for (i = 0; i < 10; i++)
{
if (i == 5)
{
break;
}
}
}
然后 i
可能会在程序的正常流程之外发生变化(例如,由于中断)。在这种情况下 >=
是谨慎的。
题目前提错误;盲目地使用 a <= 0.0
而不是 a == 0.0
不是浮点数的有效做法。有关主题的处理,请参阅 How dangerous is it to compare floating point values?。
尽管如此,在某些情况下,使用不等式关系运算符 "more hardened" 比使用相等运算符 反之亦然 。一般来说,我建议不要这样做,因为它可能会给你一种 错误的安全感;例如,在您使用 i==5
vs i>=5
的问题示例中,编译器可能能够证明它们是相同的,并在需要时针对另一个进行优化。这意味着它不一定会采取任何措施来保护您免受堆栈溢出或中微子或任何其他原因的影响,这些原因 i
的值可能会在语言定义的语义之外变为 0..5 以外的值。
也有一些情况下,不等式的使用不是由不等式定义的,尤其是涉及指针的情况。如果 pos
和 end
都是指针,那么只要它们都有效,pos==end
就是定义良好的。但是如果它们都是空的,而 pos==end
是明确定义的并且是真的,pos>=end
是未定义的行为。同样,如果它们都指向不同的数组(特别是如果 end
指向一个不属于您的数组的哨兵),pos==end
将始终为 false,但 pos>=end
是未定义的行为。
我还发现当你知道 i>5
在逻辑上是不可能的时候写 if (i>=5)
是一种误导——它让 reader 停下来思考它是否可能,如果不可能,为什么你是这样写的,而不是 if (i==5)
.
Like could there ever be a case where the == is not evaluated
不,使用 ==
是安全的。整数表示准确使用的整数类型范围内的所有值。没有惊喜。
Should you then set the comparison to be >= instead of ==
由于结果相同,您可以两者都做,但我会发现 >=
令人困惑。所以为了可读性,我更喜欢 ==
is there any performance . . . that can make one choose between the ways to code
你不能通过查看 C 代码来判断。这取决于所使用的系统 (CPU)。不过,总的来说,我怀疑您是否会体验到任何重大差异。