解析十进制并在右边过滤额外的0?

从XML文件中我收到格式的小数:

1.132000 6.000000 

目前我正在使用Decimal.Parse,如下所示:

 decimal myDecimal = Decimal.Parse(node.Element("myElementName").Value, System.Globalization.CultureInfo.InvariantCulture); 
  • 如何将myDecimal打印到字符串中,如下所示?

     1.132 6 

我不认为有任何标准的数字格式字符串总是会省略尾随无关紧要的零,我担心。

您可以尝试编写自己的十进制规范化方法,但这可能非常棘手。 使用.NET 4中的BigInteger类它是合理可行的,但没有它(或类似的东西),它确实非常难。

编辑:好的,我想这就是你想要的:

 using System; using System.Numerics; public static class DecimalExtensions { // Avoiding implicit conversions just for clarity private static readonly BigInteger Ten = new BigInteger(10); private static readonly BigInteger UInt32Mask = new BigInteger(0xffffffffU); public static decimal Normalize(this decimal input) { unchecked { int[] bits = decimal.GetBits(input); BigInteger mantissa = new BigInteger((uint) bits[0]) + (new BigInteger((uint) bits[1]) << 32) + (new BigInteger((uint) bits[2]) << 64); int sign = bits[3] & int.MinValue; int exponent = (bits[3] & 0xff0000) >> 16; // The loop condition here is ugly, because we want // to do both the DivRem part and the exponent check :( while (exponent > 0) { BigInteger remainder; BigInteger divided = BigInteger.DivRem(mantissa, Ten, out remainder); if (remainder != BigInteger.Zero) { break; } exponent--; mantissa = divided; } // Okay, now put it all back together again... bits[3] = (exponent << 16) | sign; // For each 32 bits, convert the bottom 32 bits into a uint (which won't // overflow) and then cast to int (which will respect the bits, which // is what we want) bits[0] = (int) (uint) (mantissa & UInt32Mask); mantissa >>= 32; bits[1] = (int) (uint) (mantissa & UInt32Mask); mantissa >>= 32; bits[2] = (int) (uint) (mantissa & UInt32Mask); return new decimal(bits); } } class Program { static void Main(string[] args) { Check(6.000m); Check(6000m); Check(6m); Check(60.00m); Check(12345.00100m); Check(-100.00m); } static void Check(decimal d) { Console.WriteLine("Before: {0} - after: {1}", d, d.Normalize()); } } } 

这将从小数中删除所有尾随零,然后您可以使用ToString()

 public static class DecimalExtensions { public static Decimal Normalize(this Decimal value) { return value / 1.000000000000000000000000000000000m; } } 

或者,如果你想要精确的精确度,比如5个小数位,首先是Normalize()然后再乘以1.00000m。

这符合给出的例子,但很不好。 (我认为)

 myDecimal.ToString("#.######") 

有什么其他要求吗? 您是否要操纵值并将操纵值显示为此小数位数?

替代答案涉及递归,如下所示:

  //use like so: myTextbox.Text = RemoveTrailingZeroes( myDecimal.ToString() ); private string RemoveTrailingZeroes(string input) { if ( input.Contains( "." ) && input.Substring( input.Length - 1 ) == "0" ) { //test the last character == "0" return RemoveTrailingZeroes( input.Substring( 0, input.Length - 2 ) ) //drop the last character and recurse again } return input; //else return the original string } 

如果你想要一个扩展方法,那么这是一个选项

  //use like so: myTextbox.Text = myDecimal.ToString().RemoveTrailingZeroes(); private string RemoveTrailingZeroes(this string input) { if ( input.Contains( "." ) && input.Substring( input.Length - 1 ) == "0" ) { //test the last character == "0" return RemoveTrailingZeroes( input.Substring( 0, input.Length - 2 ) ) //drop the last character and recurse again } return input; //else return the original string } 

添加了input.Contains( "." ) &&来自Jon Skeet的评论,但请记住这会让这个速度变得非常慢。 如果你知道你总是有一个小数而且没有像myDecimal = 6000;那样的情况myDecimal = 6000; 那么你可以放弃那个测试,或者你可以将它变成一个类,并根据输入是否包含小数等来拥有几个私有方法。我最简单,“它工作”而不是Enterprise FizzBuzz

如果您只需要执行此操作以显示,那么如何使用自定义格式字符串?

 // decimal has 28/29 significant digits so 30 "#" symbols should be plenty public static readonly string TrimmedDecimal = "0." + new string('#', 30); // ... decimal x = 1.132000m; Console.WriteLine(x.ToString() + " - " + x.ToString(TrimmedDecimal)); // 1.132 decimal y = 6.000000m; Console.WriteLine(y.ToString() + " - " + y.ToString(TrimmedDecimal)); // 6 

在小数点上使用toString(“G29”)怎么样? 这正是你想要实现的目标!