C++ C++;警告:双精度除以零
案例1:C++ C++;警告:双精度除以零,c++,gcc,floating-point,divide-by-zero,C++,Gcc,Floating Point,Divide By Zero,案例1: #include <iostream> int main() { double d = 15.50; std::cout<<(d/0.0)<<std::endl; } #include <iostream> int main() { if(0 == 0.0) std::cout<<"Same"<<std::endl; else std::cout
#include <iostream>
int main()
{
double d = 15.50;
std::cout<<(d/0.0)<<std::endl;
}
#include <iostream>
int main()
{
if(0 == 0.0)
std::cout<<"Same"<<std::endl;
else
std::cout<<"Not same"<<std::endl;
}
Same
编译器给出以下警告():
输出:
#include <iostream>
int main()
{
double d = 15.50;
std::cout<<(d/0.0)<<std::endl;
}
#include <iostream>
int main()
{
if(0 == 0.0)
std::cout<<"Same"<<std::endl;
else
std::cout<<"Not same"<<std::endl;
}
Same
标准C++中,两种情况都是。任何事情都可能发生,包括格式化硬盘。您不应期望或依赖“返回inf.Ok”或任何其他行为 编译器显然决定在一种情况下给出警告,而不是在另一种情况下,但这并不意味着一个代码是正确的,另一个代码是错误的。这只是编译器生成警告的一个怪癖 从C++17标准[expr.mul]/4: 二进制
/
运算符产生商,二进制%
运算符产生第一个表达式除以第二个表达式的余数如果/
或%
的第二个操作数为零,则行为未定义。
浮点除以零等于零,并给出无穷大(根据分子的值为正或负(或
NaN
表示±0))
对于整数,无法表示无穷大,语言定义了要执行的操作,因此编译器会帮助您避开该路径
然而,在这种情况下,由于分子是一个
double
,除数(0
)也应该被提升为double,并且没有理由在这里给出警告,同时不给出0.0
的警告,所以我认为这是一个编译器错误。我不会在这个答案中进入UB/not UB崩溃
我只想指出,0
和0.0
是不同的,尽管0==0.0
的计算结果为true0
是int
文本,0.0
是double
文本
然而,在这种情况下,最终结果是相同的:d/0
是浮点除法,因为d
是双精度的,因此0
被隐式转换为双精度。我最好的猜测是,在执行int
到double
因此,步骤如下:
/(T,T2)
,其中T=double
,T2=int
std::is_integral::value
是否为true
和b==0
-这会触发警告T2
到double
请注意,这是根据
(顺便说一句,这个标志似乎不能在GCC 8.1中明确使用) -Wdiv由零开始
关于编译时整数除以零的警告。这是默认设置。要禁用警告消息,请使用-Wno div by zero。浮点数 零除法没有被警告,因为它可以是一种合法的计算方法 获得无限和非
浮点零除的行为不同于整数零除
该标准区分+inf和-inf,而整数不能存储无穷大。整数除以零的结果是未定义的行为。浮点除以零是由浮点标准定义的,结果是+inf或-inf。我认为
foo/0
和foo/0.0
是不同的。也就是说,第一个除法(整数除法或浮点除法)的结果在很大程度上取决于foo
的类型,而第二个除法(它将始终是浮点除法)的结果并非如此
这两者中是否有一个是UB无关紧要的。引用标准:
允许的未定义行为范围从完全忽略情况并产生不可预测的结果,到在翻译或程序执行过程中以环境特有的记录方式(无论是否发出诊断消息),再到终止翻译或执行(发出诊断信息)
(强调矿山)
以“”为例警告:告诉编译器您确实想使用赋值结果的方法是显式的,并在赋值周围添加括号。结果语句具有相同的效果,但它告诉编译器您知道自己在做什么。对于
foo/0.0
,也可以这样说:因为您是显式的通过使用0.0
而不是0
告诉编译器“这是浮点除法”,编译器信任您,不会发出警告。这看起来像是一个gcc错误,-Wno div by zero
的文档:
不要警告编译时整数除零。浮点除零没有警告,因为它可以是获取无穷大和非整数的合法方法
在两个操作数中包含的常规算术转换之后,将为双精度:
许多需要算术或枚举类型操作数的二进制运算符会导致转换并产生
以类似的方式创建结果类型。目的是生成一个公共类型,它也是结果的类型。
此模式称为常用算术转换,其定义如下:
-否则,如果任一操作数为双精度,则另一个操作数应转换为双精度。
以及:
*和/的操作数应具有算术或非范围枚举类型;%的操作数应具有整数或非范围枚举类型。
通常对操作数执行算术转换,并确定re的类型