What is the difference between 'decimal' and 'float' in C#?
在C语言中使用decimal或float有什么区别?我知道float用于更精确的十进制数,decimal用于货币或价格等少数小数,但当它用于少数小数时,为什么最好使用decimal而不是float?
- "我知道float用于更精确的十进制数字,decimal用于一些小数,例如currency",您可以向后看,decimal具有更高的精度。
- 简单的回答。使用浮动来降低精度。使用双精度。使用十进制精确。当然,你不能存储超过15位小数的范围,但这不是浮动的。
- @卡兹马卡里先生"准确"!真的!那么,decimal是如何表示1/3的呢?当后者乘以3时会发生什么?
- 对不起的。十进制存储大约28位数字的范围。如果你把1除以3,你得到0.33。它只存储28个重复3个。当你把它乘以3,你会得到0.99。28个重复的9个。如你所见,这是精确的数学评估。但是如果你使用双精度类型,因为它是浮动的,而且精度很高(不是精确的),你会得到1。因为它总是四舍五入到小数点较少的地方。这就是为什么我们说浮动。它可以根据小数向上取整或向下取整。因此,它不适合存储例如在赛车中的世界记录或时间。因为毫秒是重要的,我们不应该绕过任何东西!
- 但是当你想用数学形式计算某个东西时,你必须用double来给你更好的数字(在某些情况下,由于四舍五入会给你精确的结果)。就像你举的例子。1/3不完全存储。0.33*3不精确计算,但当我们取0.999时,我们得到1,这是预期的精确结果)。同样,double比decimal快得多,但是你感觉不到它,因为处理器很快!您必须阅读有关decimal与double-performance stackoverflow.com/a/329618/4767498的答案
- 抱歉我的英语太差了,但我希望你明白我的意思。
float是一种浮点二进制类型,也就是说,它是一个二进制尾数,后面跟一个二进制指数,形式为mantissa x 10 ^ exponent,10是二进制中的数字2。例如,数字3.0表示为1.1 x 10^1,数字8 1/2表示为1.0001 x 10^11。它基本上以二进制分数的形式表示数字。以2为基数的浮点数的问题在于,很难精确地表示非2因子的十进制数。
用浮点二进制格式表示1/2、1/4、1/8、1/16等值很容易。1/2只是0.1,1/4是0.01,1/8是0.001等,但是如果你想表示一个像0.6这样的十进制值,你必须建立一个基2分数的和来接近于表示它。所以最后得到的是1.001100110011001100110011 x 10^-1的浮点表示,其中0011只是不断重复,因为在基2中没有十进制0.6的有理表示。
这就是decimal型的出现。decimal类型不使用分数二进制表示,而是使用符号位、96位整数有效位和整数比例因子来表示值,格式为(sign x significand) / (10 ^ scaling factor)。符号可以是0或1,有效位可以是0到2^96-1之间的任何值,比例因子可以是0到28之间的任何值。这意味着数字是以十进制分数而不是二进制分数来表示的,所以我们人类用来处理的数字可以精确准确地以合理的形式表示。与我们前面看到的丑陋和不精确的0.6二进制表示不同,decimal类型表示0.6,作为一个干净的(1 x 6) / (10 ^ 1)类型。很漂亮,不是吗?
不幸的是,这是有代价的。在decimal型上的操作比在float或double上的操作慢得多。几乎每一台人类已知的计算机中的处理器都是二进制处理器(我说"几乎每一台",因为我不能反驳地球上某个地方存在的非二进制计算机)。这意味着它本身支持二进制加法、减法等。像float x = 256.0 / 2;这样的操作编译成一个简单的指令,其中浮点数的指数递减。但是,decimal x = 256.0m / 2;编译成一组更复杂的指令,因为数字不是以二进制小数形式存储的,必须考虑数字的特殊base-10表示。
一般来说,如果您需要的速度超过十进制精度,那么float或double就足以满足您的应用。但是,如果您要求小数精度高于其他所有要求,例如会计,那么decimal是要使用的类型。
有关详细信息,请参阅此msdn文档。
十进制将有128位,仅浮动32位来表示数字。
The decimal keyword indicates a 128-bit data type. Compared to floating-point types, the decimal type has more precision and a smaller range, which makes it appropriate for financial and monetary calculations. The approximate range and precision for the decimal type are shown in the following table.
(-7.9 x 1028 to 7.9 x 1028) / (10^0 - ^28), 28-29 significant digits
来自MSDN
另一方面,浮动:
The float keyword signifies a simple type that stores 32-bit floating-point values. The following table shows the precision and approximate range for the float type.
-3.4 × 10^38 to +3.4 × 10^38, 7 significant digits
链接
- 那么,decimal是小数最精确的关键字吗?
- 是的,它支持更大的数字(因此更精确)。我不知道我的头顶支持更高的数学值。edit Decimal.Max给你79,228,162,514,264,337,593,543,950,335,其中Single.MaxValue(为什么是float类型Single?根据msdn,3.402823e38说。
- 但是float更快,所以我应该避免使用decimal,除非我需要很多精度,对吗?
- 我们可以说,考虑到现代计算机有多大的功率,这"并不重要",但我想没有必要加强坏的habbits。所以,如果你能记住哪种类型比较小(就内存而言),并且你知道它能满足你的需求,那么是的,我想用float会更好。我有过一些教授,他们关心使用必要的最小类型,我也有过一些雇主,只要它们能编出来,他们就什么都不在乎。
- @facundschiavoni如果您使用的是十进制值(不是二进制),除非您需要很大的速度,否则请使用decimal。尝试运行以下代码:float x = 0.29f; bool surprise = (x * 10) == (0.29f * 10);。