##没有躲过的坑--意想不到的除数为零
工程中有这样一个需求,需要获得一张图片的width和height,然后等比例的显示这张图片。
首先是获得得到一张图片的路径,然后计算出他的width和height,然后计算:
~~~
int resize_width = 160;
int resize_height = 160;
if (image_width > image_height) {
resize_width = 160;
resize_height = 160 * image_height / image_width;
}
else {
resize_height = 160;
resize_width = 160 * image_width / image_height;
}
~~~
很多情况下 ,我们都可以如愿以偿。
但是情况总有特俗,这就看你是如何计算一张图片的width和height的了,之前Google过一个方法只能计算24k大小以上的图片。
当图片过大或是过小,我们使用的方法无法计算这张图片的width和height时,情况出现了。
我们从小就知道除法中除数不能为零,但是在编程过程中往往忽略这一点。加之测试不够,往往会挖下一个很大的坑儿。
因此修改上面的代码:
~~~
int resize_width = 0;
int resize_height = 0;
if (image_width == 0 || image_height == 0)
{
resize_width = 160;
resize_height = 160;
}
else
{
if (image_width > image_height) {
resize_width = 160;
resize_height = 160 * image_height / image_width;
}
else {
resize_height = 160;
resize_width = 160 * image_width / image_height;
}
}
~~~
对width和height是否为零进行判断。
说道除法,那就继续写点。
C++中的大多数二元操作都要求两个操作数是同一类型。如果操作数的不同类型,其中一个操作数会提升到和另一个操作数相匹配的类型。在C++中,除法操作符可以被看做是2个不同的操作:其中一个操作于整数之上,另一个是操作于浮点数之上。如果操作数是浮点数类型,除法操作将返回一个浮点数的值:
~~~
float fX = 7;
float fY = 2;
float fValue = fX / fY;
// fValue = 3.5
~~~
如果操作数是整数类型,除法操作将丢弃任何小数部分,并只返回整数部分。
~~~
int nX = 7;
int nY = 2;
int nValue = nX / nY;
// nValue = 3
~~~
如果一个操作数是整型,另一个操作数是浮点型,则整型会提升为浮点型:
~~~
float fX = 7.0;
int nY = 2;
float fValue = fX / nY;
// nY 提升为浮点型,除法操作将返回浮点型值
// fValue = 3.5
~~~
有很多人会想当然:
~~~
int nX = 7;
int nY = 2;
float fValue = nX / nY;
// fValue = 3(不是3.5哦!)
~~~
这里的本意是nX/nY将产生一个浮点型的除法操作,因为结果是赋给一个浮点型变量的。但实际上并非如此。nX/nY首先被计算,结果是一个整型值,然后才会提升为浮点型并赋值给fValue。但在赋值之前,小数部分就已经丢弃了。
要强制两个整数采用浮点型除法,其中一个操作数需要类型转换为浮点数:
~~~
int nX = 7;
int nY = 2;
float fValue = static_cast<float>(nX) / nY;
// fValue = 3.5
~~~
因为nX显式的转换为float型,nY将隐式地提升为float型,因此除法操作符将执行浮点型除法,得到的结果就是3.5。
有关整数除法的另一个有趣的事情是,当一个操作数是负数时C++标准并未规定如何截断结果。造成的结果就是,编译器可以自由地选择向上截断或者向下截断!比如,-5/2可以既可以计算为-3也可以计算为-2,这和编译器是向下取整还是向0取整有关。大多数现代的编译器是向0取整的。
- 前言
- deprecated关键字
- 指针(内存泄露)
- 头文件相互包含(Compiler error C2653: not a class or namespace name)
- 获取一张图片的width和height
- This function or variable may be unsafe.
- 智能指针陷阱
- wstring与string的转换
- windows下chrome浏览器插件不能安装
- 重定义关键字
- 正确释放vector的内存
- 获取设备环境HDC
- 抽象类不能实例化对象(但是你明明定义的不是抽象类)
- 重载赋值运算符的自我赋值
- 程序中的变量未初始化
- 成对使用new和delete时要采取相同的形式
- 意想不到的除数为零
- map的初始化(插入数据)
- 正则表达式截取字符串
- 捕获窗口之外的鼠标消息(钩子还是??)
- 类中的静态成员变量(static or const static)
- 有if就要有else(一定成对)
- map查找结果处理
- 使用using namespace std的坏习惯
- new一个指针数组、以及创建动态二维数组
- 使用太多的全局变量
- 没有及时break出for循环
- vector使用erase后迭代器变成野指针
- C++函数的默认参数(重新定义默认参数)
- 0xC0000005: 读取位置 xxx时发生访问冲突
- std::string初始化、最快速判断字符串为空
- 你开发的软件安装在C盘Program Files (x86)下产生的异常