I want to increase a decimal's smallest fractional part with one so that for example
decimal d = 0.01
d++
d == 0.02
or
decimal d = 0.000012349
d++
d == 0.000012350
How do i do this?
The decimal type (.NET 2.0 and later) retains significant trailing zeroes that are the result of a calculation or as a result of parsing a string. E.g. 1.2 * 0.5 = 0.60 (multiplying two numbers accurate to one decimal place gives a result accurate to 2 decimal places, even when the second decimal place is zero):
decimal result = 1.2M * 0.5M;
Console.WriteLine(result.ToString()); // outputs 0.60
The following assumes you want to consider all significant digits in your decimal value, i.e.
decimal d = 1.2349M; // original 1.2349;
d = IncrementLastDigit(d); // result is 1.2350;
d = IncrementLastDigit(d); // result is 1.2351; (not 1.2360).
However if you want to first remove trailing zeroes, you can do so, e.g. using the technique in this answer.
There's nothing built-in to do this. You'll have to do it yourself by (a) determining how many digits there are after the decimal, then (b) adding the appropriate amount.
To determine how many digits there are after the decimal, you can either format as a string, then count them, or more efficiently, call decimal.GetBits(), the result of which is an array of four integers that contains the scaling factor in bits 16-23 of the fourth integer.
Once you have that you can easily calculate the required value to add to your decimal value.
Here's an implementation that uses GetBits, which "increments" away from zero for negative numbers IncrementLastDigit(-1.234M) => -1.235M.
static decimal IncrementLastDigit(decimal value)
{
int[] bits1 = decimal.GetBits(value);
int saved = bits1[3];
bits1[3] = 0; // Set scaling to 0, remove sign
int[] bits2 = decimal.GetBits(new decimal(bits1) + 1);
bits2[3] = saved; // Restore original scaling and sign
return new decimal(bits2);
}
Or here's an alternative (perhaps slightly more elegant):
static decimal GetScaledOne(decimal value)
{
int[] bits = decimal.GetBits(value);
// Generate a value +1, scaled using the same scaling factor as the input value
bits[0] = 1;
bits[1] = 0;
bits[2] = 0;
bits[3] = bits[3] & 0x00FF0000;
return new decimal(bits);
}
static decimal IncrementLastDigit(decimal value)
{
return value < 0 ? value - GetScaledOne(value) : value + GetScaledOne(value);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With