C#将字符串转换为十进制4dp

时间:2013-09-13 13:18:53

标签: c#

我需要取一个字符串对象并将其转换为小数到4 dp。

例如:

string val = "145.83011";
decimal sss = Math.Round(Convert.ToDecimal(val), 4);

带回145.8301 - 好

然而:

string val = "145.8300";
decimal sss = Math.Round(Convert.ToDecimal(val), 4);

带回145.83 我需要它是145.8300

我需要十进制格式,所以不能使用字符串格式选项。

由于 抢劫

2 个答案:

答案 0 :(得分:2)

一种选择是使用字符串操作三次:

  • 将原始文本解析为decimal值(这将保留原始小数位数)
  • 使用字符串格式以完全 4个小数位的字符串结尾。 (Math.Round确保最多 4DP,但不完全 4DP。)
  • 解析格式化结果以恢复到{4}的decimal值。

这样的事情:

public static decimal Force4DecimalPlaces(string input)
{
    decimal parsed = decimal.Parse(input, CultureInfo.InvariantCulture); 
    string intermediate = parsed.ToString("0.0000", CultureInfo.InvariantCulture);
    return decimal.Parse(intermediate, CultureInfo.InvariantCulture);
}

我反复使用这样的字符串转换,但替代方案相对棘手。您可以获取原始位,拆分不同的部分以找到尾数和比例,然后适当调整......或者您可以计算出一些算术运算序列以达到正确的比例。 (Jeppe的乘以1.0000m的方法可能完全正确 - 我只是不知道它是否记录是正确的。至少值得在适当的测试中添加各种数字你期待看到。)

请注意,就我所知,上述代码将在一半上执行,因此1.12345将转换为1.1235。

评论中输出的示例:

using System;
using System.Globalization;

class Test
{
    static void Main()        
    {
        Console.WriteLine(Force4DecimalPlaces("0.0000001")); // 0.0000
        Console.WriteLine(Force4DecimalPlaces("1.000000"));  // 1.0000
        Console.WriteLine(Force4DecimalPlaces("1.5"));       // 1.5000
        Console.WriteLine(Force4DecimalPlaces("1.56789"));   // 1.5679
    }

    public static decimal Force4DecimalPlaces(string input)
    {
        decimal parsed = decimal.Parse(input, CultureInfo.InvariantCulture); 
        string intermediate = parsed.ToString("0.0000", CultureInfo.InvariantCulture);
        return decimal.Parse(intermediate, CultureInfo.InvariantCulture);
    }
} 

答案 1 :(得分:0)

Convert.ToDecimaldecimal.Parse 保留字符串中的尾随零(System.Decimal总共最多可以包含28-29位数,因此大多数情况下都是如此所有尾随零的空间仍然存在。)

并且Math.Round(..., 4)会将尾随零保留到小数点后的第四位。

因此,问题的前提是错误的。你的例子确实带回了你想要的东西。

在任何情况下,考虑指定同时包含IFormatProvider的重载,并将CultureInfo.InvariantCulture作为参数。然后转换独立于当地文化。

如果您想要处理 "145.83" 附加字符串中不包含的尾随零的字符串,请使用:

string val = "145.83";
decimal sss = Math.Round(
    decimal.Parse(val, CultureInfo.InvariantCulture) * 1.0000m,
    4);

Epilog:如果您不喜欢乘以1.0000m之类的数字,请使用decimal.GetBits来获取内部表示。通过乘以或除以适当的10的幂来调整整数“部分”,并通过减去或加上相应的数字来调整比例“部分”。该比例计算从96位整数开始向左移动小数点的位数。