.NET中的decimal,float和double之间的区别?

时间:2009-03-06 11:31:23

标签: .net floating-point double decimal

.NET中decimalfloatdouble之间有什么区别?

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

18 个答案:

答案 0 :(得分:2118)

floatdoublefloating binary point types。换句话说,它们代表了这样的数字:

10001.10010110011

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

decimalfloating decimal point type。换句话说,它们代表了这样的数字:

12345.65789

同样,十进制点的数量和位置都在值内编码 - 这使得decimal仍然是浮点类型而不是固定点类型。

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

至于什么时候使用:

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

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

答案 1 :(得分:990)

精确度是主要区别。

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

答案 2 :(得分:77)

十进制结构严格适用于要求准确性的财务计算,这对于舍入是相对不容忍的。然而,小数不足以用于科学应用,原因如下:

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

答案 3 :(得分:68)

+---------+----------------+---------+----------+---------------------------------------------+
| C#      | .Net Framework | Signed? | Bytes    | Possible Values                             |
| Type    | (System) type  |         | Occupied |                                             |
+---------+----------------+---------+----------+---------------------------------------------+
| sbyte   | System.Sbyte   | Yes     | 1        | -128 to 127                                 |
| short   | System.Int16   | Yes     | 2        | -32768 to 32767                             |
| int     | System.Int32   | Yes     | 4        | -2147483648 to 2147483647                   |
| long    | System.Int64   | Yes     | 8        | -9223372036854775808 to 9223372036854775807 |
| byte    | System.Byte    | No      | 1        | 0 to 255                                    |
| ushort  | System.Uint16  | No      | 2        | 0 to 65535                                  |
| uint    | System.UInt32  | No      | 4        | 0 to 4294967295                             |
| ulong   | System.Uint64  | No      | 8        | 0 to 18446744073709551615                   |
| float   | System.Single  | Yes     | 4        | Approximately ±1.5 x 10-45 to ±3.4 x 1038   |
|         |                |         |          |  with 7 significant figures                 |
| double  | System.Double  | Yes     | 8        | Approximately ±5.0 x 10-324 to ±1.7 x 10308 |
|         |                |         |          |  with 15 or 16 significant figures          |
| decimal | System.Decimal | Yes     | 12       | Approximately ±1.0 x 10-28 to ±7.9 x 1028   |
|         |                |         |          |  with 28 or 29 significant figures          |
| char    | System.Char    | N/A     | 2        | Any Unicode character (16 bit)              |
| bool    | System.Boolean | N/A     | 1 / 2    | true or false                               |
+---------+----------------+---------+----------+---------------------------------------------+

有关详细信息,请参阅:
http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/921a8ffc-9829-4145-bdc9-a96c1ec174a5

答案 4 :(得分:46)

float 7位精度

double有大约15位精度

decimal有大约28位精度

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

我发现这很有趣。 What Every Computer Scientist Should Know About Floating-Point Arithmetic

答案 5 :(得分:39)

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

  

何时会有人使用其中一种?

计算

使用小数

将float / double用于测量的

一些例子:

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

  • 距离(我们计算距离或测量距离吗?*)

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

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

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

答案 6 :(得分:34)

没人提到

  

在默认设置中,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;

答案 7 :(得分:27)

  1. Double和float可以除以整数零,在编译和运行时都没有异常。
  2. 十进制不能除以整数零。如果你这样做,编译总是会失败。

答案 8 :(得分:27)

如上所述,整数是整数。他们无法存储点数,例如.7,.42和.007。如果您需要存储非整数的数字,则需要使用不同类型的变量。您可以使用double类型或float类型。您以完全相同的方式设置这些类型的变量:您可以键入intdouble,而不是使用单词float。像这样:

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#将再次向上或向下舍入。道德是如果你想要准确,小心四舍五入!

答案 9 :(得分:13)

这对我来说是一个有趣的话题,就像今天一样,我们只有一个令人讨厌的小错误,关于decimal精度低于float

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

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,然后转换为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,但这实际上确保了仍可识别的小数字。出于某种原因, double.TryParse 实际上能够检索到这么小的数字,而 decimal.TryParse 会将它们设置为零。

奇。很奇怪。

答案 10 :(得分:12)

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

答案 11 :(得分:8)

对于内存和性能都很关键的游戏和嵌入式系统等应用程序,float通常是数字类型,因为它更快,是double的一半大小。整数曾经是首选武器,但浮点性能在现代处理器中已超过整数。十进制就出来了!

答案 12 :(得分:7)

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

Float - 32位(7位)

加倍 - 64位(15-16位)

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

更多关于...... the difference between Decimal, Float and Double

答案 13 :(得分:5)

所有这些类型的问题在于存在某种不精确性 并且,如下例所示,小的十进制数可能会出现此问题

Dim fMean as Double = 1.18
Dim fDelta as Double = 0.08
Dim fLimit as Double = 1.1

If fMean - fDelta < fLimit Then
    bLower = True
Else
    bLower = False
End If

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

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

如果我用Decimal替换Double,则bLower包含FALSE,这是一个很好的答案。

在double中,问题是fMean-fDelta = 1.09999999999低于1.1。

警告:我认为其他数字肯定存在同样的问题,因为Decimal只是一个精度更高的双精度,并且精度总是有限制。

实际上,Double,Float和Decimal对应于COBOL中的BINARY十进制!

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

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

答案 14 :(得分:4)

简单来说:

  1. Decimal,Double和Float变量类型在存储值方面有所不同。
  2. 精度是 主要差异 (请注意,这不是单一的差异) float 是单精度(32位)浮动点数据类型, double 是双精度(64位)浮点数据类型,十进制是128位浮点数据类型。
  3. 摘要表:
  4. /==========================================================================================
        Type       Bits    Have up to                   Approximate Range 
    /==========================================================================================
        float      32      7 digits                     -3.4 × 10 ^ (38)   to +3.4 × 10 ^ (38)
        double     64      15-16 digits                 ±5.0 × 10 ^ (-324) to ±1.7 × 10 ^ (308)
        decimal    128     28-29 significant digits     ±7.9 x 10 ^ (28) or (1 to 10 ^ (28)
    /==========================================================================================
    
    您可以阅读更多hereFloatDoubleDecimal

答案 15 :(得分:3)

每种方法之间的主要区别在于精度。

float32-bit个号码,double64-bit个号码,decimal128-bit个号码。

答案 16 :(得分:0)

  • 十进制 128位(28-29位有效数字) 如果是财务应用,最好使用 十进制类型,因为它可以为您提供较高的准确性,并且易于避免舍入错误 对于需要精度(例如货币和货币)的非整数数学,请使用十进制

  • 64位(15-16位) 除了处理金钱以外,双精度类型可能是用于实值的最常用数据类型。 对于不需要最精确答案的非整数数学,请使用double。

  • 浮动 32位(7位数字) 它主要用于图形库中,因为对处理能力的要求非常高, 还使用了会承受舍入错误的情况。

Decimalsdouble/float慢得多。

DecimalsFloats/Doubles在没有强制转换的情况下无法进行比较,而FloatsDoubles则可以。

Decimals也允许编码或尾随零。

答案 17 :(得分:-2)

要在.Net(c#)中定义小数,浮点数和双精度数

您必须将值提及为:

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

并检查结果。

每个字节占用的字节数

Float - 4
Double - 8
Decimal - 12