.net中的decimal、float和double有什么区别?
什么时候会有人用这些?
- 有趣的文章zetcode.com/lang/csharp/datatypes
- 相关:sandbox.mc.edu/~bennet/cs110/flt/dtof.html
(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)
- float/double通常不表示数字为101.101110,通常表示为类似于1101010 * 2^(01010010)的指数。
- @哈扎德:答案的"和二进制点的位置"部分就是这个意思。
- 我很惊讶还没有人说,float是一个c别名关键字,不是.net类型。是System.Single。single和double是浮动二进制点类型。
- 等等……难道最后不是用1和0来表示小数吗?我以为计算机只能以二进制形式工作。所以十进制最终是二进制的,不是吗?
- @Bkspugeon:好吧,只有以同样的方式,你可以说,一切都是二进制类型,在这一点上,它成为一个相当无用的定义。decimal是一种十进制类型,它是一个表示为整数有效位和小数位数的数字,因此结果是有效位*10^小数位数,而float和double是有效位*2^小数位数。取一个以十进制书写的数字,将小数点向右移动到足够远的位置,这样就可以得到一个整数来计算有效位和小数位数。对于float/double,您可以从一个二进制数字开始。
- 另一个方面是这些数据类型之间的转换:单数据类型和双数据类型-使用"模糊"比较-从双数据类型到单数据类型的转换会丢失精度-从单数据类型到双数据类型的转换会造成不准确-从十进制转换会导致基之间的舍入错误-创建团队C在您使用的数据类型上存在[样式指南],并观察转换
- 另一个区别是:浮点32位;双64位;十进制128位。
(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)字母名称
- 这个答案需要修正。十进制的精度不是128位,而是无穷大的,因为格式与浮点有本质的不同。@双向飞碟答案是最好的。Example: 0.1 = 0.099999.... in float but in decimal it is 0.l, that is infinite precision. If you were to use 128 bits precision like in floats, you would get 0.999999....(upto 29 digits) but that is still not precise as decimal 0.1
- @主持人:对不起,十进制不能代表所有可以用十进制表示的数字,但不能代表1/3。1.0米/3.0米将评估为0.333333…结尾有大量但有限的3s。乘以3不会返回精确的1.0。
- 这是数字本身的错误(0.3333…在这种情况下),而不是它的十进制表示,它是100%忠实地产生的。当您在数字中引入错误时,任何主体都不能删除它(甚至十进制数字也不能删除)。从这个数字中消除错误的唯一方法是使用1/3而不是0.333。有些计算器可能取1/3作为中间值,但大多数不是。
- @主持人:我认为你混淆了准确性和精确性。在这种情况下,它们是不同的。Precision是可用来表示数字的位数。精度越高,就越不需要旋转。没有数据类型具有无限精度。
- @igBylargeman精度和准确性用于仪器测量值的环境。在这种情况下,我们不讨论任何仪器。我们只讨论用小数和浮点忠实地表示一个值。在这里,精度不适用,因为我们不谈论测量相同值的一致性,一次又一次。但准确是可以的。小数点在其范围内的精度为100%,即无限精度。
- @rocodilehunter:您假设要测量的值正好是0.1--在现实世界中很少发生这种情况!任何有限的存储格式都会将无限数量的可能值合并为有限数量的位模式。例如,float将0.1和0.1 + 1e-8合并,而decimal将0.1和0.1 + 1e-29合并。当然,在给定的范围内,某些值可以以零精度损失的任何格式表示(例如,float可以以零精度损失存储高达1.6e7的任何整数),但这仍然不是无限精度。
- @Danielpryden,好吧,我相信float代表0.1,而不是0.1+1e-29。这是因为格式与float本质上不同。这就是为什么它非常缓慢但准确的原因。如果你是对的,那么小数就没用了。记住float if(0.1 = 0.1)中的主要问题,当我们认为这个条件应该是正确的时候,这个条件不成立。在十进制中,它将始终为真,因为0.1将是0.1,而其他值则为零。例如,它不会是0.999999999999999999999999。
- @主持人:你没明白我的意思。0.1不是一个特殊值!唯一能使0.1比0.10000001更好的是因为人类像基数10。即使使用float值,如果用相同的方法初始化两个值,它们都将是相同的值。只是这个值不一定是0.1,它是最接近0.1的值,可以精确地表示为float。当然,对于二进制浮点数,(1.0 / 10) * 10 != 1.0,但是对于十进制浮点数,(1.0 / 3) * 3 != 1.0。两者都不是完全精确的。
- @丹尼尔普里登,小数点,精确到0.1。当然,这不仅仅是0.1。很多小数都有这个问题。事实是十进制的(0.1==0.1)将始终为真。在float中,它可能是真的,也可能不是真的,因为实际的二进制值可能不是0.1。
- @主持人:你还是不明白。我不知道该怎么更清楚地说:在C语言中,如果你用double a = 0.1; double b = 0.1;,那么a == b就是真的。只是a和b并不完全等同于0.1。在c中,如果您执行decimal a = 1.0m / 3.0m; decimal b = 1.0m / 3.0m;,那么a == b也将是正确的。但在这种情况下,a和b都不能完全等同于1/3,它们都不能等同于0.3333...。在这两种情况下,由于表示的原因,某些精度会丢失。你顽固地说,decimal具有"无限"精度,这是错误的。
- @主持人:为了以防万一你不相信我,这里有一些示例代码显示了0.1 == 0.1。
- 这应该标记为正确答案。乔恩·斯基特的回答有点令人困惑…
- @奇布埃泽奥帕特亚:斯基特的回答讨论了一个完全独立的差异,这个答案完全忽略了。就我个人而言,我认为双向飞碟的答案更有价值,因为他的答案在决定使用哪种数据类型时更为相关。
- @布赖恩,它们都很有价值,这就是为什么我一开始就说,没有彼此,它们是不完整的。然而,关于所问的问题,这个答案只是直截了当地告诉你基本的区别。你可以在乔恩·斯基特的回答中从这一个中扣除几乎所有的扣款。:)
- @不,你不能,因为这个答案甚至没有提到十进制/二进制的区别。
- @丹尼尔普里登-我知道这是一个老问题,但也许我可以帮助澄清。这里的问题是,当表示在十进制格式精度范围内的数字时,十进制数字是100%准确的。也就是说,不是π,或1/3,或2/3的结果。这无关紧要,因为这些数字需要比十进制更高的精度。如果对超过精度的十进制值进行计算,则所有下注都将关闭。对于格式精度范围内的浮点数/双位数,不一定总是100%准确。例如1。
- @神秘人:你所说的"在十进制格式的精度范围内"是什么意思?如果您要测量的数字正好是一个整数的10次方,那么绝对要使用decimal。在日常生活中遇到的许多数字都具有这种特性(因为它们是离散的,而不是连续的,测量),但其他许多数字则没有。任何用途的正确数据类型始终取决于用途。请不要把我在这里说的任何一句话误认为是暗示任何人都应该总是使用浮点数——我只是在说一个人不应该盲目地总是使用decimal。
- @神秘人:我认为你的一部分困惑被短语"在格式的精确范围内"所出卖。我不认为这有道理——你的意思是"在可代表的范围内"吗?但即使这样也不能证明什么:0.1不再是2^53+1的"精确范围",而且两者都可以同样忠实地表示。
- 几乎每次浮点表示的精度问题(无论是十进制还是二进制)出现时,都会有一段长时间的交叉讨论。从根本上说,这是由于浮点数表示的精确值是否与现实世界中的相同精确值对应的问题。这不能通过观察数字本身的表示来知道;它只能由使用表示的人知道。
- 下面是一个C(本文将讨论)的小示例代码,它将问题可视化(使用十进制和浮点)。(0.1f == 1f/10)和(0.1m == 1m/10)。第一个将评估为假,而第二个将评估为真,即使两者都应评估为真。这是因为float不能精确地存储值0.1。
- @davidm&229;rtensson:为什么0.1f不等于1f/10?这两个值不应该都是13421773/134217728吗?
- @supercat是因为float在内部的工作方式0.1f不能以内部二进制格式精确表示,而且由于计算在内部使用的精度更高,1f/10不会落在与0.1f相同的舍入值上,因此它们将不相等。
- @davidm&229;rtensson:表达式1f/10的编译时类型是float。您是说,在执行比较之前,编译器不需要将除法的结果四舍五入到最接近的float?我认为这有点破坏了这样一个事实,即允许直接将float与任何其他东西进行比较,或将double与除32位或更小整数以外的任何其他东西进行比较[我认为需要强制转换],但我认为严重破坏了一个编译器,它执行了语言规则中的浮点/浮点比较虽然这是一个浮动/双重比较。
- @davidm&229;rtensson:(顺便说一下,我想看到的是一种同时具有"loose"和"strict"32位和64位浮点类型的语言,其中严格的类型不接受任何隐式转换,"loose"类型将被定义为将操作结果扩展到double,并且通常允许隐式向下转换o float,但不允许直接比较32位和64位值。我假设,虽然C对double d1=f1*f2;毫无疑问,但程序员很少真正打算让d1持有float精度结果。)
- 二进制浮点的IEEE标准不要求严格的十进制精度,请参阅下面的MarkJones答案。它不是由语言定义的。如果需要严格的四舍五入,则应使用十进制数据类型,该数据类型是一个十进制浮点,如jon skeet在下面的mehrdad答案中指出的那样。不同的类型有不同的用途和要求。例如,当计算物理中的实际值时,原始数字可能比编译器的精度低,因此计算错误通常对测量错误的影响较小。
- 另一种尝试是把钉子钉在头上:float和double都可以精确地代表p/q的分数形式,其中q是2的幂。例如0.5、3.25、1/256等,但是decimal可以精确地表示p/q形式的分数,其中q是10(10)的幂。看看这个答案。虽然decimal的有效位数更高是正确的,但这样做是有误导性的;这种表示与float和double有根本的不同,decimal用于精确的十进制计算。
- 精度不是主要区别。小数以10为基数是主要区别。
- -1没有提到范围或不同的基础。
- -1虽然float和double的主要区别是精度,但float、double和decimal的主要区别不是。的确,十进制的精度更高,但更重要的是,它还以十进制为中心的格式存储值,而不是以二进制为中心的格式存储值的float和double。举个例子,十进制中的数字".75"相当于二进制中的".11",因为二分之一加四分之一等于四分之三。当然,一些小数点十进制值(即使在~7位范围内)只能通过双精度和浮点来近似。
- @当q是2的幂或5的幂(即素因子为10)时,matt decimal可以精确地表示形式p/q的分数。例如,考虑1/2(0.5)和1/5(0.2);分母都不是10的幂。
- @hmd考虑一个浮点基3系统,其中1/10(而不是1/101)是无限重复分数:0.00220022….但是,1/3不是;它是0.1。考虑一下马特的评论:在给定的基数中可以精确表示的分数是那些使用基数的素数因子的分数。十进制没有无限的精度;它有28位十进制的精度。如果它真的有无限的精度,你就可以代表EDOCX1的一半(0)。但是你不能,把它除以2就得到了0.0000000018626451492309570312m,而不是0.00000000186264514923095703125。
- @Phoog不要求P/Q采用最简单的形式。在您的示例中,1/2=5/10和1/5=2/10,因此具有精确的十进制表示。另一个例子是1/20=0.05,其中分母既不是2、5或10的幂。你说"当q是2的幂或5的幂时,十进制可以精确地表示p/q形式的分数"。尽管从技术上讲是正确的,但实际上这比我所说的要严格,因为1/10,例如,不能以p/q的形式写,其中q是2或5的幂。
- @hmd除了可以表示为decimal但不能表示为double的值(如0.1),还有一些值可以精确表示为double,但不能表示为decimal。考虑分数1 / 2^31。decimal表示被截断,而double表示是精确的。double的.NET字符串表示不准确,但内存中的位表示是准确的。jon skeet有一个类,它可以将任何双精度转换为精确的十进制字符串表示形式,这个表示形式可以很长:csharpindepth.com/articles/general/floatingpoint.aspx
- @Matt I也过于简单化了。真正的要求是,将分数减少到最简单的形式Q后,它是2的幂和5的幂的乘积;也就是说,Q的唯一素数必须与基的唯一素数相同或是其子集。当然,你可以等价地重铸它,因为所有q的素因子,要么是基的素因子,要么是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.
- 如果你在做财务计算,你必须滚动你自己的数据类型或者找到一个符合你确切需求的好库。金融环境中的准确度由(人类)标准机构定义,他们对如何进行计算有非常具体的本地化(时间和地理)规则。在.NET中,简单的数字数据类型中不会捕获正确的舍入。计算能力只是拼图中很小的一部分。
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
- 您省略了最大的差异,即十进制类型使用的基数(十进制存储为基数10,列出的所有其他数字类型都是基数2)。
- 上述图片或源论坛帖子中没有正确描述单值和双值的值范围。因为我们不能轻易地在这里上标文本,所以使用插入符号字符:single应该是10^-45和10^38,double应该是10^-324和10^308。此外,msdn的浮动范围为-3.4x10^38到+3.4x10^38。在msdn中搜索system.single和system.double以防链接更改。单:msdn.microsoft.com/en-us/library/b1e65aza.aspx双:msdn.microsoft.com/en-us/library/678hzk9.aspx
- 十进制是128位…意味着它占用16字节而不是12字节
(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)
- @罗杰利普斯康姆:我认为,在会计应用中,在没有大于32位的整数类型可用的情况下(基本上只有那些情况),double是适当的,并且double被用作53位整数类型(例如,持有一整笔钱,或一整百分之一美分)。如今,这种方法并没有多大用处,但许多语言在获得64位(在某些情况下甚至是32位)之前就已经具备了使用双精度浮点值的能力。整数数学。
- 您的答案意味着精度是这些数据类型之间的唯一区别。考虑到二进制浮点运算通常在硬件FPU中实现,性能是一个显著的差异。对于某些应用程序来说,这可能无关紧要,但对于其他应用程序则至关重要。
- @supercat double在会计应用中从来都不合适。因为double只能近似十进制值(即使在其自身精度的范围内)。这是因为double以以以base-2(二进制)为中心的格式存储值。
- @Brainslugs83:使用浮点类型来保存非整数数量是不正确的,但是对于语言来说,使用浮点类型精确地表示大于整数类型所能表示的整数值是非常常见的。也许最极端的例子是turbo-87,它的整数类型仅限于-32768到+32767,但是它的Real可以用单位精度表示高达1.8e+19的值。我认为用Real代表一整笔硬币比用……
- …以便它尝试使用一组16位值执行多精度数学。对于大多数其他语言来说,差异并不是那么极端,但是很长一段时间以来,对于语言来说,没有任何超过4e9的整数类型,而是有一个单位精度高达9e15的double类型是很常见的。如果需要存储大于最大可用整数类型的整数,使用double比尝试篡改多精度数学更简单、更有效,特别是当处理器具有执行16x16->32或…
- …32x32->64乘法,编程语言通常不会。
我不会重复其他答案和评论中已经回答的大量好(和一些坏)信息,但我会用提示回答您的后续问题:
When would someone use one of these?
对计数值使用小数
测量值使用浮点/双精度
一些例子:
金钱(我们是计算金钱还是衡量金钱?)
距离(我们是计算距离还是测量距离?*)
分数(我们是计算分数还是衡量分数?)
我们总是数数钱,不应该测量它。我们通常测量距离。我们经常数数分数。
*在某些情况下,我称之为名义距离,我们可能真的想要"计算"距离。例如,我们可能正在处理显示到城市距离的国家标志,我们知道这些距离永远不会有超过一个十进制数字(x x x.x km)。
- 我真的很喜欢这个答案,尤其是"我们是数钱还是量钱?"然而,除了钱,我想不出任何"计数"的东西,它不是简单的整数。我见过一些应用程序使用十进制,因为double的有效数字太少。换句话说,十进制可能会被使用,因为c没有四重类型en.wikipedia.org/wiki/fourple-precision_floating-point_for‌&8203;mat
没有人提到过
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; |
- 同decimal.MaxValue+0.1D == decimal.MaxValue一样。也许你的意思是像float.MaxValue*2一样?
- @supercar,但decimal.maxvalue+1==decimal.maxvalue不是真的
- @supercar decimal.maxvalue+0.1m==decimal.maxvalue确定
- System.Decimal在无法区分整个单元之前抛出了一个异常,但是如果一个应用程序要处理诸如美元和美分之类的问题,那就太晚了。
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.
- 他们当然可以!它们也有一些"神奇"的值,如无穷大、负无穷大和NaN(不是数字),这使得它在计算坡度时非常有用地检测垂直线…此外,如果需要决定调用float.typarse、double.typarse和decimal.typarse(例如,为了检测字符串是否是数字),我建议使用double或float,因为它们将正确解析"无穷大"、"-无穷大"和"nan",而decimal不会。
- 只有当试图将文字decimal除以零(cs0020)时,编译才会失败,对于整型文字也是如此。但是,如果运行时十进制值被零除,您将得到一个异常,而不是编译错误。
- @然而,Brainslugs83,您可能不想根据上下文解析"Infinity"或"Nan"。如果开发人员不够严格,那么这似乎是对用户输入的一个很好的利用。
如前所述,整数是整数。他们不能存储点,比如.7、.42和.007。如果需要存储不是整数的数字,则需要不同类型的变量。您可以使用double类型或float类型。您以完全相同的方式设置这些类型的变量:不使用单词int,而是键入double或float。这样地:
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将再次向上或向下取整。道德上,如果你想要精确,小心取整!
- 在您的示例中,使用.42和.007的投票被否决。D
- 你提到的"点某物"通常被称为数字的"小数部分"。"浮点数"并不意味着"一个有点的数字,在结尾有点";而是"浮点数"区分了数字的类型,而不是"定点"数字(也可以存储小数);区别在于精度是固定的还是浮动的。--浮点数以精度为代价提供更大的动态值范围(最小值和最大值),而固定点数以范围为代价提供恒定的精度。
这对我来说是一个有趣的线索,就像今天,我们刚刚遇到了一个讨厌的小错误,关于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完全失去了该值。其中一个例子是
奇怪的是,解决方案是先将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会将它们设置为零。
奇怪的。非常奇怪。
- 出于好奇,cellValue.toString()的原始值是多少?十进制。色氨酸("0.00006317592",out val)似乎有效…
- -别误会我,如果是真的,这很有趣,但这是一个单独的问题,肯定不是这个问题的答案。
- 可能是因为Excel单元格返回了double,toString()的值是"6.31759e-05",所以decimal.parse()不喜欢这个符号。我敢打赌,如果您检查decimal.typarse()的返回值,它肯定是假的。
- @韦斯顿的答案往往补充其他答案,填补他们错过的细微差别。这个答案强调了解析方面的差异。这在很大程度上是这个问题的答案!
- 呃。。。decimal.Parse("0.00006317592")工作——你还有别的事情要做。--可能是科学符号?
- 浮动:±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位有效数字)
- 差别不仅仅是精确度。--decimal实际上是以十进制格式存储的(而不是以2为基数;因此它不会由于两个数字系统之间的转换而丢失或舍入数字);此外,decimal没有特殊值的概念,如NaN、-0、∞或-∞。
对于内存和性能都至关重要的应用程序(如游戏和嵌入式系统),float通常是数字类型的选择,因为它速度更快,只有双倍大小的一半。整数曾经是首选的武器,但在现代处理器中,浮点性能已经超过了整数。小数点就在外面!
- 几乎所有的现代系统,甚至手机,都支持双精度的硬件;如果你的游戏有简单的物理原理,你会发现双精度和浮点型有很大的区别。(例如,计算一个简单的小行星克隆体的速度/摩擦力,加倍可以使加速度比漂浮更流畅地流动。--似乎没关系,但完全没关系。)
- double的大小也是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)
/========================================================================================== |
代码>您可以在这里阅读更多内容:浮点、双精度和小数。
- 这个答案补充了什么,而这些在现有答案中还没有涵盖?顺便说一句,"小数"行中的"或"不正确:您复制的网页中的斜线表示除法,而不是替代方法。
- 我强烈怀疑,精度是主要的区别。主要区别在于基数:十进制浮点与二进制浮点。这一区别正是使Decimal适合金融应用的原因,也是决定Decimal和Double的主要标准。例如,很少有Double精度不足以用于科学应用(而且Decimal由于其范围有限,常常不适合科学应用)。
每种方法的主要区别在于精度。
float是32-bit号,double是64-bit号,decimal是128-bit号。