2

What's the second minimum value that a decimal can represent? That is the value which is larger than Decimal.MinValue and smaller than any other values that a decimal can represent. How can I obtain this value in C#? Thanks!

Jon
  • 428,835
  • 81
  • 738
  • 806
xiagao1982
  • 1,077
  • 1
  • 13
  • 25

3 Answers3

8

The second-minimum value is Decimal.MinValue + 1.

This can be inferred from the documentation for decimal:

A decimal number is a floating-point value that consists of a sign, a numeric value where each digit in the value ranges from 0 to 9, and a scaling factor that indicates the position of a floating decimal point that separates the integral and fractional parts of the numeric value.

The binary representation of a Decimal value consists of a 1-bit sign, a 96-bit integer number, and a scaling factor used to divide the 96-bit integer and specify what portion of it is a decimal fraction. The scaling factor is implicitly the number 10, raised to an exponent ranging from 0 to 28. Therefore, the binary representation of a Decimal value is of the form, ((-2^96 to 2^96) / 10^(0 to 28)), where -2^96-1 is equal to MinValue, and 2^96-1 is equal to MaxValue.

From the above we can infer that on the extreme edges of the legal value range, the scaling factor is 1 (10 to the power 0) and therefore that's the smallest quantum when a decimal value is modified.

Live proof.

Jon
  • 428,835
  • 81
  • 738
  • 806
6

According to MSDN, a decimal is represented like ((-2^96 to 2^96) / 10^(0 to 28)), where -2^96-1 is equal to MinValue, and 2^96-1 is equal to MaxValue, so the smallest difference between two decimals is 1/10^28.
That difference is only possible between small decimals though. Generally, as a decimal becomes larger (no matter the sign), you lose decimal points, until there are none left.

UPDATE: As also pointed out in the comments, you can't actually change decimal.MinValue by adding the smallest decimal value (as above). Decimal has 1 bit for the sign, 96 bit for a number and a scaling factor (10^x) by which the number is divided.

In order to get to such a large negative number, the exponent portion of the scaling factor must be set to 0 (-> 10^0 == 1), because setting it to anything higher would cause the number to be divided by that and thus it would get smaller.

That means, for such a number, the smallest difference would be 1/10^0, or 1.

So you are looking for this:

decimal.MinValue + 1m;
Botz3000
  • 39,020
  • 8
  • 103
  • 127
  • +1, I *think* this is what the OP is after. Possibly the answer would be `Decimal.MinValue + 0.000...1`. – George Duckett Jun 28 '12 at 09:44
  • @Botz3000, @George: But `(Decimal.MinValue + 0.000...1) == Decimal.MinValue`. – LukeH Jun 28 '12 at 09:46
  • 1
    -1: This is incorrect. The scaling factor represents the portion of the 96 bits that is a decimal fraction. You can trivially confirm this by checking what `Decimal.MinValue + 0.000001m` is. – Jon Jun 28 '12 at 09:47
  • @LukeH: Surely there is some number that when added to `Decimal.MinValue` such that `Decimal.MinValue + x > Decimal.MinValue` where `x < 1`. – George Duckett Jun 28 '12 at 09:48
  • @GeorgeDuckett: "Surely" why? Any hard facts? – Jon Jun 28 '12 at 09:51
  • @Jon, see my comment on the other answer. I'm guessing that my understanding of decimal is wrong. – George Duckett Jun 28 '12 at 09:51
  • @George: Well, you could set `x` to `0.49999999999999999999999999995` in your source code if you like, but `Decimal.MinValue + x` would still be `-79,228,162,514,264,337,593,543,950,334`. – LukeH Jun 28 '12 at 09:53
  • @GeorgeDuckett: Please remove your upvote too, as this answer is factually wrong. – Jon Jun 28 '12 at 09:53
  • @Jon: I tried to earlier, but no edit so couldn't. Have now removed. – George Duckett Jun 28 '12 at 09:54
  • @Jon Got it wrong. I edited my answer and added some explanation of the reason. – Botz3000 Jun 28 '12 at 10:05
  • @Botz3000: Downvote removed, but please edit further because the very first line of the current version is still wrong. – Jon Jun 28 '12 at 10:14
3

http://msdn.microsoft.com/en-us/library/system.decimal.minvalue.aspx

Decimal.MinValue + 1

So: -79,228,162,514,264,337,593,543,950,334.

t3hn00b
  • 904
  • 5
  • 13
  • I think you mean _negative_ 79,228,162,514,264,337,593,543,950,334 – Bridge Jun 28 '12 at 09:40
  • Since it's decimal why add 1.0, why not 0.00000....1 (maybe what asker is asking) – George Duckett Jun 28 '12 at 09:43
  • @George: Because the `Decimal` type can't represent any intermediate values between `-79,228,162,514,264,337,593,543,950,335` and `-79,228,162,514,264,337,593,543,950,334`. The smallest discrete step is 1. – LukeH Jun 28 '12 at 09:49
  • I'm a bit confused now, as i thought the point of decimal (as opposed to float etc.) is that the difference in values it can represent is fixed. – George Duckett Jun 28 '12 at 09:50