C# decimal and double
据我所知,十进制用于精确计算,建议用于货币计算。double提供更好的范围,但精度较低,比decimal快得多。
如果我有时间和速率,我觉得double适合时间,decimal适合速率。我不能将这两种方法混合起来运行计算,而不进行强制转换,这又是另一个性能瓶颈。这里最好的方法是什么?只需使用小数表示时间和速率?
- 你说的时间是什么意思?毫秒?几分钟?蜱虫?所有这些情况都是长的或十进制的。
- 最佳方法取决于您的需求。正如您没有指定,那么您可能真的没有,这意味着进入小数点,然后继续。
- 在波斯,我认为TimeSpan最适合时间。对于速率,这取决于你用它做什么。
- 除非您在执行数百万次的计算中需要极快的速度,否则只需执行decimal。
- 你经常谈论性能问题。它们是真的吗(以双/十进制选择为原因进行测量和识别)?或者,您是否预测到一个不存在但不确定的潜在问题?
- 它是模糊的,但时间和速率往往是物理性质。你必须测量的那种东西,任何测量都有隐含的不精确性,而且它们很少少于百万分之一。足够好,可以做两倍,精确到四分之一,比需要的精度高9个数量级。
- @Hanspassant,你是对的,但是对于浮点值,有时缺乏精度会产生0.800000001或0.999999之类的输出,或者使0.1f == 0.1之类的东西出错。所以你必须对这些类型更加小心。
- 你认为十进制不会发生这种情况吗?csonole.writeline(3米*(1米/3米))
- 这是因为小数是完全精确的,但达到了极限,得到这个结果几乎是合理的。使用浮动可以得到意外的值,比如1f/3f==0.333333343。这有多可接受?当您再次执行*3时,您只是在撤消先前给您的错误浮动。小数会给你0.333333333333333333333333333333。另外,0.1f*1e6==100000.00149016112。多年来,浮点数给我带来的麻烦比小数多(实际上我不记得小数有什么问题)。只需看看javascript对浮动的所有问题…关键是要了解这些差异。
两者都使用double。decimal用于货币或其他以10为基数表示数字很重要的情况。如果你不关心数字的基10表示,就不要使用decimal。对于时间或物理量变化率之类的事情,基本10表示通常不重要,因此decimal不是最合适的选择。
要认识到的重要一点是,decimal仍然是浮点类型。它仍然存在舍入误差,不能表示某些"简单"数字(如1/3)。它的一个优点(也是一个目的)是它可以精确地表示小于29位有效数字的十进制数。这意味着0.1或12345.6789这样的数字。基本上,任何一个十进制数字都可以用少于29位的数字写在纸上。如果你有一个重复的小数或者一个无理数,那么decimal就没有什么好处。
经验法则是使用更适合您将要处理的值的类型。这意味着您应该使用DateTime或TimeSpan作为时间,除非您只关心特定的单位,如秒、天等,在这种情况下,您可以使用任何整数类型。通常情况下,您需要精确,不希望因舍入而出现任何错误,因此我不会使用任何浮点类型,如float或double。
对于任何与金钱有关的东西,当然你也不希望有任何舍入误差,所以你应该在这里使用decimal。
最后,只有当对于一些非常具体的需求,在一个数百万次的计算中需要绝对速度,而对于这个计算,decimal恰好不够快,那么我才会考虑使用另一种更快的类型。我首先尝试使用整数值(如果你有小数,可以用你的值乘以10的幂),最后只除以10的幂。如果不能做到这一点,只有这样我才会考虑使用double。如果不确定是否需要,不要过早地进行优化。
- 使用double并不是过早的优化,而是更简单的选择。避免过早优化的关键是避免在知道代码是否值得之前使代码复杂化。尝试使用decimal或必须在整个地方进行缩放的整型,是应该避免的不必要的复杂性。
- 我认为decimal比较简单,头痛也比较轻。正如我上面所评论的,有时浮点值缺乏精度会产生0.800000001或0.9999999之类的输出,或者使0.1f == 0.1之类的东西出错。所以你必须对这些类型更加小心。不管怎样,我们几乎不知道豪斯马克需要什么,所以这里都是猜测。
- 我认为在这两种情况下都必须注意同样的问题,因为decimal仍然是浮点类型,并且仍然存在舍入和截断错误。它会遇到同样的问题,但在不同的情况下。所以我不同意这么简单。我认为这一建议使江户十一〔一〕看起来像是一颗神奇的子弹,而事实并非如此。
- 你需要无限的小数,而不是取整和截断。否则你会怎么避免?如果你超过了decimal的限制,那么忍受这些是很合理的。我从来没有经历过神奇的小数出现或意外的不平等与小数,我认为他们是一个更可靠的类型比所谓的浮点型。不管怎么说,编程中没有什么是神奇的,它显然不是每种情况下的最佳解决方案,但至少在货币计算中,我会说这是一个很简单的方法。