由于操作 '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 / int
:合法,尽管精度有所损失
decimal / decimal
:合法,尽管丢失了精度
decimal * decimal
:合法,尽管丢失了精度
decimal * double
: 非法
(当然,你总是可以用强制转换覆盖,但这个解决方案对我来说并不令人满意。)
还有其他我不知道的原因可以解释吗?
在处理利率、增值税税率或一般利率时,对我来说,使用双精度数来存储这些值,然后能够将它们与小数一起使用似乎更合乎逻辑。
但我必须在两者之间做出选择:
- 使用
decimal
(矫枉过正)存储速率。
- 使用
double
存储速率然后进行转换(丑陋)。
考虑到所有这些,我的问题是:
'decimal
' * 'double
' 是否被 C# 编译器禁止?
decimal multiplication (*
) operator仅接受decimal
类型的操作数。但是,存在从 int
到 decimal
的隐式转换,因此编译器会为您将 int
转换为 decimal
。
技术上,没有从 decimal
到 double
的隐式转换(反之亦然,因此编译器无法为您转换;您需要显式地转换其中一个操作数。
逻辑上,你需要对最后一个进行强制转换,因为编译器需要知道 result 的类型。对于前三个,类型是明确的——由于从 int
到 decimal
.
的隐式转换,它们都会导致 decimal
但是 decimal
* double
的结果应该是什么?根据您的需要,它可以是 decimal
或 double
。如果您将它分配给一个变量,那么编译器 可以 推断,但是如果它是内联完成的呢? 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
应用于不精确的科学测量(温度、距离)和其他计算,其中 速度 比小数表示的准确性更重要。
我知道 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
存储速率然后进行转换(丑陋)。
考虑到所有这些,我的问题是:
'decimal
' * 'double
' 是否被 C# 编译器禁止?
decimal multiplication (*
) operator仅接受decimal
类型的操作数。但是,存在从 int
到 decimal
的隐式转换,因此编译器会为您将 int
转换为 decimal
。
技术上,没有从 decimal
到 double
的隐式转换(反之亦然,因此编译器无法为您转换;您需要显式地转换其中一个操作数。
逻辑上,你需要对最后一个进行强制转换,因为编译器需要知道 result 的类型。对于前三个,类型是明确的——由于从 int
到 decimal
.
decimal
但是 decimal
* double
的结果应该是什么?根据您的需要,它可以是 decimal
或 double
。如果您将它分配给一个变量,那么编译器 可以 推断,但是如果它是内联完成的呢? 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
应用于不精确的科学测量(温度、距离)和其他计算,其中 速度 比小数表示的准确性更重要。