I'm answering my own question here (I think). In any case, what I wrote is consistent. I have the feeling I'm in a minority when I care about these things, but if you're into this too and you see I've said something wrong, please let me know.
Now the key point about all this stuff is that very shortly this decimal representation that C# uses will not be IEEE compliant (because the standard is changing). I don't think the difference will be easily apparent to users; the answers will be the same most (if not essentially all) of the time. But there are a lot of smart people out there and I wouldn't be surprised if someone can engineer a scenario that gives different answers.
Basically what you have currently is a 96-bit decimal number (not counting sign and exponent) in 128 bits. Here are some examples showing the full 128 bits with the MSB on the left and the LSB on the right.
00000000 204FCE5E 3E250261 0FFFFFFF for 999999999999999 9999999999999
80000000 204FCE5E 3E250261 0FFFFFFF for -999999999999999 9999999999999
001C0000 204FCE5E 3E250261 0FFFFFFF for .99999999999999 99999999999999
The decimal type takes up 128 bits, but all those 128 bits are not used. The decimal number really is a mantissa (I always like to call this the significand), an exponent (base 10), and a sign.
The significand takes up 96 bits, but that’s not to say that the maximum significand is 96 ones. It’s not. You’re limited to 28 decimal digits.
Add another digit and you get an overflow. That is, enter 999999999999999 99999999999991 gives an overflow. Add a decimal point (with digits after the decimal point that remain less that 0.5) and you get the same number.
00000000 204FCE5E 3E250261 0FFFFFFF
for 999999999999999 9999999999999.4 99999 and
for 999999999999999 9999999999999
If you add a decimal point (with digits that total >= 0.5), you get one more bit in the significand, but never any more.
00000000 204FCE5E 3E250261 10000000
for 999999999999999 9999999999999.5 and
for 999999999999999 9999999999999.9 99999
What about that sign and exponent? The biggest exponent you can get is 28. Here’s a number that produces it.
001C0000 204FCE5E 3E250261 0FFFFFFF for .99999999999999 99999999999999
That means that the exponent doesn’t take up more than 5 bits, but the max exponent is not 5 ones. It’s 1C.
The MSB is the sign bit. Here's a negative number.
801C0000 204FCE5E 3E250261 0FFFFFFF for -.99999999999999 99999999999999
I think decimal representation has cohorts. If I understood the term correctly, numbers that have different memory representations (different bit patterns) but test as numerically equal belong to a cohort.
Here are some members of a cohort for decimal 2. That 14 (hex) is 20 (dec); the 4E20 (hex) is 20000 (dec). When you got the 20000, you have an exponent of 4 (actually -4) to bring the value back to 2.
00010000 00000000 00000000 00000014 2.0
00020000 00000000 00000000 000000C8 2.00
00030000 00000000 00000000 000007D0 2.000
00040000 00000000 00000000 00004E20 2.0000
This is curious and hoping someone can enlighten me. Inside a C# console app I do
-
decimal mydecimal;
-
mydecimal=2.0m;
-
and then break and look at the memory window. I diplay the address of mydecimal and it does not contain what I expect. But if I edit the value of mydecimal in the debugger, I do see the memory window show what I expect. Then I can even put in back to what it was originally and it is what I expect.
I'm trying to be articulate and struggling but here is an example. If I break right after that mydecimal assignment and I see the following in the memory window. (0x0450ecb0 is the address of mydecimal.
0x0450ECB0 00010000 00000000 00000014 ............
Then, I change mydecmal from 2 to 1 in the watch window and the memory changes to the following (which is what I expect)
0x0450ECB0 00000000 00000000 00000001
The in the watch window I change mydecimal back to 2 and see the following (again what I expect)
0x0450ECB0 00000000 00000000 00000002
What's gong on with that first display? Why don't I see what I think I should? Am I expecting the right thing? Does this have somethng to do with flushing?
Advice is much appreciated. Thanks.
-ted