初學C++的時候,對這個模板很陌生,不知道它究竟是作什麼用的,今天拿起《C++標準程序庫》,出現了它的討論,因此決定好好研究一番。 ios
1. numeric_limits是什麼? git
(A)《C++標準程序庫》: 程序員
- 通常來講,數值型別的極值是一個與平臺相關的特性。C++標準程序庫經過template numeric_limits提供這些極值,取代傳統C語言,所採用的預處理常數。新的極值概念有兩個優勢,第一是提供更好的型別安全性,第二是程序員可藉此寫出一些template以覈定這些極值。
(B)MSDN 安全
- The template class describes arithmetic properties of built-in numerical types.
-
- The header defines explicit specializations for the types wchar_t, bool, char, signed char, unsigned char, short, unsigned short, int, unsigned int, long, unsigned long, float, double, and long double. For these explicit specializations, the member numeric_limits::is_specialized is true, and all relevant members have meaningful values. The program can supply additional explicit specializations. Most member functions of the class describe or test possible implementations of float.
-
- For an arbitrary specialization, no members have meaningful values. A member object that does not have a meaningful value stores zero (or false) and a member function that does not return a meaningful value returns Type(0).
-
-
-
- 上面的意思是說:
-
- 這個模板類描述了內建類型的數值屬性。
-
- C++標準庫顯式地爲wchar_t, bool, char, signed char, unsigned char, short, unsigned short, int, unsigned int, long, unsigned long, float, double, and long double這些類型提供了特化。對於這些類型來講,is_specialized爲true,而且全部的相關的成員(成員變量或成員函數)是有意義的。這個模板也提供其餘的特化。大部分的成員函數能夠用float型別來描述或測試。
-
- 對於一個任意的特化,相關的成員是沒有意義的。一個沒有意義的對象通常用0(或者false)來表示,一個沒有意義的成員函數會返回0.
(C)個人理解 函數
- 說白了,它是一個模板類,它主要是把C++當中的一些內建型別進行了封裝,好比說numeric_limits<int>是一個特化後的類,從這個類的成員變量與成員函數中,咱們能夠了解到int的不少特性:能夠表示的最大值,最小值,是不是精確的,是不是有符號等等。若是用其餘任意(非內建類型)來特化這個模板類,好比string,string怎麼可能有最大值?咱們從MSDN上能夠了解到,這對string,成員變量與成員函數是沒有意義的,要麼返回0要麼爲false。
2. 小例展現numeric_limits的基本用法: 測試
- #include <limits>
- #include <iostream>
- using namespace std;
-
- int main() {
- cout << boolalpha;
-
- cout << "max(short): " << numeric_limits<short>::max() << endl;
- cout << "min(short): " << numeric_limits<short>::min() << endl;
-
- cout << "max(int): " << numeric_limits<int>::max() << endl;
- cout << "min(int): " << numeric_limits<int>::min() << endl;
-
- cout << "max(long): " << numeric_limits<long>::max() << endl;
- cout << "min(long): " << numeric_limits<long>::min() << endl;
-
- cout << endl;
-
- cout << "max(float): " << numeric_limits<float>::max() << endl;
- cout << "min(float): " << numeric_limits<float>::min() << endl;
-
- cout << "max(double): " << numeric_limits<double>::max() << endl;
- cout << "min(double): " << numeric_limits<double>::min() << endl;
-
- cout << "max(long double): " << numeric_limits<long double>::max() << endl;
- cout << "min(long double): " << numeric_limits<long double>::min() << endl;
-
- cout << endl;
-
- cout << "is_signed(char): "
- << numeric_limits<char>::is_signed << endl;
- cout << "is_specialized(string): "
- << numeric_limits<string>::is_specialized << endl;
- }
我機器上的運行結果: ui
- max(short): 32767
- min(short): -32768
- max(int): 2147483647
- min(int): -2147483648
- max(long): 2147483647
- min(long): -2147483648
-
- max(float): 3.40282e+038
- min(float): 1.17549e-038
- max(double): 1.79769e+308
- min(double): 2.22507e-308
- max(long double): 1.79769e+308
- min(long double): 2.22507e-308
-
- is_signed(char): true
- is_specialized(string): false
- 請按任意鍵繼續. . .
關於爲何float的最小值居然是正的?我也存在疑問,從結果中,咱們看出,min返回的是float型別能夠表示的最小的正值, spa
而不是最小的float數。 .net
從這個例子中,咱們差很少了解到numeric_limits的基本用法。 對象
3. 基本成員函數
我以float類型來展現:
- #include <limits>
- #include <iostream>
- using namespace std;
-
- int main() {
- cout << boolalpha;
- // 能夠表示的最大值
- cout << "max(float): " << numeric_limits<float>::max() << endl;
- // 能夠表示的大於0的最小值,其餘類型的實現或與此不一樣
- cout << "min(float): " << numeric_limits<float>::min() << endl;
- // 標準庫是否爲其實現了特化
- cout << "is_specialized(float): " << numeric_limits<float>::is_specialized << endl;
- // 是不是有符號的,便可以表示正負值
- cout << "is_signed(float): " << numeric_limits<float>::is_signed << endl;
- // 不否是整形的
- cout << "is_integer(float): " << numeric_limits<float>::is_integer << endl;
- // 是不是精確表示的
- cout << "is_exact(float): " << numeric_limits<float>::is_exact << endl;
- // 是否存在大小界限
- cout << "is_bounded(float): " << numeric_limits<float>::is_bounded << endl;
- // 兩個比較大的數相加而不會溢出,生成一個較小的值
- cout << "is_modulo(float): " << numeric_limits<float>::is_modulo << endl;
- // 是否符合某某標準
- cout << "is_iec559(float): " << numeric_limits<float>::is_iec559 << endl;
- // 不加+-號能夠表示的位數
- cout << "digits(float): " << numeric_limits<float>::digits << endl;
- // 十進制數的個數
- cout << "digits10(float): " << numeric_limits<float>::digits10 << endl;
- // 通常基數爲2
- cout << "radix(float): " << numeric_limits<float>::radix << endl;
- // 以2爲基數的最小指數
- cout << "min_exponent(float): " << numeric_limits<float>::min_exponent << endl;
- // 以2爲基數的最大指數
- cout << "max_exponent(float): " << numeric_limits<float>::max_exponent << endl;
- // 以10爲基數的最小指數
- cout << "min_exponent10(float): " << numeric_limits<float>::min_exponent10 << endl;
- // 以10爲基數的最大指數
- cout << "max_exponent10(float): " << numeric_limits<float>::max_exponent10 << endl;
- // 1值和最接近1值的差距
- cout << "epsilon(float): " << numeric_limits<float>::epsilon() << endl;
- // 舍入方式
- cout << "round_style(float): " << numeric_limits<float>::round_style << endl;
- }
運行結果:
- max(float): 3.40282e+038
- min(float): 1.17549e-038
- is_specialized(float): true
- is_signed(float): true
- is_integer(float): false
- is_exact(float): false
- is_bounded(float): true
- is_modulo(float): false
- is_iec559(float): true
- digits(float): 24
- digits10(float): 6
- radix(float): 2
- min_exponent(float): -125
- max_exponent(float): 128
- min_exponent10(float): -37
- max_exponent10(float): 38
- epsilon(float): 1.19209e-007
- round_style(float): 1
- 請按任意鍵繼續. . .