【问题标题】:How to String.Format decimal with unlimited decimal places?如何 String.Format 具有无限小数位的小数?
【发布时间】:2011-10-17 14:23:42
【问题描述】:

我需要将十进制数转换为具有千组和无限(可变)十进制数的格式化字符串:

1234 -> "1,234"
1234.567 -> "1,234.567"
1234.1234567890123456789 -> "1,234.1234567890123456789"

我尝试了String.Format("{0:#,#.#}", decimal),但它会将任何数字修剪到最多 1 个小数位。

【问题讨论】:

标签: c#


【解决方案1】:

你可以多次使用#(见Custom Numeric Format Strings):

string.Format("{0:#,#.#############################}", decimalValue)

或者,如果您只是直接格式化一个数字,您也可以使用decimal.ToString 和格式字符串。

但是,没有办法包含“无限十进制数”。如果没有支持任意精度浮点数的库(例如,使用 Extreme Numerics 中的 BigFloat 之类的东西),您最终会遇到精度问题。即使decimal type 的精度也有限制(28-29 位有效数字)。除此之外,您还会遇到其他问题。

【讨论】:

  • 不幸的是,这不是所有十进制类型(如双精度)的通用解决方案。
  • @jurev:是的,但仅限于所讨论类型的精度限制。正如我所说,所有标准浮点类型的精度都是有限的——你只能按照类型的精度工作。
  • @jurev: double 不是十进制类型,它是精度有限的二进制浮点数。
  • @jurev 准确地说是 15-16 位 msdn.microsoft.com/en-us/library/678hzkk9.aspx
【解决方案2】:

正如我所说,十进制类型的精度为 28-29 位。

decimal mon = 1234.12345678901234567890123M;
var monStr = mon.ToString("#,0.##############################");
var monStr2 = String.Format("{0:#,0.##############################}", mon);

这里小数点后有30x#:-)

我已将# 更改为0,这样0.15 就不会写成.15

【讨论】:

    【解决方案3】:

    这应该可以解决问题

    string DecimalToDecimalsString(decimal input_num)
            {            
                decimal d_integer = Math.Truncate(input_num); // = 1234,0000...
                decimal d_decimals = input_num-d_integer; // = 0,5678...
    
                while (Math.Truncate(d_decimals) != d_decimals)
                    d_decimals *= 10; //remove decimals
    
                string s_integer = String.Format("{0:#,#}", d_integer);
                string s_decimals = String.Format("{0:#}", d_decimals);
    
                return s_integer + "." + s_decimals;
            }
    

    用其他类型替换小数也应该有效。

    【讨论】:

    • 有趣的解决方案,但它不适用于国际格式(有些国家甚至有不同的 1000 组分隔符用于整数和小数部分)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-23
    • 2022-06-28
    • 2012-06-26
    相关资源
    最近更新 更多