十进制、浮点数和双精度之间的区别。NET?

. NET中的decimalfloatdouble有什么区别?

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

1154755 次浏览

精度是最大的区别。

浮点数-7位(32位)

双倍-15-16位(64位)

十进制-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.3333333double: 0.333333333333333decimal: 0.3333333333333333333333333333

floatSystem.Single的C#别名)和doubleSystem.Double的C#别名)是浮点二进制点类型float是32位;double是64位。换句话说,它们表示如下数字:

10001.10010110011

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

decimalSystem.Decimal的C#别名)是浮点十进制点类型。换句话说,它们表示这样的数字:

12345.65789

同样,十进制点的数字和位置都在值中编码-这就是为什么decimal仍然是浮点类型而不是定点类型。

需要注意的重要一点是,人类习惯于以十进制形式表示非整数,并期望以十进制表示获得精确结果;并非所有十进制数字都可以用二进制浮点精确表示-例如0.1-因此,如果您使用二进制浮点值,您实际上会得到0.1的近似值。使用浮动小数点时,您仍然会得到近似值-例如,1除以3的结果无法准确表示。

至于什么时候使用:

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

  • 对于那些更多的自然产物,无论如何都无法真正测量完全的值,float/double更合适。例如,科学数据通常会以这种形式表示。在这里,原始值一开始就不是“十进制精度”,所以预期结果保持“十进制精度”并不重要。浮点二进制类型比小数快得多。

  1. 双精度和浮点数可以除以整数零,在编译和运行时都没有异常。
  2. 小数不能除以整数零。如果您这样做,编译将始终失败。

十进制结构严格适用于需要精确度的财务计算,这些计算相对不允许四舍五入。然而,小数不适合科学应用,原因如下:

  • 在许多科学计算中,由于被测量的物理问题或人工制品的实际限制,一定程度的精度损失是可以接受的。
  • 对于大多数操作,十进制比浮点数和双精度要慢得多,主要是因为浮点数操作是在二进制中完成的,而十进制的东西是在基数10中完成的(即浮点数和双精度由FPU硬件处理,例如MMX/SSE,而十进制是在软件中计算的)。
  • Decimal的取值范围比Double小得令人无法接受,尽管它支持更多的精度数字。因此,Decimal不能用于表示许多科学值。

float 7位精度

double大约有15位精度

decimal大约有28位精度

如果您需要更好的精度,请使用双精度而不是浮点数。在现代CPU中,两种数据类型的性能几乎相同。使用浮点数的唯一好处是它们占用的空间更少。只有当你有很多它们时,实际情况才重要。

我发现这很有趣每个计算机科学家都应该知道的关于浮点运算的知识

这对我来说是一个有趣的线索,因为今天,我们刚刚有一个令人讨厌的小bug,关于decimal的精度低于float

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

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

现在,对于我们的Excel值中的几乎所有,这工作得很好。但是对于一些非常小的Excel值,使用#0完全失去了值。一个这样的例子是

  • cell Value=0.00006317592

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

奇怪的是,解决方案是先将Excel值转换为double,然后再转换为decimal

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,但这实际上确保了小数字仍然可以被识别。出于某种原因,#2实际上能够检索到如此小的数字,而#3将它们设置为零。

奇怪。非常奇怪。

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

float myFloat;double myDouble;

float是“浮点数”的缩写,只是表示末尾有一个点的数字。

两者之间的区别在于它们可以容纳的数字的大小。对于float,您的数字最多可以有7位数字。对于double,您最多可以有16位数字。更准确地说,这是官方的大小:

float:  1.5 × 10^-45  to 3.4 × 10^38double: 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#将再次向上或向下舍入。寓意是如果您想要准确性,请小心舍入!

