Подтвердить что ты не робот

Разберите десятичный символ и добавьте фильтр 0 справа?

Из файла XML я получаю десятичные знаки в формате:

1.132000
6.000000

В настоящее время я использую Decimal.Parse вот так:

decimal myDecimal = Decimal.Parse(node.Element("myElementName").Value, System.Globalization.CultureInfo.InvariantCulture);
  • Как печатать myDecimal в строке выглядеть ниже?

    1.132
    6
    
4b9b3361

Ответ 1

Я не думаю, что есть стандартные строки с числовым форматированием, которые, как я опасаюсь, всегда будут пропускать незначительные нули.

Вы можете попытаться написать свой собственный метод декомпликации, но это может быть довольно сложно. С классом BigInteger из .NET 4 это было бы разумно выполнимо, но без этого (или что-то подобное) было бы очень сложно.

EDIT: Хорошо, я думаю, что это то, что вы хотите:

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());
        }
    }
}

Ответ 2

Это приведет к удалению всех конечных нулей из десятичной дроби, а затем вы можете просто использовать ToString().

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

Или, если вы хотите точную точность, скажем, 5 знаков после запятой, сначала Normalize(), а затем умножьте на 1.00000 м.

Ответ 3

Это соответствует приведенному примеру, но НЕ БОЛЕЕ. (Я ДУМАЮ)

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;, вы можете отказаться от этого теста, или вы можете сделать это в классе и иметь несколько частных методов, основанных на том, содержит ли вход десятичное число и т.д. я был простейшим и "он работает" вместо Enterprise FizzBuzz

Ответ 4

Если вам нужно сделать это только для отображения, то как насчет использования пользовательской строки формата?

// 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

Ответ 5

Как насчет использования toString ( "G29" ) в десятичной системе? это делает именно то, что вы пытаетесь достичь!