##沒有躲過的坑--意想不到的除數為零
工程中有這樣一個需求,需要獲得一張圖片的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)下產生的異常