溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

MySQL定點數(shù)類型講解

發(fā)布時間:2020-04-26 15:41:45 來源:億速云 閱讀:202 作者:三月 欄目:編程語言

下文內(nèi)容主要給大家?guī)?a title="MySQL" target="_blank" href="http://www.kemok4.com/mysql/">MySQL定點數(shù)類型講解,這里所講到的知識,與書籍略有不同,都是億速云專業(yè)技術人員在與用戶接觸過程中,總結出來的,具有一定的經(jīng)驗分享價值,希望給廣大讀者帶來幫助。

定點數(shù)類型

正因為用浮點數(shù)表示小數(shù)可能會有不精確的情況,在一些情況下我們必須保證小數(shù)是精確的,所以設計MySQL的大叔們提出一種稱之為定點數(shù)的數(shù)據(jù)類型,它也是存儲小數(shù)的一種方式:

MySQL定點數(shù)類型講解

其中:

  • M表示該小數(shù)最多需要的十進制有效數(shù)字個數(shù)。

注意是有效數(shù)字個數(shù),比方說對于小數(shù)-2.3來說有效數(shù)字個數(shù)就是2,對于小數(shù)0.9來說有效數(shù)字個數(shù)就是1。

  • D表示該小數(shù)的小數(shù)點后的十進制數(shù)字個數(shù)。

這個好理解,小數(shù)點后有幾個十進制數(shù)字,D的值就是什么。

舉個例子看一下,設置了MD的單精度浮點數(shù)的取值范圍的變化:

MySQL定點數(shù)類型講解

可以看到,在D相同的情況下,M越大,該類型的取值范圍越大;在M相同的情況下,D越大,該類型的取值范圍越小。當然,MD的取值也不是無限大的,M的取值范圍是1~255,D的取值范圍是0~30,而且D的值必須不大于MMD都是可選的,如果我們省略了它們,那它們的值按照機器支持的最大值來存儲。

我們說定點數(shù)是一種精確的小數(shù),為了達到精確的目的我們就不能把它轉(zhuǎn)換成二進制小數(shù)之后再存儲(因為有很多十進制小數(shù)轉(zhuǎn)為二進制小數(shù)后需要進行舍入操作,導致二進制小數(shù)表示的數(shù)值是不精確的)。其實轉(zhuǎn)念一想,所謂的小數(shù)只是把兩個十進制整數(shù)用小數(shù)點分割開來而已,我們只要把小數(shù)點左右的兩個十進制整數(shù)給存儲起來,那不就是精確的了么。比方說對于十進制小數(shù)2.38來說,我們可以把這個小數(shù)的小數(shù)點左右的兩個整數(shù),也就是238分別保存起來,那么不就相當于保存了一個精確的小數(shù)么,這波操作是不是很6。

當然事情并沒有這么簡單,對于給定M、D值的DECIMAL(M, D)類型,比如DEMCIMAL(16, 4)來說:

  • 首先確定小數(shù)點左邊的整數(shù)最多需要存儲的十進制位數(shù)是12位,小數(shù)點右邊的整數(shù)需要存儲的十進制位數(shù)是4位,如圖所示:

MySQL定點數(shù)類型講解

  • 從小數(shù)點位置出發(fā),每個整數(shù)每隔9個十進制位劃分為1組,效果就是這樣:

MySQL定點數(shù)類型講解

從圖中可以看出,如果不足9個十進制位,也會被劃分成一組。

  • 針對每個組中的十進制數(shù)字,將其轉(zhuǎn)換為二進制數(shù)字進行存儲,根據(jù)組中包含的十進制數(shù)字位數(shù)不同,所需的存儲空間大小也不同,具體見下表:

MySQL定點數(shù)類型講解

所以DECIMAL(16, 4)共需要占用8個字節(jié)的存儲空間大小,這8個字節(jié)由下邊3個部分組成:

  1. 第1組包含3個十進制位,需要使用2個字節(jié)存儲。
  2. 第2組包含9個十進制位,需要使用4個字節(jié)存儲。
  3. 第3組包含4個十進制位,需要使用2個字節(jié)存儲。
  • 將轉(zhuǎn)換完成的比特位序列的最高位設置為1。

這些步驟看的有一丟丟懵逼吧,別著急,舉個例子就都清楚了。比方說我們使用定點數(shù)類型DECIMAL(16, 4)來存儲十進制小數(shù)1234567890.1234,這個小數(shù)會被劃分成3個部分:

1 234567890 1234

也就是:

  1. 第1組中包含整數(shù)1。
  2. 第2組中包含整數(shù)234567890。
  3. 第3組中包含整數(shù)1234。

然后將每一組中的十進制數(shù)字轉(zhuǎn)換成對應的二進制數(shù)字:

  • 第1組占用2個字節(jié),整數(shù)1對應的二進制數(shù)就是(字節(jié)之間實際上沒有空格,只不過為了大家理解上的方便我們加了一個空格):
    00000000 00000001

    二進制看起來太難受,我們還是轉(zhuǎn)換成對應的十六進制看一下:

    0x0001
  • 第2組占用4個字節(jié),整數(shù)234567890對應的十六進制數(shù)就是:
    0x0DFB38D2
  • 第3組占用2個字節(jié),整數(shù)1234對應的十六進制數(shù)就是:
    0x04D2

    所以將這些十六進制數(shù)字連起來之后就是:

    0x00010DFB38D204D2

    最后還要將這個結果的最高位設置為1,所以最終十進制小數(shù)1234567890.1234使用定點數(shù)類型DECIMAL(16, 4)存儲時共占用8個字節(jié),具體內(nèi)容為:

    0x80010DFB38D204D2

    有的朋友會問,如果我們想使用定點數(shù)類型DECIMAL(16, 4)存儲一個負數(shù)怎么辦,比方說-1234567890.1234,這時只需要將0x80010DFB38D204D2中的每一個比特位都執(zhí)行一個取反操作就好,也就是得到下邊這個結果:

    0x7FFEF204C72DFB2D

    從上邊的敘述中我們可以知道,對于DECIMAL(M, D)類型來說,給定的MD的值不同,所需的存儲空間大小也不同??梢钥吹?,與浮點數(shù)相比,定點數(shù)需要更多的空間來存儲數(shù)據(jù),所以如果不是在某些需要存儲精確小數(shù)的場景下,一般的小數(shù)用浮點數(shù)表示就足夠了。

對于定點數(shù)類型DECIMAL(M, D)來說,MD都是可選的,默認的M的值是10,默認的D的值是0,也就是說下列等式是成立的:

DECIMAL = DECIMAL(10) = DECIMAL(10, 0)
DECIMAL(n) = DECIMAL(n, 0)

另外M的范圍是1~65D的范圍是0~30,且D的值不能超過M

對于以上關于MySQL定點數(shù)類型講解,如果大家還有更多需要了解的可以持續(xù)關注我們億速云的行業(yè)推新,如需獲取專業(yè)解答,可在官網(wǎng)聯(lián)系售前售后的,希望該文章可給大家?guī)硪欢ǖ闹R更新。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI