次の方法で共有


System.Decimal 構造体

この記事では、この API のリファレンス ドキュメントに補足的な解説を提供します。

Decimal値型は、正の79,228,162,514,264,337,593,543,950,335から負の79,228,162,514,264,337,593,543,950,335までの範囲の10進数を表します。 Decimalの既定値は 0 です。 Decimal値型は、整数と小数部の数字を大量に必要とし、丸め誤差がない財務計算に適しています。 Decimal型では、丸める必要性がなくなるわけではありません。 むしろ、丸めによるエラーを最小限に抑えます。 たとえば、次のコードは、1 ではなく 0.9999999999999999999999999999 という結果を生成します。

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

10 進数は、符号、値の各桁の範囲が 0 から 9 の数値、および数値の整数部分と小数部を区切る浮動小数点の位置を示す拡大縮小率で構成される浮動小数点値です。

Decimal値のバイナリ表現は、96 ビットの整数で構成される 128 ビットと、10 進数の部分を指定するために使用される符号やスケール ファクターなどを表す 32 ビットフラグのセットです。 したがって、フォームの Decimal 値のバイナリ表現 ((-296 から 296) / 10(0 から 28))、-(296-1) は MinValue、296-1MaxValueと等しくなります。 Decimal値のバイナリ表現と例の詳細については、Decimal(Int32[]) コンストラクターと GetBits メソッドを参照してください。

スケール ファクターは、Decimal 数値の末尾にゼロを維持します。 末尾のゼロは、算術演算または比較演算の Decimal 数値の値には影響しません。 ただし、適切な書式指定文字列が適用されている場合は、 ToString メソッドによって末尾のゼロが表示される可能性があります。

変換に関する考慮事項

この型は、 Decimal 値を SByteInt16Int32Int64ByteUInt16UInt32、および UInt64 の値に変換するメソッドを提供します。 これらの整数型から Decimal への変換は、情報を失ったり例外をスローしたりしない変換を拡大しています。

Decimalから任意の整数型への変換では、Decimal値を最も近い整数値に 0 に丸める変換が縮小されています。 C# などの一部の言語では、 Decimal 値から Char 値への変換もサポートされています。 変換先の型でこれらの変換の結果を表すことができない場合は、 OverflowException 例外がスローされます。

Decimal型には、Decimal値とSingle値との間でDouble値を変換するメソッドも用意されています。 DecimalからSingleまたはDoubleへの変換では、変換された値の大きさに関する情報ではなく、精度が失われる可能性がある変換が縮小されます。 変換で例外は発生しません。

SingleまたはDoubleからDecimalへの変換では、変換の結果をOverflowExceptionとして表すことができない場合、Decimal例外がスローされます。

Decimal 値に対して操作を実行する

Decimal型は、加算、減算、除算、乗算、単項否定などの標準的な数学演算をサポートしています。 Decimal メソッドを呼び出すことで、GetBits値のバイナリ表現を直接操作することもできます。

2 つの Decimal 値を比較するには、標準の数値比較演算子を使用するか、 CompareTo または Equals メソッドを呼び出すことができます。

Math クラスのメンバーを呼び出して、数値の絶対値の取得、2 つの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