+---------+----------------+---------+----------+---------------------------------------------------------+| C#      | .Net Framework | Signed? | Bytes    | Possible Values                                         || Type    | (System) type  |         | Occupied |                                                         |+---------+----------------+---------+----------+---------------------------------------------------------+| sbyte   | System.Sbyte   | Yes     | 1        | -128 to 127                                             || short   | System.Int16   | Yes     | 2        | -32,768 to 32,767                                       || int     | System.Int32   | Yes     | 4        | -2,147,483,648 to 2,147,483,647                         || long    | System.Int64   | Yes     | 8        | -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 || byte    | System.Byte    | No      | 1        | 0 to 255                                                || ushort  | System.Uint16  | No      | 2        | 0 to 65,535                                             || uint    | System.UInt32  | No      | 4        | 0 to 4,294,967,295                                      || ulong   | System.Uint64  | No      | 8        | 0 to 18,446,744,073,709,551,615                         || float   | System.Single  | Yes     | 4        | Approximately ±1.5e-45 to ±3.4e38                       ||         |                |         |          |  with ~6-9 significant figures                          || double  | System.Double  | Yes     | 8        | Approximately ±5.0e-324 to ±1.7e308                     ||         |                |         |          |  with ~15-17 significant figures                        || decimal | System.Decimal | Yes     | 16       | Approximately ±1.0e-28 to ±7.9e28                       ||         |                |         |          |  with 28-29 significant figures                         || char    | System.Char    | N/A     | 2        | Any Unicode character (16 bit)                          || bool    | System.Boolean | N/A     | 1 / 2    | true or false                                           |+---------+----------------+---------+----------+---------------------------------------------------------+

查看这里获取更多信息

  • 浮点数:±1.5 x 10^-45至±3.4 x 10^38(~7个有效数字
  • 双倍:±5.0 x 10^-324至±1.7 x 10^308(15-16个有效数字)
  • 十进制:±1.0 x 10^-28至±7.9 x 10^28(28-29个有效数字)

对于内存和性能都至关重要的游戏和嵌入式系统等应用程序,浮点数通常是数字类型的选择,因为它更快并且是双精度的一半。整数曾经是首选武器,但浮点数性能已经超过了现代处理器中的整数。小数就对了!

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

浮点数-32位(7位)

双-64位(15-16位)

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

更多关于十进制、浮点数和双倍数的区别

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

  • float是一个32位的数字
  • double是一个64位的数字
  • decimal是一个128位的数字

没人提过这个

在默认设置中,浮点数(系统.单)和双打(系统.双)永远不会使用溢出检查,而Decimal(System. Decimal)将始终使用溢出检查。

我的意思是

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

抛出错误码

但这些并没有:

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

&

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

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

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

计数值使用十进制

测量值使用浮点数/双精度

一些例子:

  • 钱(我们计算钱还是衡量钱?)

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

  • 分数(我们是计算分数还是衡量分数?)

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

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

所有这些类型的问题是存在一定的不精确性并且这个问题可能会出现在小十进制数字中,如以下示例

Dim fMean as Double = 1.18Dim fDelta as Double = 0.08Dim fLimit as Double = 1.1
If fMean - fDelta < fLimit ThenbLower = TrueElsebLower = FalseEnd If

问题:bLow变量包含哪个值?

答案:在32位机器上,bLow包含TRUE!!!

如果我用十进制替换双精度,bLow包含FALSE,这是一个很好的答案。

在双精度中,问题是fMean-fDelta=1.09999999999低于1.1。

注意:我认为同样的问题也可能存在于其他数字中,因为Decimal只是一个具有更高精度的双精度,并且精度总是有限制的。

事实上,Double、Float和Decimal对应于COBOL中的BINary decimal!

遗憾的是,在COBOL中实现的其他数字类型在. Net中不存在。对于那些不了解COBOL的人,COBOL中存在以下数字类型

BINARY or COMP like float or double or decimalPACKED-DECIMAL or COMP-3 (2 digit in 1 byte)ZONED-DECIMAL (1 digit in 1 byte)

简单的一句话:

  1. Decimal、Double和Float变量类型在存储值的方式上是不同的。
  2. 精度是主要区别(请注意,这不是单差),其中浮动是单精度(32位)浮点数据类型,双倍是双精度(64位)浮点数据类型,十进制是128位浮点数据类型。
  3. 全量表:

<>/==========================================================================================类型钻头具有近似范围/==========================================================================================浮点数32 7位-3.4×10^(38)至+3.4×10^(38)双64位15-16位±5.0×10^(-324)至±1.7×10^(308)十进制128位28-29位有效数字±7.9 x 10^(28)或(1至10^(28)/==========================================================================================您可以阅读更多这里浮点数双倍十进制

在. Net(c#)中定义Decimal、Float和Double

您必须提及以下值:

Decimal dec = 12M/6;Double dbl = 11D/6;float fl = 15F/6;

并检查结果。

和每个占用的字节是

Float - 4Double - 8Decimal - 12