您似乎很清楚使用浮点类型的好处。我倾向于在所有情况下设计小数点,并依靠分析器让我知道小数点操作是否会导致瓶颈或减速。在这些情况下,我会“下注”来双倍或浮动,但只能在内部完成,并且仔细尝试通过限制正在执行的数学运算中的有效数字的数量来管理精度损失。
一般来说,如果你的值是瞬态的(不重用),你可以安全地使用浮点类型。浮点类型的真正问题是以下三种情况。
- 您正在聚集浮点值(在这种情况下,精度误差化合物)
- 你建
- 你正在做数学与基于所述浮点值(例如在一个递归算法)值非常宽的数目的数字显著(例如,
123456789.1 * .000000000000000987654321
)
EDIT
甲ccording到reference documentation on C# decimals:
的小数关键字表示 128位的数据类型。与 浮点类型相比,小数类型 具有更高的精度和更小的范围,因此适用于 财务和货币计算。
所以澄清我的上述声明:
我倾向于在所有 情况下为小数设计,并依靠探查让 我知道,如果在十进制运算是 造成瓶颈或慢-downs。
我只在有小数的行业工作过。如果您正在使用phsyics或图形引擎,那么设计浮点类型(float或double)可能会更有益处。
小数是不是无限精确的(这是不可能代表无限精度用于在原始数据类型非整数),但它远远大于双更精确的:
- 小数= 28-29显著数字
- 双= 15-16显著数字
- 浮子= 7个显著数字
编辑2
回应Konrad Rudolph的评论,项目#1(上述)绝对正确。不精确性的聚合确实复合了。请参见下面的代码为例:
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();
}
此输出以下:
Three Fifths: 0.6000000000
Six Hundred Thousand: 600000.0000000000
Single: 599093.4000000000
Double: 599999.9999886850
Decimal: 600000.0000000000
正如你所看到的,即使我们从同一来源不断增加,双重的结果是少精确的(尽管可能会正确地回合),并且浮点数远不够精确,直到它减少到只有两个有效数字。
另请参阅http://stackoverflow.com/questions/2545567/in-net-how-do-i-choose-between-a-decimal-and-a-double –
这得到upvoted相当有规律,我仍然奋斗用它。例如,我正在开发一个用于财务计算的应用程序,因此我在整个过程中使用了十进制。但数学和VisualBasic.Financial函数使用双重,所以有很多转换,我不断猜测使用小数。 –
@JamieIde这是疯狂的金融功能使用双倍,金钱应该始终在十进制。 –