Непонятное поведение System.Decimal
От: Kostyan2204  
Дата: 29.03.07 03:20
Оценка:
Приветствую!

Разъясните такое поведение типа decimal.

Код №1
-------
decimal a = 0.00003m;
MessageBox.Show(a.ToString());


Появится сообщение 0,00003



Код №2
------
Есть таблица в БД MS SQL Server 2000 в которой есть поле типа decimal(24,7).
В этом поле храниться величина 0,00003


SqlDataReader rdr = cmd.ExecuteReader();
rdr.Read();

decimal a = rdr.GetDecimal(1);
MessageBox.Show(a.ToString());

В этом случае на экране появится сообщение: 0,0000300

Внимание, вопрос: почему так происходит?
Как избавиться от последних нулей?

P.S.
Если Коде №2 использовать общее форматирование a.ToString("Gxx"), то возвращается число в научной натации.
Непонятное поведение System.Decimal
От: nikov США http://www.linkedin.com/in/nikov
Дата: 29.03.07 07:05
Оценка: 18 (2)
#Имя: FAQ.dotnet.decimal
Здравствуйте, Kostyan2204, Вы писали:

K>Разъясните такое поведение типа decimal.


Дело в том, что переменная типа decimal помимо значимых десятичных цифр содержит масштаб (scale). Хотя он и не учитывается при сравнении двух величин с помощью оператора == или метода Equals, он, тем не менее, влияет на внутреннее двоичное представление этих велечин и на значение, возвращаемое методом ToString.
MSDN

Decimal Structure
.....
The scaling factor also preserves any trailing zeroes in a Decimal number. Trailing zeroes do not affect the value of a Decimal number in arithmetic or comparison operations. However, trailing zeroes can be revealed by the ToString method if an appropriate format string is applied.


Для разъяснения можно посмотреть такой код:

using System;
using System.Globalization;

class Program
{
    static void Main()
    {
        decimal x = decimal.Parse("0.10", CultureInfo.InvariantCulture);
        decimal y = decimal.Parse("0.100", CultureInfo.InvariantCulture);

        Console.WriteLine(x == y);
        Console.WriteLine(x.Equals(y));

        Console.WriteLine(BitConverter.ToString(ToByteArray(decimal.GetBits(x))));
        Console.WriteLine(BitConverter.ToString(ToByteArray(decimal.GetBits(y))));

        Console.WriteLine(x.ToString(CultureInfo.InvariantCulture));
        Console.WriteLine(y.ToString(CultureInfo.InvariantCulture));
    }

    static byte[] ToByteArray(int[] source)
    {
        if (source == null) throw new ArgumentNullException("source");
        int len = source.Length * sizeof (int);
        byte[] dest = new byte[len];
        Buffer.BlockCopy(source, 0, dest, 0, len);
        return dest;
    }
}



True
True
0A-00-00-00-00-00-00-00-00-00-00-00-00-00-02-00
64-00-00-00-00-00-00-00-00-00-00-00-00-00-03-00
0.10
0.100
Re[2]: Непонятное поведение System.Decimal
От: nikov США http://www.linkedin.com/in/nikov
Дата: 29.03.07 07:10
Оценка:
N>влияет на внутреннее двоичное представление этих велечин

Прошу прощения, опечатка. Имелось в виду "величин".
Re: Непонятное поведение System.Decimal
От: Аноним  
Дата: 29.03.07 07:15
Оценка:
[skipped code]
K>В этом случае на экране появится сообщение: 0,0000300
K>Как избавиться от последних нулей?

decimal dec = decimal.Round (dec, 5);
Re[2]: Непонятное поведение System.Decimal
От: Kostyan2204  
Дата: 29.03.07 08:48
Оценка:
А>[skipped code]
K>>В этом случае на экране появится сообщение: 0,0000300
K>>Как избавиться от последних нулей?

А>
А>decimal dec = decimal.Round (dec, 5);
А>



дело в том, что если в табличке будет значение 0,0000130, то
decimal dec = decimal.Round (dec, 5);

выдаст 0,00001.

Можно ли выводит любые значения, игнорируя последние нули?
Re[3]: Непонятное поведение System.Decimal
От: Lloyd Россия  
Дата: 29.03.07 08:50
Оценка:
Здравствуйте, Kostyan2204, Вы писали:

K>Можно ли выводит любые значения, игнорируя последние нули?


Тупо тримнуть хвостовые нули.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.