Как округлить десятичную дробь для 2 десятичных знаков - PullRequest
3 голосов
/ 03 ноября 2011

У меня есть 2 десятичных числа:

1999,9999
1999,99

если я использую функцию

decimal.Round(Temp, 2);

тогда у меня есть такие результаты:

2000,00
1999,99

Как сделать так, чтобы, даже если есть 1999,999999, оно округляется до 1999,99 вместо 2000,00.

Спасибо.

Ответы [ 5 ]

4 голосов
/ 03 ноября 2011

Округление всегда заставит 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);
2 голосов
/ 03 ноября 2011

Вам нужно усечь цифры.Один из способов сделать это: decimal.Truncate(<number> * 100) / 100;

0 голосов
/ 11 декабря 2012

Попробуйте это:

Convert.ToDecimal(x.ToString("#.##"));
0 голосов
/ 03 ноября 2011

Ну, краткий ответ таков: 1999,9999 округленное до 2 десятичных знаков на самом деле 2000,00.

Существует несколько различных стратегий округления & mdash; http://en.wikipedia.org/wiki/Rounding & mdash; Вы можете прочитать о них.

Но если вы не хотите округлять значение и вместо этого урезать его, то это должно сработать. scale - это степень 10, указывающая положение, в котором должно произойти усечение. Если scale является отрицательной степенью 10 (например, 10 -2 ), то будет происходить усечение на столько цифр справа от десятичной запятой. Если scale неотрицательно, то усечение происходит слева от десятичной точки (например, шкала 1 aka 10 0 будет усекать дробь, и scale из 100 (или 10 2 ) обрежет все справа от места 100, преобразовав 1999.9999m в 1900m.

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

Кроме того, вы можете написать метод, подобный следующему коду. Это работает для любой шкалы: отрицательные значения для шкала усекают столько позиций справа от десятичной точки; ненулевые значения усекаются слева от десятичной точки.

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 включительно. Я бы создал decimal[] с отрицательной нижней границей: тогда проверка того, находится ли указанный масштаб в справочной таблице, состоит только из проверки, является ли значение масштаба допустимым индексом в массиве. Если это так, вытащите коэффициент, используя значение шкалы в качестве индекса.

  • Вторая оптимизация будет заключаться в кэшировании мощности 10 значений при их вычислении. Если вы уже вычислили значение, вам не нужно его пересчитывать, просто извлеките его из кэша, используя шкалу в качестве ключа.

0 голосов
/ 03 ноября 2011
decimal d = 1999.999999; //or any

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