调整小数精度,.net
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1132765/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Adjusting decimal precision, .net
提问by Amy B
These lines in C#
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 can see that creating a decimal variable from a literal allows me to control the precision.
所以我可以看到从文字创建十进制变量允许我控制精度。
- Can I adjust the precision of decimal variables without using literals?
- How can I create b from a? How can I create b from c?
- 我可以在不使用文字的情况下调整十进制变量的精度吗?
- 如何从 a 创建 b?如何从 c 创建 b?
采纳答案by Joe
Preserving trailing zeroes like this was introduced in .NET 1.1 for more strict conformance with the ECMA CLI specification.
.NET 1.1 中引入了这样的保留尾随零,以更严格地符合 ECMA CLI 规范。
There is some info on this on MSDN, e.g. here.
MSDN 上有一些关于此的信息,例如here。
You can adjust the precision as follows:
您可以按如下方式调整精度:
Math.Round (or Ceiling, Floor etc) to decrease precision (b from c)
Multiply by 1.000... (with the number of decimals you want) to increase precision - e.g. multiply by 1.0M to get b from a.
Math.Round(或天花板、地板等)以降低精度(b 来自 c)
乘以 1.000...(使用您想要的小数位数)以提高精度 - 例如乘以 1.0M 以从 a 中得到 b。
回答by Andrew Hare
You are just seeing different representations of the exact same data. The precision of a decimalwill be scaled to be as big as it needs to be (within reason).
您只是看到完全相同数据的不同表示。a 的精度decimal将被缩放到所需的大小(在合理范围内)。
From System.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, ((-296to 296) / 10(0 to 28)), where -296-1 is equal to MinValue, and 296-1 is equal to MaxValue.
The scaling factor also preserves any trailing zeroes in a Decimal number. Trailing zeroes do not affect the value of a Decimal number in arithmetic or comparison operations. However, trailing zeroes can be revealed by the ToString method if an appropriate format string is applied.
十进制数是一个浮点值,由一个符号、一个数字值(该值中的每个数字的范围为 0 到 9)和一个比例因子组成,该比例因子指示分隔整数部分和小数部分的浮点小数点的位置的数值。
Decimal 值的二进制表示由 1 位符号、96 位整数和用于划分 96 位整数并指定它的哪一部分是十进制小数的比例因子组成。比例因子隐含地是数字 10,上升到 0 到 28 之间的指数。因此,十进制值的二进制表示形式为 ((-2 96到 2 96) / 10 (0 到 28)) ,其中 -2 96-1 等于 MinValue,2 96-1 等于 MaxValue。
缩放因子还保留十进制数中的任何尾随零。尾随零不会影响算术或比较运算中十进制数的值。但是,如果应用了适当的格式字符串,ToString 方法可以显示尾随零。
回答by Tadas ?ukys
What about Math.Round(decimal d, int decimals)?
回答by Christian Hayter
It's tempting to confuse decimalin SQL Server with decimalin .NET; they are quite different.
很容易将decimalSQL Server 中的与decimal.NET 中的混淆;他们是完全不同的。
A SQL Server decimalis a fixed-point number whose precision and scale are fixed when the column or variable is defined.
SQL Serverdecimal是一个定点数,其精度和小数位数在定义列或变量时是固定的。
A .NET decimalis a floating-point number like floatand double(the difference being that decimalaccurately preserves decimal digits whereas floatand doubleaccurately preserve binary digits). Attempting to control the precision of a .NET decimalis pointless, since all calculations will yield the same results regardless of the presence or absence of padding zeros.
甲.NETdecimal就像一个浮点数float和double(不同之处在于decimal准确蜜饯十进制数字,而float且double准确地保存二进制数)。试图控制 .NET 的精度decimal是没有意义的,因为无论是否存在填充零,所有计算都会产生相同的结果。
回答by Amy B
I found that I could "tamper" with the scale by multiplying or dividing by a fancy 1.
我发现我可以通过乘以或除以一个花哨的 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 fabricate a sufficiently precise 1 to change scale factors by known sizes.
我可以制造一个足够精确的 1 以通过已知尺寸改变比例因子。
decimal scaleFactorBase = 1.0m;
decimal scaleFactor = 1m;
int scaleFactorSize = 3;
for (int i = 0; i < scaleFactorSize; i++)
{
scaleFactor *= scaleFactorBase;
}
decimal z = a * scaleFactor;
回答by shamp00
This will remove all the trailing zeros from the decimal and then you can just use ToString().
这将从十进制中删除所有尾随零,然后您可以使用ToString().
public static class DecimalExtensions
{
public static Decimal Normalize(this Decimal value)
{
return value / 1.000000000000000000000000000000000m;
}
}
Or alternatively, if you want an exact number of trailing zeros, say 5, first Normalize() and then multiply by 1.00000m.
或者,如果您想要确切数量的尾随零,例如 5,首先 Normalize(),然后乘以 1.00000m。
回答by sgmoore
The question is - do you really need the precision storedin the decimal, rather than just displaying the decimal to the required precision. Most applications know internally how precise they want to be and display to that level of precision. For example, even if a user enters an invoice for 100 in an accounts package, it still prints out as 100.00 using something like val.ToString("n2").
问题是 - 您是否真的需要以小数形式存储的精度,而不仅仅是将小数显示为所需的精度。大多数应用程序在内部知道他们想要的精确度并显示到该精度水平。例如,即使用户在帐户包中输入 100 的发票,它仍会使用 val.ToString("n2") 之类的内容打印出 100.00。
How can I create b from a? How can I create b from c?
如何从 a 创建 b?如何从 c 创建 b?
c to b is possible.
c 到 b 是可能的。
Console.WriteLine(Math.Round(2.00000000m, 1))
produces 2.0
产生 2.0
a to b is tricky as the concept of introducing precision is a little alien to mathematics.
a 到 b 很棘手,因为引入精度的概念与数学有点陌生。
I guess a horrible hack could be a round trip.
我想一个可怕的黑客可能是一个往返。
decimal b = Decimal.Parse(a.ToString("#.0"));
Console.WriteLine(b);
produces 2.0
产生 2.0

