.NET中的 decimal , float 和 double 有什么区别?
decimal
float
double
什么时候会有人使用其中一种?
对于内存和性能都很关键的游戏和嵌入式系统等应用程序,float通常是数字类型,因为它更快,是double的一半大小 . 整数曾经是首选武器,但浮点性能在现代处理器中已超过整数 . 十进制就出来了!
所有这些类型的问题是某些不精确性存在并且这个问题可能发生在小的十进制数字中,如下例所示
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)
float 7位精度
double 具有大约15位精度
decimal 具有大约28位精度
如果您需要更高的精确度,请使用double而不是float . 在现代CPU中,两种数据类型具有几乎相同的性能 . 使用浮动的唯一好处是它们占用的空间更少 . 只有当你有很多这样的事情时才真正重要 .
我发现这很有趣 . What Every Computer Scientist Should Know About Floating-Point Arithmetic
Decimal,Double和Float变量类型在存储值方面有所不同 . 精度是主要区别,其中float是单精度(32位)浮点数据类型,double是双精度(64位)浮点数据类型,decimal是128位浮点数据类型 .
浮动 - 32位(7位)
双 - 64位(15-16位)
十进制 - 128位(28-29位有效数字)
更多关于...... the difference between Decimal, Float and Double
float 和 double 是floating binary point types . 换句话说,它们代表了这样的数字:
10001.10010110011
二进制数和二进制点的位置都在该值内编码 .
decimal 是floating decimal point type . 换句话说,它们代表了这样的数字:
12345.65789
同样,小数点的数量和位置都在值内编码 - 这使得 decimal 仍然是浮点类型而不是固定点类型 .
需要注意的重要一点是,人类习惯于以十进制形式表示非整数,并期望十进制表示中的精确结果;并非所有的十进制数都可以在二进制浮点中精确表示 - 例如0.1 - 所以如果你使用二进制浮点值,你实际上会得到0.1的近似值 . 在使用浮动小数点时,您仍然可以获得近似值 - 例如,无法准确表示将1除以3的结果 .
至于什么时候使用:
对于"naturally exact decimals"的值,最好使用 decimal . 这通常适用于人类发明的任何概念:财务 Value 是最明显的例子,但也有其他概念 . 例如,考虑给予潜水员或滑冰者的分数 .
对于那些无论如何都无法真正准确测量的更多人工制品的值, float / double 更合适 . 例如,科学数据通常以这种形式表示 . 在这里,原始值赢得't be 117929 to start with, so it'对于维持"decimal accuracy"的预期结果并不重要 . 使用浮点二进制点类型比使用小数要快得多 .
如前所述,整数是整数 . 他们无法存储点数,例如.7,.42和.007 . 如果您需要存储非整数的数字,则需要使用不同类型的变量 . 您可以使用double类型或float类型 . 您以完全相同的方式设置这些类型的变量:而不是使用单词 int ,键入 double 或 float . 像这样:
int
float myFloat; double myDouble;
( float 是"floating point"的缩写,只是表示最后有点的数字 . )
两者之间的差异在于它们可以容纳的数字的大小 . 对于 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#将再次向上或向下舍入 . 道德是如果你想要准确,小心四舍五入!
Double和float可以除以整数零,在编译和运行时都没有异常 .
十进制不能除以整数零 . 如果这样做,编译将始终失败 .
我不会重复已经在其他答案和评论中回答的大量好的(和一些坏的)信息,但我会用一个提示回答你的后续问题:
使用小数表示 counted 值
使用float / double表示 measured 值
一些例子:
钱(我们数钱还是衡量金钱?)
距离(我们计算距离还是测量距离?*)
分数(我们计算分数还是衡量分数?)
我们总是数钱,不应该衡量它 . 我们通常测量距离 . 我们经常算得分 .
*在某些情况下,我称之为名义距离,我们可能确实想要'count'距离 . 例如,也许我们正在处理显示到城市的距离的国家标志,我们知道那些距离永远不会超过一个十进制数字(xxx.x km) .
漂浮〜±1.5 x 10-45到±3.4 x 1038 -------- 7个数字double~±5.0 x 10-324到±1.7 x 10308 ------ 15或16位数十进制〜±1.0 x 10-28到±7.9 x 1028 -------- 28或29个数字
这对我来说是一个有趣的线程,因为今天,我们刚刚遇到了一个令人讨厌的小bug,关于 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 ,然后转换为 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 会将它们设置为零 .
奇 . 很奇怪 .
没有人提到这一点
在默认设置中,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;
这些中的每一个之间的主要区别在于精度 .
float 是 32-bit 号, double 是 64-bit 号, decimal 是 128-bit 号 .
32-bit
64-bit
128-bit
简单来说:
Decimal,Double和Float变量类型在存储值方面有所不同 .
精度是 main difference (请注意,这不是单个差异),其中 float 是单精度(32位)浮点数据类型, double 是双精度(64位)浮点数据类型, decimal 是128位浮点数据类型 .
摘要表:
/========================================================================================== 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) /==========================================================================================
您可以阅读更多here,Float,Double和Decimal .
精度是主要的区别 .
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比float和double慢很多(主要是因为浮点运算是以二进制形式完成的,而Decimal的东西是在10中完成的(即浮点数和双精度由FPU硬件处理,例如MMX / SSE,而小数用软件计算) .
尽管它支持更多的精度数字,但Decimal的值范围比double小得多 . 因此,Decimal不能用于表示许多科学 Value .
+---------+----------------+---------+----------+---------------------------------------------+ | 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
16 回答
对于内存和性能都很关键的游戏和嵌入式系统等应用程序,float通常是数字类型,因为它更快,是double的一半大小 . 整数曾经是首选武器,但浮点性能在现代处理器中已超过整数 . 十进制就出来了!
所有这些类型的问题是某些不精确性存在并且这个问题可能发生在小的十进制数字中,如下例所示
问题: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中存在数字类型
float
7位精度double
具有大约15位精度decimal
具有大约28位精度如果您需要更高的精确度,请使用double而不是float . 在现代CPU中,两种数据类型具有几乎相同的性能 . 使用浮动的唯一好处是它们占用的空间更少 . 只有当你有很多这样的事情时才真正重要 .
我发现这很有趣 . What Every Computer Scientist Should Know About Floating-Point Arithmetic
Decimal,Double和Float变量类型在存储值方面有所不同 . 精度是主要区别,其中float是单精度(32位)浮点数据类型,double是双精度(64位)浮点数据类型,decimal是128位浮点数据类型 .
浮动 - 32位(7位)
双 - 64位(15-16位)
十进制 - 128位(28-29位有效数字)
更多关于...... the difference between Decimal, Float and Double
float
和double
是floating binary point types . 换句话说,它们代表了这样的数字:二进制数和二进制点的位置都在该值内编码 .
decimal
是floating decimal point type . 换句话说,它们代表了这样的数字:同样,小数点的数量和位置都在值内编码 - 这使得
decimal
仍然是浮点类型而不是固定点类型 .需要注意的重要一点是,人类习惯于以十进制形式表示非整数,并期望十进制表示中的精确结果;并非所有的十进制数都可以在二进制浮点中精确表示 - 例如0.1 - 所以如果你使用二进制浮点值,你实际上会得到0.1的近似值 . 在使用浮动小数点时,您仍然可以获得近似值 - 例如,无法准确表示将1除以3的结果 .
至于什么时候使用:
对于"naturally exact decimals"的值,最好使用
decimal
. 这通常适用于人类发明的任何概念:财务 Value 是最明显的例子,但也有其他概念 . 例如,考虑给予潜水员或滑冰者的分数 .对于那些无论如何都无法真正准确测量的更多人工制品的值,
float
/double
更合适 . 例如,科学数据通常以这种形式表示 . 在这里,原始值赢得't be 117929 to start with, so it'对于维持"decimal accuracy"的预期结果并不重要 . 使用浮点二进制点类型比使用小数要快得多 .如前所述,整数是整数 . 他们无法存储点数,例如.7,.42和.007 . 如果您需要存储非整数的数字,则需要使用不同类型的变量 . 您可以使用double类型或float类型 . 您以完全相同的方式设置这些类型的变量:而不是使用单词
int
,键入double
或float
. 像这样:(
float
是"floating point"的缩写,只是表示最后有点的数字 . )两者之间的差异在于它们可以容纳的数字的大小 . 对于
float
,您的号码最多可以包含7位数字 . 对于double
s,最多可包含16位数字 . 更确切地说,这是官方规模:float
是32位数字,double
是64位数字 .双击新按钮以获取代码 . 将以下三行添加到按钮代码中:
暂停程序并返回编码窗口 . 改变这一行:
运行程序并单击双击按钮 . 该消息框正确显示数字 . 但是,最后添加另一个数字,C#将再次向上或向下舍入 . 道德是如果你想要准确,小心四舍五入!
Double和float可以除以整数零,在编译和运行时都没有异常 .
十进制不能除以整数零 . 如果这样做,编译将始终失败 .
我不会重复已经在其他答案和评论中回答的大量好的(和一些坏的)信息,但我会用一个提示回答你的后续问题:
使用小数表示 counted 值
使用float / double表示 measured 值
一些例子:
钱(我们数钱还是衡量金钱?)
距离(我们计算距离还是测量距离?*)
分数(我们计算分数还是衡量分数?)
我们总是数钱,不应该衡量它 . 我们通常测量距离 . 我们经常算得分 .
*在某些情况下,我称之为名义距离,我们可能确实想要'count'距离 . 例如,也许我们正在处理显示到城市的距离的国家标志,我们知道那些距离永远不会超过一个十进制数字(xxx.x km) .
漂浮〜±1.5 x 10-45到±3.4 x 1038 -------- 7个数字
double~±5.0 x 10-324到±1.7 x 10308 ------ 15或16位数
十进制〜±1.0 x 10-28到±7.9 x 1028 -------- 28或29个数字
这对我来说是一个有趣的线程,因为今天,我们刚刚遇到了一个令人讨厌的小bug,关于
decimal
的精度低于float
.在我们的C#代码中,我们从Excel电子表格中读取数值,将它们转换为
decimal
,然后将此decimal
发送回服务以保存到SQL Server数据库中 .现在,对于我们几乎所有的Excel值,这都非常有效 . 但是对于一些非常小的Excel值,使用 decimal.TryParse 完全丢失了该值 . 一个这样的例子是
cellValue = 0.00006317592
Decimal.TryParse(cellValue.ToString(),out value); //会返回 0
奇怪的是,解决方案是首先将Excel值转换为
double
,然后转换为decimal
:尽管
double
的精度低于decimal
,但实际上确保了小数字仍然可以识别 . 出于某种原因, double.TryParse 实际上能够检索到这么小的数字,而 decimal.TryParse 会将它们设置为零 .奇 . 很奇怪 .
没有人提到这一点
我的意思是
抛出 OverflowException .
但这些不是:
&
这些中的每一个之间的主要区别在于精度 .
float
是32-bit
号,double
是64-bit
号,decimal
是128-bit
号 .简单来说:
Decimal,Double和Float变量类型在存储值方面有所不同 .
精度是 main difference (请注意,这不是单个差异),其中 float 是单精度(32位)浮点数据类型, double 是双精度(64位)浮点数据类型, decimal 是128位浮点数据类型 .
摘要表:
您可以阅读更多here,Float,Double和Decimal .
精度是主要的区别 .
Float - 7位数(32位)
Double -15-16位(64位)
Decimal -28-29有效数字(128位)
小数具有更高的精度,通常用于需要高精度的金融应用程序中 . 小数比一个双/浮点慢得多(在某些测试中高达20倍) .
如果没有演员阵容,则无法比较小数和浮点数/双打,而浮点数和双打则可以 . 小数也允许编码或尾随零 .
结果:
十进制结构严格适用于要求准确性的财务计算,这对于舍入是相对不容忍的 . 然而,小数不足以用于科学应用,原因如下:
由于物理问题或测量的人工制品的实际限制,在许多科学计算中可以接受一定的精度损失 . 财务方面的精确度损失是不可接受的 .
对于大多数操作,Decimal比float和double慢很多(主要是因为浮点运算是以二进制形式完成的,而Decimal的东西是在10中完成的(即浮点数和双精度由FPU硬件处理,例如MMX / SSE,而小数用软件计算) .
尽管它支持更多的精度数字,但Decimal的值范围比double小得多 . 因此,Decimal不能用于表示许多科学 Value .
欲获得更多信息,看到:
http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/921a8ffc-9829-4145-bdc9-a96c1ec174a5