2286

.NET和.NETdecimal中有什么区别?floatdouble

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

4

18 回答 18

2458

float并且double浮点二进制点类型。换句话说,它们代表这样的数字:

10001.10010110011

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

decimal浮点数类型_ 换句话说,它们代表这样的数字:

12345.65789

同样,数字和小数点的位置都在值内编码——这就是decimal仍然是浮点类型而不是定点类型的原因。

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

至于什么时候用:

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

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

于 2009-03-06T11:56:02.670 回答
1186

精度是主要区别。

浮点数- 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
于 2009-03-06T11:33:02.363 回答
109
+---------+----------------+---------+----------+---------------------------------------------------------+
| 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                                           |
+---------+----------------+---------+----------+---------------------------------------------------------+

请参阅此处了解更多信息

于 2013-06-07T12:50:10.403 回答
92

Decimal 结构严格适用于需要精确度的金融计算,相对不能容忍四舍五入。然而,小数对于科学应用来说是不够的,原因如下:

  • 由于被测量的物理问题或人工制品的实际限制,在许多科学计算中,一定程度的精度损失是可以接受的。在金融领域,精度损失是不可接受的。
  • 对于大多数操作来说,十进制比浮点和双精度要慢得多(很多),主要是因为浮点运算是以二进制完成的,而十进制的东西是以 10 为底完成的(即浮点和双精度由 FPU 硬件处理,例如 MMX/SSE ,而小数是在软件中计算的)。
  • 尽管 Decimal 支持更多位数的精度,但 Decimal 的值范围比 double 小得令人无法接受。因此,Decimal 不能用于表示许多科学值。
于 2011-04-13T13:55:01.900 回答
70

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

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

对计数值使用小数

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

一些例子:

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

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

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

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

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

于 2016-04-22T15:18:17.973 回答
50

float7位精度

double大约有 15 位的精度

decimal大约有 28 位精度

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

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

于 2011-08-29T00:06:27.303 回答
42

没有人提到过

在默认设置中,浮点数 (System.Single) 和双精度数 (System.Double) 永远不会使用溢出检查,而十进制 (System.Decimal) 将始终使用溢出检查。

我是说

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

抛出溢出异常。

但这些不会:

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

&

double myNumber = double.MaxValue;
myNumber += 1;
于 2015-01-02T13:12:39.123 回答
28

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

float myFloat;
double myDouble;

float是“浮点数”的缩写,仅表示末尾带有点的数字。)

两者之间的区别在于它们可以容纳的数字的大小。对于float,您的号码中最多可以有 7 位数字。对于doubles,您最多可以有 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# 将再次向上或向下舍入。道德是如果你想要准确,小心四舍五入!

于 2012-05-22T12:05:17.550 回答
27
  1. 在编译和运行时,双精度和浮点数都可以被整数零除而无一例外。
  2. 小数不能除以整数零。如果你这样做,编译总是会失败。
于 2010-07-29T07:21:10.860 回答
18
  • 浮动:±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 位有效数字)
于 2014-01-02T05:01:41.580 回答
13

这对我来说是一个有趣的话题,因为今天,我们刚刚遇到了一个令人讨厌的小错误,关于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完全丢失了值。一个这样的例子是

  • 单元格值 = 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精度低于 a decimal,但这实际上确保了仍然可以识别小数字。由于某种原因,double.TryParse实际上能够检索到如此小的数字,而decimal.TryParse将它们设置为零。

奇怪的。很奇怪。

于 2012-04-16T09:23:44.703 回答
13

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

浮点数 - 32 位(7 位)

双 - 64 位(15-16 位)

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

更多关于... Decimal、Float 和 Double 之间的区别

于 2014-09-30T08:22:24.160 回答
8

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

于 2014-05-16T16:21:29.247 回答
8
  • 十进制128 位(28-29 位有效数字) 在金融应用中,最好使用 Decimal 类型,因为它可以为您提供高水平的准确性并且易于避免舍入错误 在需要精度的非整数数学中使用十进制(例如货币和货币)

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

  • 浮点 32 位(7 位) 它主要用于图形库,因为对处理能力的要求非常高,也用于可以忍受舍入错误的情况。

Decimals比 a 慢得多double/float

Decimals并且Floats/Doubles不能在没有强制转换的情况下进行比较,而FloatsDoubles可以。

Decimals还允许编码或尾随零。

于 2019-12-14T12:16:36.717 回答
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 !!!

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

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

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

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

令人遗憾的是,在 COBOL 中实现的其他数字类型在 .Net 中不存在。对于那些不知道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) 
于 2017-02-23T13:05:31.637 回答
4

简单来说:

  1. Decimal、Double 和 Float 变量类型在存储值的方式上有所不同。
  2. 精度是主要区别(注意这不是单一的区别),其中float是单精度(32 位)浮点数据类型,double是双精度(64 位)浮点数据类型,decimal是 128 位浮点数据类型。
  3. 汇总表:

/==========================================================================================
    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)
/==========================================================================================
您可以在此处 阅读更多内容,FloatDoubleDecimal

于 2018-02-10T08:47:40.287 回答
2

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

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

于 2014-12-21T18:50:12.293 回答
-3

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

您必须将值提及为:

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

并检查结果。

并且每个占用的字节数是

Float - 4
Double - 8
Decimal - 12
于 2020-01-17T11:26:59.830 回答