-2

我需要获取一个字符串对象并将其转换为十进制到 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

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

谢谢抢

4

2 回答 2

2

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

  • 将原始文本解析为一个decimal值(这将保留原始小数位数)
  • 使用字符串格式化以精确到小数点后 4 位的字符串结束。(Math.Round确保最多有4DP,但不完全是4DP。)
  • 解析格式化的结果以返回decimal正好为 4DP 的值。

所以是这样的:

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);
    }
} 
于 2013-09-13T13:22:53.847 回答
0

两者Convert.ToDecimal都保留字符串中的尾随零(adecimal.Parse 总共System.Decimal最多可以有 28-29 位数字,因此在大多数情况下,所有尾随零仍有空间)。

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

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

在任何情况下,请考虑指定也接受 an 的重载,并将其作为参数IFormatProvider给出。CultureInfo.InvariantCulture然后转换是独立于当地文化的。

相反,如果您想处理类似字符串"145.83"附加不在字符串中的尾随零,请使用:

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

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

于 2013-09-13T13:21:30.613 回答