.net - decimal float区别




.NET中decimal,float和double的区别? (12)

.NET中的decimalfloatdouble什么区别?

什么时候会有人使用其中之一?


  1. 在编译和运行时,double和float都可以被整数零除。
  2. 十进制不能被整数零除。 如果你这样做,编译将会失败。

Decimal,Double和Float变量类型的存储方式不同。 float是单精度(32位)浮点数据类型,double是双精度(64位)浮点数据类型,decimal是128位浮点数据类型时,精度是主要区别。

浮点 - 32位(7位数字)

双64位(15-16位)

十进制 - 128位(28-29位有效数字)

主要区别是Floats和Doubles是二进制浮点类型,Decimal会将该值存储为浮点小数点类型。 所以小数具有更高的精度,通常用于需要高度准确性的货币(金融)或科学计算应用中。 但在性能方面,小数比双精度和浮点类型慢。

十进制可以100%准确地表示小数格式精度内的任何数字,而Float和Double不能准确表示所有数字,即使在各自格式精度范围内的数字也不能准确表示。

十进制

在财务应用或科学计算的情况下,最好使用十进制类型,因为它为您提供了高级别的准确性并且易于避免舍入错误

除了处理金钱之外,双重类型可能是实际值最常用的数据类型。

浮动

它主要用于图形库,因为对处理能力的要求非常高,也使用了可以忍受舍入误差的情况。


float 7位精度

double精度约为15位

decimal有大约28个数字的精度

如果您需要更高的准确度,请使用double而不是float。 在现代CPU中,两种数据类型的性能几乎相同。 使用浮动的唯一好处是它占用更少的空间。 实际上只有当你有很多人时才有意义。

我发现这很有趣。 每位计算机科学家应该了解的浮点算法


floatdouble浮点二进制点类型 。 换句话说,他们代表了这样一个数字:

10001.10010110011

二进制数和二进制点的位置都在该值内编码。

decimal浮点小数点类型 。 换句话说,他们代表了这样一个数字:

12345.65789

同样, 小数点的位置和数字都被编码在这个值中 - 这就是decimal仍然是浮点类型而不是固定点类型。

重要的是要注意的是,人类习惯用十进制形式表示非整数,并期望十进制表示中的确切结果; 并非所有的十进制数都可以在二进制浮点数中精确表示 - 例如0.1 - 所以如果使用二进制浮点数值,则实际上会得到0.1的近似值。 例如,当使用浮动小数点时,您仍会得到近似值 - 例如,除以1除以3的结果不能被精确表示。

至于什么时候使用:

  • 对于“自然精确小数”的值,使用decimal是很好的。 这通常适用于人类发明的任何概念:金融价值是最明显的例子,但也有其他概念。 例如,考虑给予潜水员或溜冰者的分数。

  • 对于自然界更多的人为因素,无论如何都无法准确衡量, float / double点更合适。 例如,科学数据通常以这种形式表示。 在这里,原始值不会以“小数精度”开始,所以对于预期结果来说,保持“小数精度”并不重要。 浮点二进制点类型比小数点处理速度快得多。


如前所述,整数是整数。 他们不能存储点,例如.7,.42和.007。 如果你需要存储不是整数的数字,你需要一个不同类型的变量。 您可以使用双精度型或浮点型。 您可以使用完全相同的方式设置这些类型的变量:不是使用int这个词,而是输入doublefloat 。 喜欢这个:

float myFloat;
double myDouble;

float是“浮点数”的缩写,只是意味着一个数字有一点点到底。)

两者之间的差异在于它们可以容纳的数字的大小。 对于float ,您的号码最多可以有7位数字。 对于double s,最多可以有16位数字。 更确切地说,这是官方规模:

float:  1.5 × 10^-45  to 3.4 × 10^38  
double: 5.0 × 10^-324 to 1.7 × 10^308

float是一个32位数字, double是一个64位数字。

双击您的新按钮以查看代码。 将以下三行添加到您的按钮代码中:

