[.Net/VB6] 關於 Decimal 所佔的位元組

我想這個東西在微軟內部應該也是個迷思吧?很多文件都有不同的記載,一般是記載為 12/16 bytes (96/128 bits),VB6 的相關討論請參考個人網站:
鄭子璉,「Microsoft Visual Basic 之 Variant 變數應用」,微軟之友季訊,夏季 6 月號,第 42 ~ 49 頁,民國 90 年 6 月。

VB6/2002/2003 的線上手冊就不引用了。直接看最新版 VB2005 的線上手冊:
描述為 12 bytes 的 (96 bits)
(及本類別下各成員與建構函式的描述)
描述為 16 bytes 的 (128 bits)
(及其他資料型別概述)

在 Decimal.GetBits 方法中,有現成的範例,不需要另外再撰寫展示例,下面引用來參考:

傳回陣列的第四個元素包含縮放比例和正負號。它包含了下列部分:
位元 0 到 15 (低字組) 未經使用,並且必須為零。
位元 16 到 23 必須包含 0 和 28 之間的指數,指示要除整數數字的 10 乘冪。
位元 24 到 30 未經使用,並且必須為零。
位元 31 包含正負號;0 表示正,而 1 表示負。
請注意,位元表示在負零和正零之間不相同。這些值在所有的作業中則視為相等。

[由於 Windows 採用 little endian byte order,所以我把範例的 Bytes 順序按照實際記憶體位置來展示,跟上面網址稍有不同]

Argument

Bits(0)

Bits(1)

Bits(2)

Bits(3)

1

01000000

00000000

00000000

00000000

100000000000000

00407A10

F35A0000

00000000

00000000

10000000000000000000000000000

00000010

6102253E

5ECE4F20

00000000

100000000000000.00000000000000

00000010

6102253E

5ECE4F20

00000E00

1.0000000000000000000000000000

00000010

6102253E

5ECE4F20

00001C00

123456789

15CD5B07

00000000

00000000

00000000

0.123456789

15CD5B07

00000000

00000000

00000900

0.000000000123456789

15CD5B07

00000000

00000000

00001200

0.000000000000000000123456789

15CD5B07

00000000

00000000

00001B00

4294967295

FFFFFFFF

00000000

00000000

00000000

18446744073709551615

FFFFFFFF

FFFFFFFF

00000000

00000000

79228162514264337593543950335

FFFFFFFF

FFFFFFFF

FFFFFFFF

00000000

-79228162514264337593543950335

FFFFFFFF

FFFFFFFF

FFFFFFFF

00000080

-7.9228162514264337593543950335

FFFFFFFF

FFFFFFFF

FFFFFFFF

00001C80


Decimal 執行個體的二進位表示由 1 位元的正負號、96 位元的整數數字和用來除 96 位元整數並指定哪些部分是十進位小數的縮放比例所組成。縮放比例是隱含數字 10,產生範圍從 0 到 28 的指數。因此,Decimal 值的二進位表示屬於形式 ((-296 到 296) / 10(0 到 28)),其中的 -296-1 等於 MinValue,並且 296-1 等於 MaxValue

兩個描述有明確的不同。
 
個人歸納的總結:
在 .Net 類別中 Decimal 共使用 14 bytes ,包含 2 bytes 未使用的情況下,可當成 16 bytes ,前 12 bytes 為超超長整數,之後 2 bytes 不使用,第 15 byte 表示指數部份,含指數負號,第 16 bytes 表示 Decimal 負號。
在 oleaut32.dll 定義的 Variant Decimal (VB6/Excel/VBA/VBScript 等) 中 Decimal 共使用 14 bytes ,包含 2 bytes 的資料型別 (VarType),可當成 16 bytes ,前 2 bytes 資料型別,為超超長整數,之後第 3 byte 表示 Decimal 負號,第 4 byte 表示指數部份,含指數負號,第 5 ~ 8 bytes 表示 超高位元組(hi),第 9 ~ 12 bytes 表示 低位元組(lo),第 13 ~ 16 bytes 表示 中位元組(mid)。
若透過檔案交換二進位資料,或直接透過位元組陣列交換資料時,需自行進行位元組的轉換與對應,才能正確在 .Net 轉換為 Decimal 。
廣告
Categories: 技術分享 | 發表留言

文章分頁導航

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 / 變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 / 變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 / 變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 / 變更 )

連結到 %s

在 WordPress.com 建立免費網站或網誌.

%d 位部落客按了讚: