1. 判斷一個數是否是“整型”,調用系統函數
#include <iostream>
#include <typeinfo>
using namespace std;
int main()
{
double i=3;
cout << typeid(i).name() << endl;
cout << typeid(3.0000).name() << endl;
system("pause") ;
return 0 ;
}
判斷一個數是否是“整數”(不能用類型來判斷,因為4.000也是整數)自定義函數來判斷:
方法:float型的數都有些偏差,比如4.000,完完全全的4.000是很難在浮點數的運算中得到的,但是當我們可以鍵盤輸入4.000時,它一定就等於4,沒有絲毫偏差。假如我們寫成:scanf("%lf",&n),並輸入4.000,此時判斷的結果應該是YES,輸入4.001則輸出NO。
一般人想到的辦法是:if ( n - int(n) == 0 )
這種做法是錯的,因為左邊是double型,右邊的0是整形,不能這樣比較的,即使改成0.00也是錯的,因為浮點數有一定誤差,4可能成了4.00…01,也可能成了3.99…99,那麼4 - int(4)就可能成了0.00…01或者-0.99…99,為了避免這種情況,必須允許和0存在一定的誤差,誤差范圍與數據類型相關,雙精度(double型)一般為1e-15,但精度(float型)一般為1e-6,所以應該寫成
if(n>=0)
if( (n-(int)n) < 1e-15 || (n-(int)n) < -0.999999999999999 )
//單精度對應1e-6和6個9,雙精度對應1e-15和15個9
printf("YES\n");
else
printf("NO\n");
else
if( -(n-(int)n) < 1e-15 || -(n-(int)n) < -0.999999999999999 )
printf("YES\n");
else
printf("NO\n");
當n >= 0時,那麼只要(n-(int)n) < 1e-15 則n就是整數,將0.000…001的情況排除了;只要(n-(int)n) < -0.999999999999999 則n就是整數,將-0.999…999的情況排除了。
當n <0時,情況類似,只要-(n-(int)n) < 1e-15 則n就是整數,將-0.000…001的情況排除了;只要-(n-(int)n) < -0.999999999999999 則n就是整數,將+0.999…999的情況排除了。
注意:常量0.99…99的默認存儲類型是double型,如果在末尾加L寫成0.99…99L,則代表long double型,在VC中long double型和double型沒多少區別,所以一般不用它(GCC中可以用)。同理整數末尾也可以加L,代表long int,取值范圍是正負21億多(在32位系統中int和long [int]都是占4個字節,取值范圍也一樣,所以一般long類型也不常用,64位系統中可以用),例如212345678L(9位數,21億多)。
完整程序如下:
#include <stdlib.h>
#include <stdio.h>
int main()
{
double n;
while(scanf("%lf",&n)==1)
{
if(n>=0)
if( (n-(int)n) < 1e-15 || (n-(int)n) < -0.999999999999999 )
//單精度對應1e-6和6個9,雙精度對應1e-15和15個9
printf("YES\n");
else
printf("NO\n");
else
if( -(n-(int)n) < 1e-15 || -(n-(int)n) < -0.999999999999999 )
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
實際測試:
double型的有效位數為15位,某些情況能達16位;我們應該用有效范圍內的數據來測試。
測試數據 預測情況
0.000000000000001(14個0) 應該輸出NO
0.0000000000000001(15個0) 超出有效范圍,結果不確定(但很能輸出NO)
9.000000000000001(14個0) 應該輸出NO
9.0000000000000001(15個0) 超出有效范圍,結果不確定(可能輸出YES或NO)
測試結果:
NO
YES
NO
YES
與預期相符。其他測試也一一通過驗證。
摘自 zollty的專欄