我理解decimal
是一种适用于金融和金钱的数字格式,因为它具有固定的精确度。
因此,当加入或减去两个decimals
时,永远不会有精度损失。
考虑到这一点,我可以理解编译器必须禁止操作'decimal
'+'double
',因为可能会丢失精度。
但是当你乘以(或除以)两个decimals
时会发生什么?
让我们考虑一个简单的十进制类型,总共只有4位数,小数点后的精度为2位数(从00.00到99.99)。
您可以定义a = 0.01
然后m = a * a = 0.0001
,被截断为0.00
,因此精度会下降。
尽管精度不高,但编译器认为此操作是合法的。
所以我们在C#中有以下案例:
decimal / int
:尽管精度不合法仍然合法decimal / decimal
:尽管精度不合法仍然合法decimal * decimal
:尽管精度不合法仍然合法decimal * double
:非法(当然,您总是可以使用强制转换覆盖,但此解决方案对我来说并不令人满意。)
还有其他原因我不知道要解释吗?
在处理利率,增值税税率或一般税率时,使用双倍来存储这些值似乎更合乎逻辑,然后能够使用小数。 但我必须在两者之间做出选择:
decimal
(过度杀伤)存储费率。double
然后投射(丑陋)来存储费率。考虑到所有这些,我的问题是:
有没有理由为C#编译器禁止'decimal
'*'double
'?
答案 0 :(得分:1)
仅decimal multiplication (*
) operator 采用decimal
类型的操作数。但是,存在从int
到decimal
的隐式转换,因此编译器会为您int
投射decimal
。
技术上,没有从decimal
到double
的隐式演员(反之亦然,所以编译器不能为你演员;你需要明确演员其中一个操作数。
逻辑,您需要在最后一个上进行强制转换,因为编译器需要知道结果的类型。对于前三个类型,类型很明确 - 由于decimal
到int
的隐式转换,它们都会产生decimal
。
但decimal
* double
的结果应该是什么?它可以是decimal
或double
,具体取决于您的需求。如果你将它分配给一个变量,那么编译器可以推断出来,但如果它是内联的呢? m * a + 1
的类型是什么?
所以你需要一个强制转换来告诉编译器结果类型是什么。
在处理利率,增值税率或一般税率时,使用双倍来存储这些值似乎更合乎逻辑
为什么呢?为什么在无法正确存储0.10 的类型中存储0.10的利率?
decimal
应该用于财务计算和其他需要保留十进制再次激活的计算。
double
应该用于不精确的科学测量(温度,距离)和其他计算,其中速度比十进制表示的准确性更重要。