Как лучше всего подойти к округлению десятичных знаков в С#

У меня десятичное значение 18,8. Значения, хранящиеся в этой переменной, могут быть любого типа. Например, это может быть 1.0000000 или 1.00004000 или 5.00000008. Я хотел бы написать метод, чтобы я мог передать ему десятичную дробь и получить округленную строку. Это не было бы проблемой, если бы я знал десятичные разряды, которые хотел бы получить. Но то, что я хотел бы получить, это:

Если это 1.0000000, должно быть возвращено 1.
Если это 1.00004000, должно быть возвращено 1.00004.
Когда это 5.00000008, должно быть возвращено 5.00000008. Таким образом, в основном он должен найти все 0, которые находятся за последней цифрой, отличной от 0, и отрезать их.

Как мне к этому подойти? Какой лучший метод? Я получаю это значение из SQL и помещаю его в десятичную переменную, но затем я хотел бы отобразить его, и наличие 5.0000000, когда оно может отображаться как 5, для меня немного излишне.

Надеюсь, я мог получить некоторые хорошие предложения.


person MadBoy    schedule 18.01.2010    source источник


Ответы (4)


Насколько я знаю, ToString ("0.##" ) подойдет, просто увеличьте количество #, чтобы ваше значение не округлялось. Например.:

decimal d = 1.999m;
string dStr = d.ToString("0.###");

Это создаст строку «1999» (разделитель зависит от используемой культуры).

В результате вы можете использовать обычную очень длинную строку форматирования: "0.############################" - для форматирования всех ваших значений.

person terR0Q    schedule 18.01.2010
comment
Я не знаю, сколько десятичных знаков мне нужно. Это сработало бы, если бы я знал, что хочу отрезать его после 3 цифр или более. Но я хочу отрезать его, только если все цифры являются нулями после последнего не нуля. - person MadBoy; 18.01.2010
comment
Если у вас есть 1.00004000, то после ToString(0.#####################) у вас будет 1.00004. Говоря о МАКСИМАЛЬНОМ количестве знаков #: это 28. Десятичный допускает максимум 28-29 значащих цифр. Это дает 1 для ведущего нуля и 28 для других знаков. Даже если у вас есть что-то вроде 15555.98900008900, все будет в порядке. - person terR0Q; 18.01.2010
comment
Спасибо, это работает. Я должен был протестировать его, прежде чем сомневаться, что он будет работать так, как вы сказали. - person MadBoy; 18.01.2010

Поэтому обрежьте нули с конца.

decimal d = 1.999m;
string dStr = d.ToString().TrimEnd('0').TrimEnd('.');
person Scoregraphic    schedule 18.01.2010
comment
А если есть значение 1 000 000,00? Тогда он теряет все нули, я полагаю? Или остается 1 000 000. - person Webleeuw; 18.01.2010
comment
Он теряет только нули после точки (.). Остается точка, но он может просто добавить еще одну TrimEnd('.'). Для I18N он должен использовать не точку, а разделитель, специфичный для культуры. - person Scoregraphic; 18.01.2010

Вы также можете использовать string.Format и вот документация по различным возможным форматам, но мне нравится Johan Sheehans шпаргалка и еще в качестве краткого справочника.

decimal number=4711.00004711m;
4711.00004711
string.Format("{0:0.#############}",number);
"4711,00004711"
number=42;
42
string.Format("{0:0.#############}",number);
"42"
person Jonas Elfström    schedule 18.01.2010

Взгляните на статью Джона Скитса: http://www.yoda.arachsys.com/csharp/floatingpoint.html

person Grzenio    schedule 18.01.2010
comment
Как статья, обсуждающая binary с плавающей запятой, связана с типом decimal, о котором идет речь в вопросе? - person LukeH; 18.01.2010