關(guān)于C語言除0引發(fā)的思考
<SPAN style="BACKGROUND-COLOR: rgb(241,254,221)">
<SPAN style="FONT-FAMILY: Microsoft YaHei">
進(jìn)行浮點(diǎn)數(shù)編程時(shí),如果沒有注意,常常會(huì)出現(xiàn)輸出類似 1.#IND, 1.#INF 或者 nan, inf 之類奇怪的輸出。這通常隱含了浮點(diǎn)數(shù)操作的異常。
</SPAN></SPAN>
進(jìn)行整數(shù)除0的時(shí)候,程序會(huì)檢查出一個(gè)錯(cuò)誤,比如對(duì)于這個(gè)代碼:
#include <stdio.h>
#include <math.h>
int main()
{
int m;
m=1/0;
printf("%d",m);
return 0;
}
運(yùn)行完以后程序就會(huì)警告:warning: division by zero [-Wdiv-by-zero]
但是對(duì)于浮點(diǎn)數(shù),就沒有類似的檢查:
#include <stdio.h>
#include <math.h>
int main()
{
double m;
m=1.0/0.0;
printf("%lf",m);
return 0;
}
不會(huì)有警告或者報(bào)錯(cuò),但是運(yùn)行完以后會(huì)出現(xiàn)這樣的值:-1.#IND00,不知所云。于是上網(wǎng)查了一下,原來是這樣!
特殊浮點(diǎn)數(shù)的含義
1.#INF / inf:這個(gè)值表示“無窮大 (infinity 的縮寫)”,即超出了計(jì)算機(jī)可以表示的浮點(diǎn)數(shù)的最大范圍(或者說超過了 double 類型的最大值)。
例如,當(dāng)用 0 除一個(gè)整數(shù)時(shí)便會(huì)得到一個(gè)1.#INF / inf值;相應(yīng)的,如果用 0 除一個(gè)負(fù)整數(shù)也會(huì)得到 -1.#INF / -inf 值。 -1.#IND / nan:這個(gè)的情況更復(fù)雜,一般來說,它們來自于任何未定義結(jié)果(非法)的浮點(diǎn)數(shù)運(yùn)算。"IND"是 indeterminate 的縮寫,而"nan"是 not a number 的縮寫。產(chǎn)生這個(gè)值的常見例子有:對(duì)負(fù)數(shù)開平方,對(duì)負(fù)數(shù)取對(duì)數(shù),0.0/0.0,0.0*∞, ∞/∞ 等。 簡(jiǎn)而言之,如果遇到 1.#INF / inf,就檢查是否發(fā)生了運(yùn)算結(jié)果溢出除零,而遇到 1.#IND / nan,就檢查是否發(fā)生了非法的運(yùn)算。
特殊浮點(diǎn)數(shù)的判斷
很多 C 庫都提供了一組函數(shù)用來判斷一個(gè)浮點(diǎn)數(shù)是否是無窮大或 NaN。int _isnan(double x) 函數(shù)用來判斷一個(gè)浮點(diǎn)數(shù)是否是 NaN,而 int _finite(double x) 用以判斷一個(gè)浮點(diǎn)數(shù)是否是無窮大。
你可能已經(jīng)注意到了,上面兩個(gè)函數(shù)都是以下劃線開頭的,因此在可移植性上可能是存在問題的,那么如何實(shí)現(xiàn)一個(gè)通用的判斷版本呢?
首先,對(duì)于 Nan,可以用下面的代碼實(shí)現(xiàn):
bool IsNumber(double x)
{
// 這里的比較操作看上去總是會(huì)得到 true
// 但有趣的是對(duì)于 IEEE 754 浮點(diǎn)數(shù) NaN 來說總會(huì)得到 false!
return (x == x);
}
而下面的代碼可以判斷一個(gè)浮點(diǎn)數(shù)是否是有限的(finite, 即既不是 NaN 又不是 infinite):
bool IsFiniteNumber(double x)
{
return (x <= DBL_MAX && x >= -DBL_MAX);
}
其中,DBL_MAX 是 <float.h> 中預(yù)定義的常量。
把上面兩個(gè)函數(shù)結(jié)合起來,還可以實(shí)現(xiàn)一個(gè)浮點(diǎn)數(shù)是否是 Inf 的判斷。
相關(guān)文章
vscode使用官方C/C++插件無法進(jìn)行代碼格式化問題
這篇文章主要介紹了vscode使用官方C/C++插件無法進(jìn)行代碼格式化問題,本文通過截圖實(shí)例代碼相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04
C++實(shí)現(xiàn)二分法求連續(xù)一元函數(shù)根
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)二分法求連續(xù)一元函數(shù)根,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-06-06
VC++ 使用 _access函數(shù)判斷文件或文件夾是否存在
這篇文章主要介紹了VC++ 使用 _access函數(shù)判斷文件或文件夾是否存在的相關(guān)資料,需要的朋友可以參考下2015-10-10
VC++簡(jiǎn)單實(shí)現(xiàn)關(guān)機(jī)、重啟計(jì)算機(jī)實(shí)例代碼
這篇文章主要介紹了VC++簡(jiǎn)單實(shí)現(xiàn)關(guān)機(jī)、重啟計(jì)算機(jī)實(shí)例代碼,很實(shí)用的功能,需要的朋友可以參考下2014-07-07
C++ 項(xiàng)目引入lib和dll的區(qū)別與使用實(shí)戰(zhàn)
靜態(tài)鏈接庫與動(dòng)態(tài)鏈接庫都是共享代碼的方式,本文主要介紹了C++項(xiàng)目引入lib和dll的區(qū)別與使用實(shí)戰(zhàn),具有一定的參考價(jià)值,感興趣的可以了解一下2024-02-02
Java?C++?算法題解leetcode145商品折扣后最終價(jià)格單調(diào)棧
這篇文章主要介紹了Java?C++?算法題解leetcode145商品折扣后最終價(jià)格單調(diào)棧示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
詳解計(jì)數(shù)排序算法及C語言程序中的實(shí)現(xiàn)
技術(shù)排序算法與我們普通接觸的冒泡排序和快速排序等基于元素比較的算法不同,在編程中通過C語言的數(shù)組能夠清除地表達(dá)出來,這里我們就來詳解計(jì)數(shù)排序算法及C語言程序中的實(shí)現(xiàn)2016-07-07
OpenCV+Qt實(shí)現(xiàn)圖像處理操作工具的示例代碼
這篇文章主要介紹了利用OpenCV+Qt實(shí)現(xiàn)圖像處理操作工具,可以實(shí)現(xiàn)雪花屏、高斯模糊、中值濾波、毛玻璃等操作,感興趣的可以了解一下2022-08-08

