C++ double和float(浮點型別)詳解

2020-07-16 10:04:39
整數並不足以適應許多工作。如果正在編寫的程式需要計算貨幣金額或精確測量,那麼就需要一種允許分數值的資料型別。在程式設計術語上,稱之為浮點數

浮點數內部的儲存方式和科學計數法是一樣的。以數位 47 281.97 為例,在科學計數法中,這個數位是 4.728 197X104。其中,104 等於 10000,4.728 197X 10 000 也就是 47 281.97。該數位的第一部分,即 4.728 197,稱為尾數

計算機通常使用 E 符號來表示浮點值。以 E 符號表示,數位 47 281.97 就應該是 4.728 197E4。E 前的數位部分是尾數,E 之後的部分是 10 的冪。當記憶體中儲存一個浮點數時,它將被儲存為尾數和 10 的冪,如表 1 所示。

表 1 顯示了科學計數法和E符號表示的其他數位
十進位制法 科學計數法 E 符號表示法
247.91 2.4791 X102 2.4791E2
0.00072 7.2 X10-4 7.2E-4
2 900 000 2.9 X106 2.9E6

在 C++ 中有以下 3 種資料型別可以表示浮點數,分別是 floatdoublelong double

float 資料型別被認為是單精度。double 資料型別通常是 float 的兩倍大小,因此被認為是雙精度。顧名思義,long double 資料型別又比 double 要大。這些資料型別的確切大小取決於當前使用的計算機。唯一可以保證的是:
  • double 至少與 float 一樣大。
  • long double 至少與 double一樣大。

表 2 顯示了通常在 PC 上發現的浮點資料型別的大小和範圍。

表 2 PC上的浮點資料型別
資料型別 關鍵字 大小 範 圍 有效數位
單精度 float 4位元組 數位介於 ±3.4E-38 和 ±3.4E38 之間 7
雙精度 double 8位元組 數位介於 ±1.7E-308 和 ±1.7E308 之間 16
高雙精度 long double 8位元組 數位介於 ±1.7E-308 和 ±1.7E308 之間 16

有些編譯器會對 long double 型別使用 8 個以上的位元組。這意味著更大的數位範圍。

有些人可能已經注意到,浮點資料型別沒有無符號分類,這是因為在所有機器上,float、double 和 long double 資料型別的變數都可以儲存正數和負數。下面的程式是使用浮點資料型別的範例。
//程式 1
// This program uses two floating-point data types, float and double.
#include <iostream>
using namespace std;
int main()
{
    float distance = 1. 496E8; //in kilometers
    double mass = 1.989E30; //in kilograms
    cout << "The Sun is " << distance << " kilometers away.n";
    cout << "The Sun's mass is " << mass << "kilogrames.n";
    return 0;
}
程式輸出結果:

The Sun is 1.496e+008 kilometers away.
The Sun's mass is 1.989e+030 kilograms.

浮點常數

浮點常數有時也叫浮點常數,它們可以按多種方式表示,如程式 1 所示,E 符號表示法就是其中的一種。在要編寫非常大或非常小的數位時,這可能是最簡單的方法。

E 符號表示法既可以使用大寫字母 E,也可以使用小寫字母 e。注意,在原始碼中,常數被寫為 1.496E8 和 1.989E30,但是程式卻將它們列印為 1.496e+008 和 1.989e+030。這兩組數位是一樣的。指數前面的加號也可加可不加。

也可以使用十進位制符號來表示浮點常數。例如,常數 1.496E8 可以寫成:

149600000.0

顯然,E 符號表示法對於冗長的數位更為方便;但對於像 47.39 這樣的數位,十進位制格式就要優於 4.739E1。

以下所有浮點常數都是等效的:
  • 1.496E8
  • 1.496e8
  • 1.496E+8
  • 1.496e+8
  • 149600000.0

浮點常數通常以 double 型別儲存在記憶體中。如果需要強制將這類常數儲存為 float 型別,則可以將 F 或 f 字母附加到其末尾。例如,以下常數將被儲存為 float 型別數位:

1.2F
45.907f

注意,由於浮點常數通常是以 double 型別儲存在記憶體中的,所以,在為 float 變數分配一個浮點常數時,某些編譯器會發出警告訊息。例如,如果 num 是一個 float 型別的變數,則以下語句可能會導致編譯器生成警告訊息:

num = 14.725;

在這種情況下,可以通過在浮點常數後面附加f字尾來抑制錯誤訊息,如下所示:

num = 14.725f;

如果要強制將某個值儲存為 long double,則可以給它附加一個 L 字尾,如下所示:

1034.56L

由於小數點的存在,編譯器並不會將它與長整型混淆。也可以使用小寫字母l來將浮點常數定義為 long double,但是最好能使用大寫字母 L,因為小寫字母 l 容易與數位 1 混淆。

將浮點值分配給整型變數

當某個浮點值被分配給整型變數時,該值的小數部分(即小數點後的部分)將被丟棄。這是因為整型變數不能包含任何包含小數的值。請看以下程式碼範例:

int number;
number= 7.8;    // 實際給 number 賦值為 7

該程式碼嘗試將浮點值 7.8 賦給整型變數 number,但這是不可能的,所以 number 實際獲得的賦值為 7,分數部分則被丟棄。當以這種方式丟棄一部分值時,該值即所謂被截斷。

將某個浮點變數賦值給整型變數具有相同的效果。請看以下程式碼範例:

int intVar;
double doubleVar = 7.8;
intVar = doubleVar; // intVar被賦值為7
//doubleVar 的值仍為 7.8

警告,浮點變數可以容納比整型變數更大的值範圍。如果浮點值儲存在整型變數中,並且整型變數的整數部分(即小數點前的部分)太大,則整型變數中將儲存無效值。