double myDouble;
myDouble = 0.007;
MessageBox.Show(myDouble.ToString());

暂停您的程序并返回编码窗口。 改变这一行:

myDouble = 0.007;
myDouble = 12345678.1234567;

运行你的程序并点击双击按钮。 消息框正确显示数字。 尽管如此,在结尾添加另一个数字,C#将再次向上或向下舍入。 道德是如果你想要的准确性,小心四舍五入!


它们之间的主要区别在于精度。

float是一个32-bit数字, double是一个64-bit数字, decimal是一个128-bit数字。


对我来说,这是一条有趣的线索,就像今天,我们刚刚遇到了一个令人讨厌的小错误,关于decimal精度低于float

在我们的C#代码中,我们正在从Excel电子表格中读取数值,将它们转换为decimal ,然后将此decimal发送回服务以保存到SQL Server数据库中。

Microsoft.Office.Interop.Excel.Range cell = …
object cellValue = cell.Value2;
if (cellValue != null)
{
    decimal value = 0;
    Decimal.TryParse(cellValue.ToString(), out value);
}

现在, 几乎所有的Excel值都可以很好地工作。 但对于一些非常小的Excel值,使用decimal.TryParse完全失去该值。 一个这样的例子是

  • cellValue = 0.00006317592

  • Decimal.TryParse(cellValue.ToString(),out value); //将返回0

奇怪的解决方案是将Excel值先转换为double精度值,然后再转换成小数值:

Microsoft.Office.Interop.Excel.Range cell = …
object cellValue = cell.Value2;
if (cellValue != null)
{
    double valueDouble = 0;
    double.TryParse(cellValue.ToString(), out valueDouble);
    decimal value = (decimal) valueDouble;
    …
}

尽管double精确度小于decimal ,但这实际上确保了小数目仍能被识别。 出于某种原因, double.TryParse实际上能够检索这样的小数字,而decimal.TryParse会将它们设置为零。

奇。 很奇怪。


我不会重复在其他答案和评论中已经回答的大量好的(和一些不好的)信息,但我会用提示回答你的后续问题:

什么时候会有人使用其中之一?

数值使用小数

使用float / double作为测量

一些例子:

  • 钱(我们数钱还是衡量金钱?)

  • 距离(我们计算距离还是测量距离?*)

  • 分数(我们计数分数还是分数?)

我们总是数钱,不应该衡量它。 我们通常测量距离。 我们经常计数分数。

*在某些情况下,我称之为标称距离 ,我们可能确实需要“计数”距离。 例如,也许我们正在处理显示到城市的距离的国家标志,并且我们知道这些距离永远不会超过一个十进制数字(xxx.x km)。


没有人提到过

在默认设置中,Floats(System.Single)和double(System.Double)永远不会使用溢出检查,而Decimal(System.Decimal)将始终使用溢出检查。

我的意思是

decimal myNumber = decimal.MaxValue;
myNumber += 1;

抛出OverflowException

但是这些不会:

float myNumber = float.MaxValue;
myNumber += 1;

double myNumber = double.MaxValue;
myNumber += 1;

浮动〜±1.5×10-45至±3.4×1038 -------- 7个数字
双±5.0 x 10-324至±1.7 x 10308 ------ 15或16位数字
小数点〜±1.0×10-28至±7.9×1028 -------- 28或29位数字


精度是主要区别。

Float - 7位数字(32位)

Double 15-16位(64位)

Decimal -28-29有效数字(128位)

小数具有更高的精度,通常用于需要高度准确性的财务应用程序中。 小数点比双/浮点数慢得多(在一些测试中高达20倍)。

小数和浮动/双打无法比较没有投,而浮动和双打可以。 小数也允许编码或尾随零。

float flt = 1F/3;
double dbl = 1D/3;
decimal dcm = 1M/3;
Console.WriteLine("float: {0} double: {1} decimal: {2}", flt, dbl, dcm);

结果:

float: 0.3333333  
double: 0.333333333333333  
decimal: 0.3333333333333333333333333333





decimal