如何将小数保留两位小数点

3

我有两个十进制数:

1999,9999
1999,99

如果我使用函数

decimal.Round(Temp, 2);

然后我有以下结果:
2000,00
1999,99

如何确保即使是1999.999999也会四舍五入为1999.99而不是2000.00。

谢谢。


你不想四舍五入,而是要截断小数部分。 - BrokenGlass
这个主题已经有一个现有的SO问题 - 我认为它提供了你正在寻找的答案。https://dev59.com/TnVC5IYBdhLWcg3wjx1d - Matt Hogan-Jones
1
@MattJones,那个链接展示了他实际上想要避免的行为。 - Anthony Pegram
@AnthonyPegram 你是对的,我感到羞愧,没有完全阅读一个SO答案就引用它。 - Matt Hogan-Jones
5个回答

4
四舍五入会使1999.999变成2000。我猜你想要截取小数点之前的数字。
你可以通过乘除法来实现此操作:
decimal TruncateToPlaces(decimal value, int places)
{
    decimal multiplier = Math.Pow(10m, places);
    return decimal.Truncate(value * multiplier) / multiplier;
}

你可以执行以下操作:
decimal value = TruncateToPlaces(1999.9999, 2);

尝试运行 TruncateToPlaces(Decimal.MaxValue - 10, int.MaxValue)。 - Viacheslav Smityukh
是的,我知道这种方法不能处理极端情况。一般来说,我尝试让我的答案展示所需的技术来使某些东西正常工作,但不包括每个参数检查/异常处理/范围检查,因为这样只会使答案变得清晰。这对于OP需要的情况完全可以胜任... - Reed Copsey
你说得对,这是针对那个问题的完美解决方案。但是这并不适用于真实的财务数据。很抱歉,是我的错误,我将你的解决方案与我的金融软件开发经验进行了比较。 - Viacheslav Smityukh

2

您需要截断小数位。一种方法是:decimal.Truncate(<number> * 100) / 100;


0

简单来说,1999.9999 保留两位小数实际上是 2000.00

有许多不同的舍入策略 — http://en.wikipedia.org/wiki/Rounding — 您可能想要了解一下。

但是,如果您不想四舍五入该值,而是想截断它,那么这应该适合您。 scale 是一个10的幂,表示应在哪个位置进行截断。 如果 scale 是负的10的幂(例如,10-2),则将在小数点右侧截断那么多位数字。 如果 scale 是非负的,则截断发生在小数点左侧(例如,比例尺为 1,也就是 100 将截断分数,而比例尺为100(或 102)将截断百位数右侧的所有内容,将 1999.9999m 转换为 1900m

decimal TruncateToHundredthsPlace( decimal value )
{
  const decimal scale = 0.01m ; // 10^-2
  decimal result = value - ( value % 0.01m ) ;
  return results ;
}

或者,您可以编写以下代码的方法。它适用于任何比例:负值的scale将截断小数点右侧的许多位置;非零值将截断小数点左侧。

public static decimal Truncate( decimal value , int scale )
{
    Decimal factor = Power(10,scale) ;
    decimal result = value - ( value % factor ) ;

    return result ;
}
private static decimal Power( int m , int n )
{
    if ( m < 1 ) throw new ArgumentOutOfRangeException("m") ;

    Decimal @base  = (decimal) m ;
    Decimal factor = 1m ; // m^0 = 1
    while ( n > 0 )
    {
        factor *= @base ;
        --n ;
    }
    while ( n < 0 )
    {
        factor /= @base ;
        ++n ;
    }
    return factor ;
}

在十进制中计算10的幂是很耗费资源的。不过有两个简单的优化方法可以加速:

  • 首先,预先计算一些合理数量的10的幂并存储在静态查找表中,例如10-10到10+10。我会创建一个带有负下标的decimal[]:这样检查指定的精度是否在查找表中只需要检查该精度值是否为数组的有效索引即可。如果是,则使用该精度值作为索引将因子提取出来。

  • 第二个优化是在计算时缓存10的幂值。如果已经计算了该值,则无需重新计算,只需使用精度作为键从缓存中获取即可。


0

试试这个:

Convert.ToDecimal(x.ToString("#.##"));

0
decimal d = 1999.999999; //or any

int temp = d*100; //199999
decimal result = temp/(decimal)100; //199.99

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接