4

次のような 2 つの値が与えられます。

decimal a = 0.15m;
decimal b = 0.85m;

a + bは常に であり、1.0m両方の値は小数点以下 2 桁までしか指定されておらず、両方の値は>= 0.0mおよびです。<= 1.0m

、およびの可能なすべての Decimal 値に対して、 が常に真になることが保証されていますか? 以下の計算を使用します。x == totalxab

decimal x = 105.99m;
decimal total = (x * a) + (x * b);

またはx == total、小数点以下 2 桁までしかなく、それを超えない場合はありますか?

小数点以下の桁数を無制限に (許可されている限り)指定できる場合でもa、有効である限り、違いはありますか?bDecimala + b = 1.0m

4

2 に答える 2

4

Decimal は、小数点位置を表す数値 10 の符号、整数、および整数指数として格納されます。数値の整数部分 (たとえば、105.99 の 105) が十分に大きくない限り、a + b は常に 1 に等しくなります。式 (x * a) + (x * b) の結果は、常に小数点以下 4 桁の正しい値になります。

float や double とは異なり、精度はデータ型のサイズ (128 ビット) まで失われません。

MSDN から:

Decimal 値型は、正の 79,228,162,514,264,337,593,543,950,335 から負の 79,228,162,514,264,337,593,543,950,335 までの範囲の 10 進数を表します。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);
于 2013-01-03T13:49:08.823 に答える
2

CLRの最大精度decimalは 29 桁です。そのような精度を使用している場合、特に乗算を行う場合は、CLR が処理できなければならない中間結果が必要になるため、実際には近似について話していることになります ( http://msdn.microsoft.com/en-usも参照してください)。 /library/364x0z75.aspx )。

有効桁数が 2 桁の x と有効桁数が 20 桁の a がある場合、x * a の最小精度はすでに 22 桁であり、中間結果にはそれ以上の精度が必要になる可能性があります。

x の有効桁数が常に 2 桁しかなく、a と b の有効桁数を十分に低く抑えることができる場合 (たとえば、22 桁 - かなり適切で、丸め誤差を処理す​​るには 27 桁から十分に離れている可能性があります)、私は ( x * a) + (x * b) は常にかなり正確な計算になるはずです。

最後に、a + b が常に 1.0m を構成するかどうかは、a と b の個々の精度とは関係ありません。

于 2013-01-03T13:51:47.647 に答える