ThinkSSL🔒 一键申购 5分钟快速签发 30天无理由退款 购买更放心 广告
##没有躲过的坑--意想不到的除数为零 工程中有这样一个需求,需要获得一张图片的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取整的。