.net NET中十进制、浮点和双精度之间的差异?
在.NET中,.net NET中十进制、浮点和双精度之间的差异?,.net,floating-point,double,decimal,.net,Floating Point,Double,Decimal,在.NET中,decimal、float和double之间有什么区别 什么时候会有人使用其中一种?精度是主要区别 -7位(32位) -15-16位(64位) -28-29位有效数字(128位) 小数具有更高的精度,通常用于要求高精度的金融应用程序中。小数比双精度/浮点数慢得多(在某些测试中高达20倍) 小数和浮点数/双精度不能在没有强制转换的情况下进行比较,而浮点数和双精度可以进行比较。小数也允许编码或尾随零 float flt = 1F/3; double dbl = 1D/3; decima
decimal
、float
和double
之间有什么区别
什么时候会有人使用其中一种?精度是主要区别 -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.3333333
double: 0.333333333333333
decimal: 0.3333333333333333333333333333
float
和double
是。换句话说,它们代表如下数字:
10001.10010110011
12345.65789
二进制数和二进制点的位置都在值内编码
decimal
是一个数字。换句话说,它们代表如下数字:
10001.10010110011
12345.65789
同样,小数点的数字和位置都在值中编码–这就是为什么decimal
仍然是浮点类型而不是定点类型
需要注意的重要一点是,人类习惯于以十进制形式表示非整数,并期望以十进制表示的精确结果;并非所有的十进制数都可以用二进制浮点表示,例如0.1,所以如果使用二进制浮点值,实际上可以得到0.1的近似值。当使用浮点小数点时,仍然会得到近似值–例如,1除以3的结果无法精确表示
关于在以下情况下使用什么:
- 对于“自然精确小数”的值,最好使用
。这通常适用于人类发明的任何概念:金融价值是最明显的例子,但也有其他例子。考虑到潜水员或溜冰运动员的得分,例如:decimal
- 对于那些更为自然产物的值,而这些值无论如何都无法准确测量,
/float
更为合适。例如,科学数据通常以这种形式表示。在这里,原始值一开始就不是“小数精度”,因此保持“小数精度”对预期结果并不重要。使用浮点二进制点类型比使用小数要快得多double
十进位结构严格适用于要求精确的财务计算,这相对不允许四舍五入。但是,小数不足以用于科学应用,原因如下:
- 在许多科学计算中,由于被测量的物理问题或人工制品的实际限制,一定程度的精度损失是可以接受的。在金融领域,精度损失是不可接受的
- 对于大多数操作,十进制比浮点和双精度运算慢得多,主要是因为浮点运算是在二进制中完成的,而十进制是在10进制中完成的(即浮点和双精度运算由FPU硬件处理,如MMX/SSE,而小数是在软件中计算的)
- Decimal的值范围比double小得令人无法接受,尽管它支持更多的精度数字。因此,十进制不能用来表示许多科学值
float
7位精度
double
大约有15位精度
decimal
大约有28位精度
如果您需要更高的精度,请使用double而不是float。
在现代CPU中,两种数据类型的性能几乎相同。使用float的唯一好处是它们占用更少的空间。事实上,只有当你拥有很多的时候才有意义
我发现这很有趣 这对我来说是一条有趣的线索,因为今天,我们刚刚遇到了一个令人讨厌的小错误,
decimal
的精度低于float
在C#代码中,我们从Excel电子表格中读取数值,将其转换为十进制
,然后将该十进制
发送回服务以保存到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值);//将返回0
双精度
,然后再转换为十进制
:
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.TryParse
实际上能够检索如此小的数字,而decimal.TryParse
会将它们设置为零
奇怪。非常奇怪。如前所述,整数是整数。他们无法存储点,比如.7、.42和.007。如果需要存储非整数的数字,则需要不同类型的变量。您可以使用double类型或float类型。您以完全相同的方式设置这些类型的变量:不使用单词
int
,而是键入double
或float
。像这样:
float myFloat;
double myDouble;
(float
是“浮点”的缩写,只是指一个数字的末尾有一个点。)
区别
myDouble = 0.007;
myDouble = 12345678.1234567;
+---------+----------------+---------+----------+---------------------------------------------------------+
| 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 |
+---------+----------------+---------+----------+---------------------------------------------------------+
decimal myNumber = decimal.MaxValue;
myNumber += 1;
float myNumber = float.MaxValue;
myNumber += 1;
double myNumber = double.MaxValue;
myNumber += 1;
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
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)
/==========================================================================================
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)
/==========================================================================================
Decimal dec = 12M/6;
Double dbl = 11D/6;
float fl = 15F/6;
Float - 4
Double - 8
Decimal - 12