您似乎可以看到使用浮点类型的好处 . 我倾向于在所有情况下设计小数,并依靠分析器让我知道十进制操作是否导致瓶颈或减速 . 在这些情况下,我将“向下转换”为double或float,但仅在内部执行,并通过限制正在执行的数学运算中的有效位数来小心地尝试管理精度损失 .
通常,如果您的值是瞬态的(不重用),则可以安全地使用浮点类型 . 浮点类型的真正问题是以下三种情况 .
您正在聚合浮点值(在这种情况下,精度错误复合)
您基于浮点值构建值(例如,在递归算法中)
您正在使用大量有效数字进行数学运算(例如, 123456789.1 * .000000000000000987654321 )
EDIT
decimal关键字表示128位数据类型 . 与浮点类型相比,十进制类型具有更高的精度和更小的范围,这使其适用于财务和货币计算 .
所以澄清我的上述说法:
我倾向于在所有情况下设计小数,并依靠分析器让我知道十进制操作是否导致瓶颈或减速 .
我只在小数有利的行业工作过 . 如果你正在研究phsyics或图形引擎,那么设计浮点类型(float或double)可能更有利 .
十进制不是无限精确的(在原始数据类型中不可能表示非整数的无限精度),但它比双精度要精确得多:
decimal = 28-29有效数字
double = 15-16位有效数字
float = 7位有效数字
EDIT 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
正如您所看到的,即使我们使用相同的源常量添加,double的结果也不太精确(尽管可能会正确地舍入),并且浮点数远不那么精确,直到它已经减少到只有两位有效数字 .