如何在 .NET 中将双精度值转换为具有固定小数位数的小数类型值
Posted
技术标签:
【中文标题】如何在 .NET 中将双精度值转换为具有固定小数位数的小数类型值【英文标题】:How do I convert a double value to a value of type decimal with a fixed number of decimal places in .NET 【发布时间】:2020-07-12 22:05:24 【问题描述】:在 .NET 中,我有一个 double 变量中的值,我需要将其转换为具有指定小数位数的十进制,并根据需要四舍五入。我正在寻找的答案将有一个类似这样的原型:
decimal DoubleToDecimal(double value, int numberOfDecimalPlaces)
我能想到的最好的方法是将双精度转换为具有正确小数位数的字符串,然后将其解析回小数:
return decimal.Parse(
double.ToString("0." + new string(numberOfDecimalPlaces,'0'))
);
我更喜欢不涉及到/从字符串转换的方式,因为这似乎效率很低。
【问题讨论】:
【参考方案1】:decimal DoubleToDecimal(double value, int numberOfDecimalPlaces)
return Math.Round((decimal)value, numberOfDecimalPlaces);
如果您需要保留尾随零,请尝试使用:
Math.Round((decimal)value,numberOfDecimalPlaces)+(0M*((decimal)Math.Pow(10,-numberOfDecimalPlaces)))
见:
> Math.Round(dd,20)
3.2222222
> (0M*((decimal)Math.Pow(10,-20)))
0.00000000000000000000
> Math.Round(dd,20)+(0M*((decimal)Math.Pow(10,-20)))
3.22222220000000000000
【讨论】:
稍微说明一下:在这里创建一个无用的方法,并添加一个CPU Proc Call和一个CPU Stack Push & Pop for什么都没有,因此这会减慢执行速度只是为了一个包装器......除非有人想要一个包装器。 @olivier-rogier 我同意,但最初的问题是用这种方法提出的。而且我已经用更复杂的代码更新了我的答案,保留了尾随零,进入一个方法是有意义的。 确实,您提供所需的东西是对的。这只是一个小小的评论,以防万一:) 不管怎样,一个小小的包装方法很可能会被编译器内联 永远不要假设这样的事情:VS C# 编译器不会通过重复代码来使用 内联方法 进行优化 => 发布二进制文件:IL_000a: call valuetype [mscorlib]System.Decimal ConsoleApp.Program::DoubleToDecimal(float64, int32)
。因此,对于一个无用的包装器,除非您愿意,否则这可能是一种可接受的设计选择,可以将需求与实现分离,您有一个 CPU Proc 调用,因此在调用之前有一个 CPU 堆栈推送,在调用之后有一个 CPU 堆栈弹出。 Intel® 64 and IA-32 Architectures Software Developer Manuals【参考方案2】:
这就是你要找的。 Convert.ToDecimal 将双精度数转换为十进制 Math.Round 将小数四舍五入到所需的小数位数。
decimal DoubleToDecimal(double value, int numberOfDecimalPlaces)
return Math.Round(Convert.ToDecimal(value), numberOfDecimalPlaces);
【讨论】:
以上是关于如何在 .NET 中将双精度值转换为具有固定小数位数的小数类型值的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 stringstream 在 C++ 中将字符串转换为双精度值 [关闭]
Java - Decimal Format.parse 返回具有指定小数位数的双精度值