关于浮点:在.NET中十进制、浮点和双精度之间的区别?

Difference between decimal, float and double in .NET?

.net中的decimalfloatdouble有什么区别?

什么时候会有人用这些?


(P)EDOCX1(英文)0和EDOCX1(英文)1是"Floating Binary Point Types"。In other words,they represent a number like this:(p)字母名称(P)The binary number and the location of the binary point are both enceded within the value.(p)(P)12.EDOCX1是一个十进制点类型。In other words,they represent a number like this:(p)字母名称(P)Again,the number and the location of the Decima point are both enceded within the value–That's what makes EDOCX1 biblic 2 still a fluating point type instead of a fixed point type.(p)(P)The important thing to note is that humans are used to representing non-integers in a Decima form,and expect exact results in Decima representations;not a ll Decima numbers are exactly representable in binary floating point–0.1,for example…,so if you use a binary floating point value you'll actually get an approxiation to 0.1.You'll still get approximations when you using a fluating Decima Point as well–The result of diversing 1 by 3 can't be exactly represented,for example.(p)(P)As for what to use when:(p)

  • (P)For values which are"naturally exact decomers"it's good to use theocx1.这通常适用于人类发明的任何概念:金融价值是最明显的例子,但也有其他的例子。例如,考虑到Score given to divers or ice skaters.(p)
  • (P)For values which are more artfacts of nature which can't really be measured exactly anyway,EDOCX1 pental 0/EDOCX1 pental 1 is more appropriate.For example,scientific data would usually be represented in this form.在这方面,最初的价值不会是"Decomly accurate"to start with,so it's not important for the expected results to maintain the"Decima Accuracy".Floating binary point types are much faster to work with than DecMals.(p)


(P)Precision is the main difference.(p)(P)FLOAT-7 DIGIITS(32比特)(p)(P)Double-15-16 digits(64比特)(p)(P)Decima-28-29 Significant Digits(128比特)(p)(P)Decimals have much higher precision and are usually used within financial applications that require a high degree of accuracy.Decimals are much slower(up to 20x times in some tests)than a double/float.(p)(P)Decimals and floats/doubles cannot be compared without a cast where floats and doubles can.Decima also allow the encourage or trailing zeros.(p)字母名称(P)结果:(p)字母名称


(P)The Decima structure is strictly geared to financial calculations requiring accuracy,which are relatively intolerant of rounding.Decima are not adequate for scientific applications,however,for several reasons:(p)

  • 由于物理问题或测量方法的实际限度,精确性的某些损失在许多科学计算中是可以接受的。在金融方面,不可接受的是缺乏精确性。
  • Decima is much(much)Slower than float and double for most operations,primarily because floating point operations are done in binary,Whereas Decima Stuff is done in Base 10(I.E.Floats and Doubles are handled by the FPU Hardware,such as MMX/SE,where Decials are calculated in software).
  • Decima has an unacceptably smaller value range than double,despite the fact that it supports more digits of precision.Therefore,Decima can't be used to represent many scientific values.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
+---------+----------------+---------+----------+---------------------------------------------+
| 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


(P)字母名称0(p)(P)EDOCX1 has about 15 digits of precision(p)(P)EDOCX1 2 common has about 28 digits of precision(p)(P)如果你需要更好的协调,使用两个不间断的流量。在现代CPUS both data types have almost the same performance.The only benefit of using flat is they take up less space.实际上,只有当你有很多他们。(p)(P)我发现这是利益。电脑科学家应该知道些什么?(p)


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

When would someone use one of these?

对计数值使用小数

测量值使用浮点/双精度

一些例子:

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

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

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

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

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


没有人提到过

In default settings, Floats (System.Single) and doubles (System.Double) will never use
overflow checking while Decimal (System.Decimal) will always use
overflow checking.

我的意思是

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

引发溢出异常。

但这些不是:

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

和;

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


  • Double and float can be divided by integer Zero without an exception at both compilation and run time.
  • Decima cannot be divided by integer Zero.Compilation will always fail if you do that.

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

    1
    2
    float myFloat;
    double myDouble;

    (float是"浮点"的缩写,意思是一个带点的数字,后面有点。)

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

    1
    2
    float:  1.5 × 10^-45  to 3.4 × 10^38  
    double: 5.0 × 10^-324 to 1.7 × 10^308

    float是32位数字,double是64位数字。

    双击新按钮获取代码。在按钮代码中添加以下三行:

    1
    2
    3
    double myDouble;
    myDouble = 0.007;
    MessageBox.Show(myDouble.ToString());

    停止程序并返回到"Coding(编码)"窗口。更改此行:

    1
    2
    myDouble = 0.007;
    myDouble = 12345678.1234567;

    运行你的程序并点击你的双按钮。消息框正确显示数字。不过,在末尾再加一个数字,C将再次向上或向下取整。道德上,如果你想要精确,小心取整!


    这对我来说是一个有趣的线索,就像今天,我们刚刚遇到了一个讨厌的小错误,关于decimal的精度低于float

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

    1
    2
    3
    4
    5
    6
    7
    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.typarse(cellValue.toString(),out value);//将返回0

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    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会将它们设置为零。

    奇怪的。非常奇怪。


    • 浮动:±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位有效数字)


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


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

    浮点-32位(7位)

    双64位(15-16位)

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

    关于…小数、浮点数和双精度数的区别


    所有这些类型的问题是存在某种不精确性这个问题可以发生在小的十进制数上,如下面的例子

    1
    2
    3
    4
    5
    6
    7
    8
    9
    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

    问题:鼓风机变量包含哪些值?

    答:在32位机器上,鼓风机包含"真"!!!!

    如果我把double替换成decimal,则blower包含false,这是一个很好的答案。

    问题是,fmean fdelta=1.09999999999低于1.1。

    注意:我认为对于其他数字也会存在同样的问题,因为十进制只是一个精度更高的双精度数,而且精度总是有限制的。

    实际上,double、float和decimal在COBOL中对应于二进制十进制!

    很遗憾,COBOL中实现的其他数字类型在.NET中不存在。对于那些不知道COBOL的人,在COBOL中有以下数字类型

    1
    2
    3
    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)

    简单来说:

  • decimal、double和float变量类型在存储值的方式上是不同的。
  • 精度是主要区别(请注意,这不是单精度差),其中float是单精度(32位)浮点数据类型,double是双精度(64位)浮点数据类型,decimal是128位浮点数据类型。
  • 汇总表:
  • 1
    2
    3
    4
    5
    6
    7
    /==========================================================================================
        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)
    /==========================================================================================

    代码>您可以在这里阅读更多内容:浮点、双精度和小数。


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

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