decimal与float和double的区别
一直很奇怪C#的预定义数据类型中为什么加了一个decimal,有float和double不就够了吗?今天来挖一挖。
浮点型
|
Name |
CTS Type |
De script ion |
Significant Figures |
Range (approximate) |
|---|---|---|---|---|
|
float |
System.Single |
32-bit single-precision floating point |
7 |
±1.5 × 10?45 to ±3.4 × 1038 |
|
double |
System.Double |
64-bit double-precision floating point |
15/16 |
±5.0 × 10 ?324 to ±1.7 × 10308 |
如果我们在代码中写一个12.3,编译器会自动认为这个数是个double型。所以如果我们想指定12.3为float类型,那么你必须在数字后面加上F/f:
float f = 12.3F;
decimal类型
作为补充,decimal类型用来表示高精度的浮点数
|
Name |
CTS Type |
De script ion |
Significant Figures |
Range (approximate) |
|---|---|---|---|---|
|
decimal |
System.Decimal |
128-bit high precision decimal notation |
28 |
±1.0 × 10?28 to ±7.9 × 1028 |
从上表可以看出,decimal的有效位数很大,达到了28位,但是表示的数据范围却比float和double类型小。decimal类型并不是C#中的基础类型,所以使用的时候会对计算时的性能有影响。
我们可以像如下的方式定义一个decimal类型的浮点数:
decimal d = 12.30M;
对decimal、float、double错误的认识
在精确计算中使用浮点数是非常危险的,尽管C#在浮点数运算时采取了很多措施使得浮点数运算的结果看起来是非常正常的。但实际上如果不清楚浮点数的特性而贸然使用的话,将造成非常严重的隐患。
考虑下面的语句:
double dd = 10000000000000000000000d;
dd += 1;
Console.WriteLine ( "{0:G50}", dd );
输出是什么?谁知道?
输出是:1000000000000000000000000
这就是浮点数精度损失的问题,最重要的是,在精度损失的时候,不会报告任何的错误,也不会有任何的异常产生。
浮点数的精度损失可能在很多地方出现,例如d * g / g 不一定等于d,d / g * g也不一定等于d。
还有两个非常危险的错误认识!!
1、decimal不是浮点型、decimal不存在精度损失。
下面有段程序大家可以去看看结果是什么。记住!所有的浮点型变量都存在精度损失的问题,而decimal是一个不折不扣的浮点型,不论它精度有多高,精度损失依然存在!
decimal dd = 10000000000000000000000000000m;
dd += 0.1m;
Console.WriteLine ( "{0:G50}", dd );
2、decimal所能储存的数比double大,从double到decimal的类型转换不会出现任何问题。
微软在decimal的帮助上真的要好好反省了。实际上只有从整形到decimal的转换才是扩大转换,decimal的精度比double大,但所能储存的最大数却比double要小。
“decimal 类型是适合财务和货币计算的 128 位数据类型。”
当然,decimal在大多数情况下是安全的,但浮点数在理论上是不安全的。
至于精度误差造成的显示问题,则是很容易修补的。浮点数会带来的问题以及整型能避免的问题就是一个:
譬如说从A帐户转账到B帐户,经计算得出结果是3.788888888888888元,那么我们从A帐户扣除这么多钱,B帐户增加这么多钱,但事实上A帐户不一定会扣除准确的数值,例如A帐户的金额在100000000000,那么这个时候100000000000 - 3.788888888888888运算结果很有可能是99999999996.211111111111112。而这个时候B帐户的金额为0则很有可能加上准确的数值,如3.788888888888888,这样一来,0.011111111111112元钱就会不见了,日积月累的,差额就会越来越大。
double是64位的,比single-32位精度高
decimal128位高精度浮点数,常用于金融运算,不会出现浮点数计算的误差
,decimal 类型具有更高的精度和更小的范围,这使它适合于财务和货币计算。
早上刚到办公室,就被中试室打来电话叫去,原来软件在测试过程中发现了个小问题:软件读出来的数据比设备LCD上显示数据小了 0.01 。
怎么会这样呢,数据类型我已经用了 double 型了整个数据长度也就6位,double型的数据有效数据位为7位,也够了阿,不明白。于是回来下断点跟踪。
前面double型在算的时候,是没问题的,数据是66.24,可是当我把66.24 乘上100后的处理结果就不对了:66.24*100.0d = 6623.9999…91,问题就出在这里了。查了msdn,Double型的数据:Double 值类型表示一个值介于 -1.79769313486232e308 和 +1.79769313486232e308 之间的双精度 64 位数字,浮点数只能近似于十进制数字,浮点数的精度决定了浮点数近似于十进制数字的精确程度。默认情况下,Double 值的精度是 15 个十进制位,但内部维护的最大精度是 17 位。所以就出现了乘上一百后,精度就不够了。又由于我们在处理数据时,是不允许四舍五入的,所以,经过单位转换后,软件中最终显示的数据为 66.23 ,比LCD上显示的66.24 小了 0.01。
因此,这之后就想到了应该用更高精度的 decimal 型。
|
类型 |
大致范围 |
精度 |
.NET Framework 类型 |
|
decimal |
±1.0 × 10e?28 至 ±7.9 × 10e28 |
28 到 29 位有效位 |
System.Decimal |
s在声明decimal类型数据时,可以 a: decimal myData = 100,此时编译器隐式转换整型数100为 100.0m;当然也可以b: decimal myData = 100.0m,但是 如果是 decimal myData = 100.0d或者decimal myData = 100.0f,就不行了,因为100.0d或者100.0f,编译器认为是浮点数,而浮点数和decimal 类型之间不存在隐式转换;因此,必须使用强制转换在这两种类型之间进行转换。This is the important,否则编译器便报错。所以一般的财务软件在处理时,都会用decimal 类型。
好了,改用decimal 型之后,就OK 了,结果就完完整整地显示为 66.24 了。
decimal与float和double的区别的更多相关文章
- decimal,float和double的区别
http://www.cnblogs.com/yellowapplemylove/archive/2011/08/23/2150316.html 一直很奇怪C#的预定义数据类型中为什么加了一个deci ...
- Sql的decimal、float、double类型的区别
三者的区别介绍 float:浮点型,含字节数为4,32bit,数值范围为-3.4E38~3.4E38(7个有效位) double:双精度实型,含字节数为8,64bit数值范围-1.7E308~1.7E ...
- decimal, float 和double
阿里的 Java 手册里写着: 6. [强制] 小数类型为 decimal,禁止使用 float 和 double. 说明:float 和 double 在存储的时候,存在精度损失的问题,很可能在值的 ...
- Decimal、 Float、 Double 使用
一.Java 1.float型定义的数据末尾必须 有"f "或"F",为了和double区别.例float x=123.456f, y=2e20f; publ ...
- java中float和double的区别
float表示单精度浮点数在机内占4个字节,用32位二进制描述. double表示双精度浮点数在机内占8个字节,用64位二进制描述.浮点数在机内用指数型式表示,分解为:数符,尾数,指数符,指数四部分. ...
- float和double的区别
1.float是单精度类型,精度有效数字为6位,超出则会四舍五入,取值范围为10的-38次方到10的38次方,float占用存储空间为4个字节. 2.double是双精度类型,精度有效数字为15位,超 ...
- 基本数据类型float和double的区别
float : 单精度浮点数 double : 双精度浮点数 两者的主要区别如下: 01.在内存中占有的字节数不同 单精度浮点数在机内存占4个字节 双精度浮点数在机内存占8个字节 02.有效数字位数不 ...
- JAVA中float与double的区别
float是单精度类型,精度是8位有效数字,取值范围是10的-38次方到10的38次方,float占用4个字节的存储空间 double是双精度类型,精度是17位有效数字,取值范围是10的-308次方到 ...
- float 与 double 类型区别
https://www.runoob.com/w3cnote/float-and-double-different.html float 单精度浮点数在机内占 4 个字节,用 32 位二进制描述. d ...
随机推荐
- h5 中修改input中 placeholder的颜色
input::-webkit-input-placeholder{ color:blue; } input::-moz-placeholder{ /* Mozilla Firefox 19+ */ c ...
- python格式化输出保留2位小数
我是小白就不用多说了,学习python做了个练习题,结果运行了一遍,发现输入金额后得到的有很多位小数, 虽然不知道为什么,但是看得很不舒服, 就想到应该把让小数点后只保留2位数 找到了方法:将{0}改 ...
- Linux物理磁盘扩容流程
1. 插入硬盘前,查看现有硬盘情况 (1)命令:fdisk -l 说明:fdisk -l 查看设备的所有分区 (2)命令:df -h 说明:df 列出文件系统的整体磁盘使用量 2. 断电插入硬盘后,重 ...
- 洛谷P1063能量项链(区间dp)
题目描述: 给定一串序列x[],其中的每一个Xi看作看作一颗珠子,每个珠子包含两个参数,head和tail,前一颗的tail值是后一个的head值,珠子呈现环形(是一条项链),所以最后一颗的tail是 ...
- C#常见基础算法
namespace 面试常见算法 { class Program { static void Main(string[] args) { ); Console.WriteLine(n1); Test2 ...
- linux下安装setuptools
wget https://pypi.python.org/packages/07/a0/11d3d76df54b9701c0f7bf23ea9b00c61c5e14eb7962bb29aed866a5 ...
- atcoder Keyence Programming Contest 2020 题解
比赛地址 A 题意:给一个\(n*m\)的初始为白色的矩阵,一次操作可以将一行或一列染成 黑色,问至少染出\(k\)个黑点的最少操作次数. \(n\),\(m\)<=100,\(k\)<= ...
- springboot web - 启动(2) run()
接上一篇 在创建 SpringApplication 之后, 调用了 run() 方法. public ConfigurableApplicationContext run(String... arg ...
- sublime text3 控制台 Package Control 的安装与使用方法
下载安装 sublime text3 直接网上搜sublime text3 下载即可,安装很简单 下一步就行,这里主要说明sublime text3 控制台 Package Control 的安装与使 ...
- Spark学习之路 (十八)SparkSQL简单使用[转]
SparkSQL的进化之路 1.0以前: Shark 1.1.x开始: SparkSQL(只是测试性的) SQL 1.3.x: SparkSQL(正式版本)+Dataframe 1.5.x: Spar ...