由于操作 'decimal' * 'decimal' 导致精度损失但被授权,为什么操作 'decimal' * 'double' 被禁止?

As operation 'decimal' * 'decimal' result in a loss of precision but is authorized, why is the operation 'decimal' * 'double' forbidden?

我知道 decimal 是一种适用于一般金融和货币的数字格式,因为它具有固定的精度。

所以当对两个 decimals 进行加法或减法时,永远不会有精度损失。

考虑到这一点,我可以理解编译器必须禁止操作“decimal”+“double”,因为这可能会导致精度损失。

但是当你乘(或除)两个 decimals 时会发生什么?

让我们考虑一个简单的十进制类型,总共只有4位数字,小数点后有2位精度(从00.00到99.99)。

你可以定义a = 0.01

然后 m = a * a = 0.0001,被截断为 0.00,因此精度有所损失。

尽管精度有所损失,但编译器认为此操作是合法的。

所以我们在 C# 中有以下情况:

(当然,你总是可以用强制转换覆盖,但这个解决方案对我来说并不令人满意。)

还有其他我不知道的原因可以解释吗?

在处理利率、增值税税率或一般利率时,对我来说,使用双精度数来存储这些值,然后能够将它们与小数一起使用似乎更合乎逻辑。 但我必须在两者之间做出选择:

考虑到所有这些,我的问题是:

'decimal' * 'double' 是否被 C# 编译器禁止?

decimal multiplication (*) operator接受decimal类型的操作数。但是,存在从 intdecimal 的隐式转换,因此编译器会为您将 int 转换为 decimal

技术上,没有从 decimaldouble 的隐式转换(反之亦然,因此编译器无法为您转换;您需要显式地转换其中一个操作数。

逻辑上,你需要对最后一个进行强制转换,因为编译器需要知道 result 的类型。对于前三个,类型是明确的——由于从 intdecimal.

的隐式转换,它们都会导致 decimal

但是 decimal * double 的结果应该是什么?根据您的需要,它可以是 decimaldouble。如果您将它分配给一个变量,那么编译器 可以 推断,但是如果它是内联完成的呢? m * a + 1 的类型是什么?

所以你需要一个强制转换来告诉编译器结果类型是什么。

When dealing with interest rate, or VAT rate, or rates in general, it would seem more logic to me to use a double to store these values

为什么?为什么要将 0.10 的利率存储在 不能准确存储 0.10 的类型中?

decimal应用于财务计算和其他需要保留十进制表示的计算。

double 应用于不精确的科学测量(温度、距离)和其他计算,其中 速度 比小数表示的准确性更重要。