C# 什么时候我应该使用双精度而不是十进制?
我可以列举使用C# 什么时候我应该使用双精度而不是十进制?,c#,types,floating-point,double,decimal,C#,Types,Floating Point,Double,Decimal,我可以列举使用double(或float)而不是decimal)的三个优点: 使用更少的内存 更快,因为处理器本机支持浮点数学运算 可以表示更大范围的数字 但这些优势似乎只适用于计算密集型操作,如建模软件中的操作。当然,当需要精度时,例如财务计算,不应使用双倍。那么,在“正常”应用程序中,是否有任何实际理由选择双精度(double)(或float)而不是decimal 编辑以添加: 感谢所有的回复,我从他们身上学到了很多 还有一个问题:一些人指出双倍可以更精确地表示真实数字。当我宣布时,我认为它
double
(或float
)而不是decimal
)的三个优点:
double
)(或float
)而不是decimal
编辑以添加:
感谢所有的回复,我从他们身上学到了很多
还有一个问题:一些人指出双倍可以更精确地表示真实数字。当我宣布时,我认为它们通常也能更准确地代表它们。但是,当执行浮点运算时,精度可能会降低(有时会显著降低)这是真的吗?在不需要精度的情况下使用双精度或浮点,例如,在我编写的platformer游戏中,我使用浮点存储玩家速度。显然,这里不需要超精度,因为我最终会在屏幕上绘制一个整数。使用浮点类型的好处似乎让您一目了然。在任何情况下,我都倾向于为小数设计,并依靠探查器让我知道对小数的操作是否会导致瓶颈或减速。在这些情况下,我将“向下转换”为double或float,但仅在内部执行,并通过限制正在执行的数学运算中的有效位数来小心地尝试管理精度损失 一般来说,如果您的值是瞬态的(不可重用),则可以安全地使用浮点类型。浮点类型的真正问题是以下三种情况
123456789.1*.000000000000000 987654321
)- 十进制=28-29位有效数字
- 双精度=15-16位有效数字
- 浮点=7位有效数字
private const float THREE_FIFTHS = 3f / 5f;
private const int ONE_MILLION = 1000000;
public static void Main(string[] args)
{
Console.WriteLine("Three Fifths: {0}", THREE_FIFTHS.ToString("F10"));
float asSingle = 0f;
double asDouble = 0d;
decimal asDecimal = 0M;
for (int i = 0; i < ONE_MILLION; i++)
{
asSingle += THREE_FIFTHS;
asDouble += THREE_FIFTHS;
asDecimal += (decimal) THREE_FIFTHS;
}
Console.WriteLine("Six Hundred Thousand: {0:F10}", THREE_FIFTHS * ONE_MILLION);
Console.WriteLine("Single: {0}", asSingle.ToString("F10"));
Console.WriteLine("Double: {0}", asDouble.ToString("F10"));
Console.WriteLine("Decimal: {0}", asDecimal.ToString("F10"));
Console.ReadLine();
}
正如您所看到的,即使我们从同一个源常量进行加法,double的结果也不太精确(尽管可能会正确舍入),而float的精度也远低于double,以至于它被减少到只有两个有效数字。我认为您已经很好地总结了优点。不过,你遗漏了一点。该类型仅在表示以10为基数的数字时更准确(例如,货币/金融计算中使用的数字)。一般来说,对于任意实数,该类型将提供至少同样高的精度(如果我错了,有人会纠正我)和更高的速度。简单的结论是:在考虑使用哪个时,始终使用
double
,除非您需要base 10
所提供的decimal
精度
编辑:
关于操作后浮点数精度下降的问题,这是一个稍微微妙的问题。事实上,每次操作完成后,精度(我在这里互换使用术语表示精度)将稳步下降。这是由于两个原因:
有关可引入精度误差的特定情况的更详细概述,请参阅。最后,如果您想在机器级别上对浮点数/运算进行深入(数学)的讨论,请阅读经常引用的文章。如果您需要与其他语言或平台进行二进制交互,则可能需要使用float或double,它们是标准化的。如果您看重性能而不是正确性,请使用浮点。选择应用程序功能中的类型。如果你需要像财务分析那样的精确性,你已经回答了你的问题。但是如果你的申请可以通过
Three Fifths: 0.6000000000
Six Hundred Thousand: 600000.0000000000
Single: 599093.4000000000
Double: 599999.9999886850
Decimal: 600000.0000000000
// Add one third + one third + one third with decimal
decimal decimalValue = 1M / 3M;
decimal decimalResult = decimalValue + decimalValue + decimalValue;
// Add one third + one third + one third with double
double doubleValue = 1D / 3D;
double doubleResult = doubleValue + doubleValue + doubleValue;
For accounting - decimal
For finance - double
For heavy computation - double
[SecuritySafeCritical]
public static extern double Pow(double x, double y);