Структуру System.Decimal

В этой статье приводятся дополнительные замечания к справочной документации по этому API.

Тип Decimal значения представляет десятичные числа, начиная от положительных 79 228 162 514 264 337 593 543 950, 335 до отрицательного 79 228 162 514 264 337 593 543 950 335. Значение Decimal по умолчанию равно 0. Тип Decimal значения подходит для финансовых вычислений, требующих большого количества значимых целочисленных и дробных цифр и без ошибок округления. Тип Decimal не устраняет необходимость округления. Но он сводит к минимуму ошибки, возникающие из-за округления. Например, следующий код создает результат 0.999999999999999999999999999999999999 вместо 1.

decimal dividend = Decimal.One;
decimal divisor = 3;
// The following displays 0.9999999999999999999999999999 to the console
Console.WriteLine(dividend/divisor * divisor);
let dividend = Decimal.One
let divisor = 3m
// The following displays 0.9999999999999999999999999999 to the console
printfn $"{dividend/divisor * divisor}"
Dim dividend As Decimal = Decimal.One
Dim divisor As Decimal = 3
' The following displays 0.9999999999999999999999999999 to the console
Console.WriteLine(dividend/divisor * divisor)

Когда результат деления и умножения передается Round методу, результат не терпит потери точности, как показано в следующем коде.

decimal dividend = Decimal.One;
decimal divisor = 3;
// The following displays 1.00 to the console
Console.WriteLine(Math.Round(dividend/divisor * divisor, 2));
let dividend = Decimal.One
let divisor = 3m
// The following displays 1.00 to the console
printfn $"{Math.Round(dividend/divisor * divisor, 2)}"
Dim dividend As Decimal = Decimal.One
Dim divisor As Decimal = 3
' The following displays 1.00 to the console
Console.WriteLine(Math.Round(dividend/divisor * divisor, 2))

Десятичное число — это значение с плавающей запятой, состоящее из знака, числовое значение, в котором каждая цифра в диапазоне от 0 до 9, а также коэффициент масштабирования, указывающий позицию с плавающей десятичной запятой, которая отделяет целые и дробные части числового значения.

Двоичное представление Decimal значения равно 128-разрядным значениям, состоящим из 96-разрядного целого числа, и 32-разрядный набор флагов, представляющих такие вещи, как знак и коэффициент масштабирования, используемый для указания части его десятичной дроби. Поэтому двоичное представление Decimal значения формы (-2 96 до 296) / 10(0 до 28)), где -(2 96-1) равноMinValue, а 296-1 равно.MaxValue Дополнительные сведения о двоичном представлении значений Decimal и примере см Decimal(Int32[]) . в конструкторе и методе GetBits .

Коэффициент масштабирования также сохраняет все конечные нули числа.Decimal Конечные нули не влияют на значение Decimal числа в арифметических операциях или операциях сравнения. Однако конечные нули могут быть выявлены методом ToString , если применяется соответствующая строка формата.

Рекомендации по преобразованию

Этот тип предоставляет методы, которые преобразуют Decimal значения в , и из SByte, Int32Int16Int64и ByteUInt16UInt32UInt64 значений. Преобразования из этих целочисленных типов для Decimal расширения преобразований, которые никогда не теряют информацию или вызывают исключения.

Преобразования из Decimal любого целочисленного типа сужают преобразования, округляющие Decimal значение до ближайшего целочисленного значения к нулю. Некоторые языки, такие как C#, также поддерживают преобразование значений Decimal в Char значения. Если результат этих преобразований не может быть представлен в целевом типе, OverflowException создается исключение.

Тип Decimal также предоставляет методы, которые преобразуют Decimal значения в и из и из Single и Double значений. Преобразования из DecimalSingleDouble или сужают преобразования, которые могут потерять точность, но не сведения о величине преобразованного значения. Преобразование не создает исключение.

Преобразования из Single или DoubleDecimal для создания OverflowException исключения, если результат преобразования не может быть представлен в виде Decimal.

Выполнение операций с десятичными значениями

Тип Decimal поддерживает стандартные математические операции, такие как добавление, вычитание, деление, умножение и унарное отрицание. Вы также можете работать непосредственно с двоичным представлением Decimal значения, вызвав GetBits метод.

Для сравнения двух Decimal значений можно использовать стандартные операторы сравнения числовых значений CompareToEquals или вызвать метод.

Можно также вызвать члены Math класса для выполнения широких числовых операций, включая получение абсолютного значения числа, определение максимального или минимального значения двух Decimal значений, получение знака числа и округление числа.

Примеры

В следующем коде показано использование функции Decimal.

/// <summary>
/// Keeping my fortune in Decimals to avoid the round-off errors.
/// </summary>
class PiggyBank {
    protected decimal MyFortune;

    public void AddPenny() {
        MyFortune = Decimal.Add(MyFortune, .01m);
    }

    public decimal Capacity {
        get {
            return Decimal.MaxValue;
        }
    }

    public decimal Dollars {
        get {
            return Decimal.Floor(MyFortune);
        }
    }

    public decimal Cents {
        get {
            return Decimal.Subtract(MyFortune, Decimal.Floor(MyFortune));
        }
    }

    public override string ToString() {
        return MyFortune.ToString("C")+" in piggy bank";
    }
}
/// Keeping my fortune in Decimals to avoid the round-off errors.
type PiggyBank() =
    let mutable myFortune = 0m

    member _.AddPenny() =
        myFortune <- Decimal.Add(myFortune, 0.01m)

    member _.Capacity =
        Decimal.MaxValue

    member _.Dollars =
        Decimal.Floor myFortune

    member _.Cents =
        Decimal.Subtract(myFortune, Decimal.Floor myFortune)

    override _.ToString() =
        $"{myFortune:C} in piggy bank"
' Keeping my fortune in Decimals to avoid the round-off errors.
Class PiggyBank
    Protected MyFortune As Decimal

    Public Sub AddPenny()
        MyFortune = [Decimal].Add(MyFortune, 0.01D)
    End Sub

    Public ReadOnly Property Capacity() As Decimal
        Get
            Return [Decimal].MaxValue
        End Get
    End Property

    Public ReadOnly Property Dollars() As Decimal
        Get
            Return [Decimal].Floor(MyFortune)
        End Get
    End Property

    Public ReadOnly Property Cents() As Decimal
        Get
            Return [Decimal].Subtract(MyFortune, [Decimal].Floor(MyFortune))
        End Get
    End Property

    Public Overrides Function ToString() As String
        Return MyFortune.ToString("C") + " in piggy bank"
    End Function
End Class