System. Decimal Structure

Source: Internet
Author: User
Tags arch linux
Introduction

We know that Microsoft.. NET Framework. the decimal structure (in the C # language, the medium price is the decimal keyword) is used to represent the decimal number, ranging from-(296-1) to 296-1, and can have 28 decimal places. This means:

    • Decimal. minvalue =-79,228,162,514,264,337,593,543,950,335 =-(296-1)
    • Decimal. maxvalue = 79,228,162,514,264,337,593,543,950,335 = 296-1
    • Decimal. Epsilon = 0.0000000000000000000000000001 = 10-28

The preceding two static read-only fields are decimal. Unfortunately, the third one does not belong to the decimal structure.

Decimal uses four 32-bit system. int32 files for storage, occupying 128 bits = 16 bytes. The allocation of bits of the 128 type is as follows:

    • 96 bits indicates the integer from 0 to 296-1, which is distributed in three 32-bit system. int32.
    • The remaining 32-bit system. int32 includes the symbol bit and proportional factor.
    • 31st bit indicates the symbol bit, 0 indicates a positive number, and 1 indicates a negative number.
    • 16th to 23 bits indicate a proportional factor, which must contain an index between 0 and 28, indicating the power of 10, that is, the decimal point location, that is, the number of digits on the right of the decimal point.
    • In fact, the index between 0 and 28 only needs 5 bits, while the above 16th to 23 Bit total 8 bits = 1 byte. That is to say, the remaining 3 bits (21st to 23 Bit) must be zero.
    • Other BITs (0-15 bit and 24-30 bit) are not used and must be zero.

The decimal. getbits method returns the internal representation of the preceding decimal. The decimal (INT [] bits) constructor uses this internal representation to construct a decimal instance. A decimal may have several different internal representations. All these internal representations are equally valid and are equal in numerical values.

Tinydecimal Data Type

To better understand the decimal structure, we construct a tinydecimal structure with only 8 bits = 1 byte:

    • Number: 0th to 5 bits (6 bits in total) indicates an integer from 0 to 26-1, with a total of 64 bits.
    • Exp: 6th bits indicate a proportional factor, which contains an index between 0 and 1, indicating the power of 10, that is, the decimal point. 0 indicates that the decimal point is on the rightmost side.
    • Sign: 7th bit indicates the sign bit. 0 indicates a positive number, and 1 indicates a negative number.

Therefore:

    • Tinydecimal. minvalue =-63 =-(26-1)
    • Tinydecimal. maxvalue = 63 = 26-1
    • Tinydecimal. Epsilon = 0.1 = 10-1

That is to say, tinydecimal indicates that the range is from-63 to 63, and there can be 1 decimal.

Tinydecimal has the following two conditions:

    • When exp = 1: 0.1, 0.2,..., 0.9, 1.0, 1.1,..., 6.2, 6.3. A total of 63.
    • When exp = 0: 1, 2,..., 63. A total of 63, but the first 6 (1 = 1.0, 2 = 2.0,..., 6 = 6.0) and above are repeated.

Therefore, the positive number of tinydecimal is 63 + (63-6) = 120. There are also 120 negative numbers. Therefore, tinydecimal has 241 different values, that is, each of the positive and negative numbers is 120, plus a zero value. Note that zero has four different representations: + 0,-0, + 0.0,-0.0. The order of positive numbers of tinydecimal is as follows:

    • 0.1, 0.2,..., 6.2, 6.3, 7, 8, 9, 10, 11,..., 62, 63

Note: In tinydecimal, the next number of 6.3 is 7, And the next number of 7 is 8, according to the absence of numbers such as 6.4 and 7.1. The following example is provided:

    • 6.3 + 0.1 = 6.3
    • 6.3 + 0.3 = 7
    • 7 + 0.4 = 7
    • 7 + 0.6 = 8
    • 63 + 1 = Overflow

We know that 1 byte can represent 28 = 256 different values. Tinydecimal has 241 different values. The calculation is as follows: 241 = 256-6*2-3, that is, 6*2 positive numbers of duplicates and 3 zero duplicates must be deducted.

Test Program

The system. Decimal structure is an enlarged version of The tinydecimal structure. To better understand the above content, I wrote the following test program:

 1   Using  System;  2    3   Static   Class  Decimaltester  4   {  5     Static  Void  Main ()  6   {  7       VaR Epsilon = 0.0000000000000000000000000001 m  ;  8       VaR A = Decimal . Maxvalue/ 100  ;  9       VaR B =7.1234567890123456789012345685 m  ;  10 Console. writeline ( "  {0}: 1e-28  "  , Epsilon );  11 Console. writeline ( "  {0 }:1e-28 + 0.1  " , 0.1 m + Epsilon );  12 Console. writeline ("  {0}:  "  , );  13 Console. writeline ( "  {0,-30}: A + 0.004  " , A + 0.004 m  );  14 Console. writeline ( "  {0,-30}: A + 0.005  " , A + 0.005 m );  15 Console. writeline ( "  {0,-30}: A + 0.01  " , A + 0.01 m  );  16 Console. writeline ( "  {0,-30}: A + 0.099  " , A + 0.099 m  );  17 Console. writeline ( " {0,-30}: A + 0.1  " , A + 0.1 m  );  18 Console. writeline ( "  {0,-30}: (A + 0.1) + 1e-28  " , A + 0.1 m + Epsilon );  19 Console. writeline ( "  {0,-30}: A + (0.1 + 1e-28)  " , A + (0.1 m + Epsilon ));  20 Console. writeline ( "  {0}: B  "  , B );  21 Console. writeline ( "  {0,-30}: B + 1  " , B + 1  );  22   }  23 }

The Epsilon of the first row of this program is the decimal. Epsilon mentioned in the Introduction. Its value is 10-28, and decimal can represent the smallest positive number.

Compile and run in Linux

Compile and run the 64-bit arch Linux mono 3.0.4 environment:

 
Work $DMCS -- versionMono C # compiler version 3.0.4.0work $DMCS decimaltester. CSWork $Mono decimaltester.exe0.0000000000000000000000000001: 1e-280.00000000000000000000001: 1e-28 + pushed: A + 0.1792281625142643375935439503.5: (A + 0.1) + pushed: A + (0.1 + 1e-28) 7.1234567890123456789012345685: b8.123456789012345678901234569: B + 1

The rows of the preceding running results are as follows:

  1. Epsilon = 10-28 = 0.0000000000000000000000000001, which is the smallest positive number that decimal can represent.
  2. Epsilon + 0.1 = 10-28 + 0.1 = 0.1000000000000000000000000001.
  3. A = decimal. Value/100 = 79... 3.35. This number has 29 valid digits.
  4. A + 0.004 = 79... 3.354, rounded to 79... 3.350Is equal to.
  5. A + 0.005 = 79... 3.355, rounded to 79... 3.360But this number cannot be expressed in decimal, so it has to be rounded to 79... 3.400The number is only 28 valid digits.
  6. A + 0.01 = 79... 3.36, as mentioned above, this number cannot be expressed in decimal, so it has to be rounded to 79... 3.40.
  7. A + 0.099 = 79... 3.449, rounded to 79... 3.400.
  8. A + 0.1 = 79... 3.45, rounded to 79... 3.50.
  9. (A + 0.1) + 10-28. The result is the same as that of the previous row.
  10. A + (0.1 + 10-28). The result is the same as that of the previous row.
  11. B = 7.1234567890123456789012345685. This number has 29 valid digits.
  12. B + 1 = 8. 1... 85. But this number cannot be expressed in decimal, so it has to be rounded to 8. 1... 9.0.

From the above analysis, we can see that in the mono environment of Linux, the Rounding Rule of decimal arithmetic operations is rounding.

Compile and run in Windows

Compile and run Windows 7 SP1 32-bit in Microsoft. NET Framework 4.5:

D: \ work>CSC decimalsumtester. CSMicrosoft (r) Visual C # compiler version 4.0.30319.17929 is used for Microsoft (R). Net Framework 4.5 copyright ownership (c) Microsoft Corporation. All rights reserved. D: \ work>Decimaltester0.0000000000000000000000000001: 1e-280.00000000000000000000001: 1e-28 + pushed: A + 0.1792281625142643375935439503.4: (A + 0.1) + pushed: A + (0.1 + 1e-28) 7.1234567890123456789012345685: b8.123456789012345678901234568: B + 1

The rows of the preceding running results are as follows:

  1. Epsilon = 10-28 = 0.0000000000000000000000000001, which is the smallest positive number that decimal can represent.
  2. Epsilon + 0.1 = 10-28 + 0.1 = 0.1000000000000000000000000001.
  3. A = decimal. Value/100 = 79... 3.35. This number has 29 valid digits.
  4. A + 0.004 = 79... 3.354, rounded to 79... 3.350Is equal to.
  5. A + 0.005 = 79... 3.355, rounded to 79... 3.360But this number cannot be expressed in decimal, so it has to be rounded to 79... 3.400The number is only 28 valid digits.
  6. A + 0.01 = 79... 3.36, as mentioned above, this number cannot be expressed in decimal, so it has to be rounded to 79... 3.40.
  7. A + 0.099 = 79... 3.449, rounded to 79... 3.400.
  8. A + 0.1 = 79... 3.45, rounded to 79... 3.40.
  9. (A + 0.1) + 10-28. The result is the same as that of the previous line, which is equal to 79... 3.4.0. Because 10-28 is too small, adding it will not change anything.
  10. A + (0.1 + 10-28) = 79... 3.4500000000000000000000000001, rounded to 79... 3.50... 0. Compared with the previous line, it is found that addition does not meet the combination law.
  11. B = 7.1234567890123456789012345685. This number has 29 valid digits.
  12. B + 1 = 8. 1... 85. But this number cannot be expressed in decimal, so it has to be rounded to 8. 1... 8.0.

From the above analysis, we can see that in the windows. NET Framework environment, the Rounding Rule for decimal arithmetic operations is four homes, six in five get even. Therefore, output in lines 8th, 9, and 12 is different from output in Linux.

Decimal has limited precision and can only represent a finite number of scattered values. In some special arithmetic operations, unexpected results are generated. In addition, the next loop is decomposed.

References
    1. Msdn: decimal structure (system)
    2. Msdn: decimal. getbits method (system)
    3. Msdn: decimal Constructor (int32 []) (system)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.