C# 解析十进制并在右侧筛选额外的0?

C# 解析十进制并在右侧筛选额外的0?,c#,string,decimal,C#,String,Decimal,从一个XML文件中,我收到以下格式的小数: 1.132000 6.000000 目前我正在使用Decimal.Parse,如下所示: decimal myDecimal = Decimal.Parse(node.Element("myElementName").Value, System.Globalization.CultureInfo.InvariantCulture); 如何将myDecimal打印为字符串 看起来像下面 1.132 6 我认为没有任何标准的数字格式字符串总是会忽

从一个XML文件中,我收到以下格式的小数:

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

decimal myDecimal = Decimal.Parse(node.Element("myElementName").Value, System.Globalization.CultureInfo.InvariantCulture);
  • 如何将myDecimal打印为字符串 看起来像下面

    1.132
    6
    

我认为没有任何标准的数字格式字符串总是会忽略后面不重要的零,我担心

您可以尝试编写自己的十进制规范化方法,但这可能相当棘手。使用.NET4中的
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());
        }
    }
}
使用系统;
使用系统数字;
公共静态类DecimalExtensions
{
//为了清晰起见,避免隐式转换
私有静态只读BigInteger十=新的BigInteger(10);
私有静态只读BigInteger UInt32Mask=新的BigInteger(0xffffffffU);
公共静态十进制标准化(此十进制输入)
{
未经检查
{
int[]位=十进制.GetBits(输入);
BigInteger尾数=
新的BigInteger((uint)位[0])+
(新的BigInteger((uint)位[1])16;
//这里的循环条件很糟糕,因为我们想要
//要同时执行DivRem部分和指数检查:(
而(指数>0)
{
大整数余数;
biginger divided=biginger.DivRem(尾数,十,余数);
if(余数!=BigInteger.Zero)
{
打破
}
指数--;
尾数=除以;
}
//好的,现在把它重新组合起来。。。

位[3]=(指数这符合给出的示例,但很差。(我认为)

还有什么其他要求?您是否要操纵这些值并将操纵的值显示为这个小数位数

备选答案涉及递归性,如下所示:

  //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;
这样的大小写,那么您可以放弃该测试,或者您可以将其放入一个类中,并根据输入是否包含小数等使用多个私有方法。I是为了最简单和“它能工作”而不是
enterprisefizzbuzz

如果您只需要在显示时这样做,那么使用自定义格式字符串如何

// 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”)怎么样?
这正是您试图实现的目标!

这将从十进制中删除所有尾随的零,然后您可以使用
ToString()


或者,如果您想要精确的精度,比如说小数点后5位,请先使用Normalize()然后乘以1.00000m。

可能的重复:事实上,它似乎是重复的,我不确定使用什么来搜索它,谢谢。请注意,@JonSkeet为您提供了另一个选项,
myDecimal.ToString.TrimEnd({'0});
但是如果字符串不包含decimal@drachenstern它总是一个包含十进制内容或null的字符串,当它为null时,它不会被解析为十进制,感谢您指出。~可能是语言问题,我不知道。“包含十进制”表示如果字符
在字符串中…
6000
不包含小数,而
6000.
6000.0
do…我不知道
decimal myDecimal=6000;Console.WriteLine(myDecimal.ToString())
显示为这三种格式中的任意一种。只要转换为字符串并在返回之前递归删除右侧的零,不是吗?@drachenstern:你可以……但你也必须小心,比如说,“6000”。@JonSkeet~非常正确,我应该在我的回答中添加这一点:实际上有一种格式可以做到这一点:toString(“G29”)我对输入“6000”的内容很满意,您也可以考虑TrimeMead如何使这更容易:“@ Jon Switt我根据您的反馈进行编辑,但如果没有代码< { 0”},则不会修改<代码> 1.02 < /代码>。
@drachenstern:为什么会这样?它不会修剪任何东西,因为0不在末尾。@JonSkeet/facepalm…此外,这意味着您为同一个问题提供了两个答案,没有?好方法。但是,您使用了33个零。如前所述,不需要超过28个零(前面的
1
总共有29个位置)。谢谢,这正是我想要的。对于某些数字,如
0.000010000
需要小心。使用科学符号会导致
1E-05
中断往返的能力,因为
decimal.Parse(“1E-05”)
失败。
// 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
public static class DecimalExtensions
{
    public static Decimal Normalize(this Decimal value)
    {
        return value / 1.000000000000000000000000000000000m;
    }
}