Decimal precision setting, .net

These lines in C #

decimal a = 2m; decimal b = 2.0m; decimal c = 2.00000000m; decimal d = 2.000000000000000000000000000m; Console.WriteLine(a); Console.WriteLine(b); Console.WriteLine(c); Console.WriteLine(d); 

Generates this output:

 2 2.0 2.00000000 2.000000000000000000000000000 

So, I see that creating a decimal variable from a literal allows me to control the accuracy.

  • Can I adjust the precision of decimal variables without using literals?
  • How can i create b from? How can I create b from c?
+53
decimal precision
Jul 15 '09 at 17:24
source share
7 answers

Preserving trailing zeros like this was introduced in .NET 1.1 to more closely comply with the ECI CLI specification.

MSDN has some information about this. here .

You can adjust the accuracy as follows:

  • Math.Round (or ceiling, floor, etc.) to reduce accuracy (b from c)

  • Multiply by 1.000 ... (with the number of decimal places you want) to increase accuracy - for example. multiply by 1.0M to get b out.

+43
Jul 15 '09 at 20:37
source share

You just see different representations of the same data. decimal accuracy will scale so that it is (within reason).

From System.Decimal :

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

Binary decimal value A value consists of a 1-bit sign, a 96-bit integer and the scaling factor used to divide a 96-bit integer and indicate how much of it is a decimal. The scaling factor is implicitly equal to the number 10, increased to a level from 0 to 28. Therefore, the binary representation of the decimal value of the form ((-2 96 to 2 96 ) / 10 (from 0 to 28) ), where -2 96 -1 is equal to MinValue and 2 96 -1 is equal to MaxValue.

The scale factor also stores any trailing zeros in decimal. Trailing zeros do not affect the decimal value in arithmetic or comparison operations. However, trailing zeros can be detected by the ToString method if the appropriate format string is applied.

+17
Jul 15 '09 at 17:26
source share
+6
Jul 15 '09 at 17:50
source share

I found that I can "fake" the scale by multiplying or dividing by fantasy 1.

 decimal a = 2m; decimal c = 2.00000000m; decimal PreciseOne = 1.000000000000000000000000000000m; //add maximum trailing zeros to a decimal x = a * PreciseOne; //remove all trailing zeros from c decimal y = c / PreciseOne; 

I can make accurate enough 1 to change scale factors by known sizes.

 decimal scaleFactorBase = 1.0m; decimal scaleFactor = 1m; int scaleFactorSize = 3; for (int i = 0; i < scaleFactorSize; i++) { scaleFactor *= scaleFactorBase; } decimal z = a * scaleFactor; 
+5
Jul 15 '09 at 18:38
source share

It is tempting to confuse decimal in SQL Server with decimal in .NET; they are completely different.

SQL Server decimal is a fixed point number whose precision and scale are fixed when a column or variable is defined.

.NET decimal is a floating point number, such as float and double (the difference is that decimal exactly stores decimal numbers, while float and double exactly store binary digits). Trying to control the accuracy of .NET decimal pointless, since all calculations give the same results, regardless of the presence or absence of padding zeros.

+5
Aug 25 '09 at 21:09
source share

The question is: do you really need the accuracy stored in decimal form, and not just displayed the decimal digit with the required accuracy. Most applications know internally how accurate they want to be and demonstrate this level of accuracy. For example, even if the user enters an invoice for 100 in the batch of accounts, he still prints as 100.00 using something like val.ToString ("n2").

How can i create b from? How to create b from c?

c to b.

 Console.WriteLine(Math.Round(2.00000000m, 1)) 

produces 2.0

a to b is difficult because the concept of introducing precision is a little foreign to mathematics.

I think that a terrible hack can be both ways.

 decimal b = Decimal.Parse(a.ToString("#.0")); Console.WriteLine(b); 

produces 2.0

+1
Jul 15 '09 at 18:03
source share

This will remove all trailing zeros from the decimal, and then you can just use ToString() .

 public static class DecimalExtensions { public static Decimal Normalize(this Decimal value) { return value / 1.000000000000000000000000000000000m; } } 

Or, alternatively, if you want the exact number of trailing zeros, say 5, first Normalize (), and then multiply by 1.00000 m.

-one
Jan 09 '13 at 18:18
source share



All Articles