c# folat, double, decimal分析
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# folat, double, decimal分析,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3015字,纯文字阅读大概需要5分钟。
内容图文
c#中,在小数后面加f表示float,d表示double,m表示decimal,不加默认是double
var a = 1.0f; //float var b = 1.0d; // double var c = 1.0m; // decimal
一直没搞懂为什么需要这么多类型,下面看一下它们能表示的范围以及内部存储,其中float和double属于浮点型,decimal是MS推出的另一种类型
范围和精度
字节数 | 范围 | 小数点 | |
float | 4 | -2128 ~ +2128,也即-3.40E38 ~ +3.40E38 | 223 = 8388608,也就是7 |
double | 8 | -21024 ~ +21024,也即-1.79E308 ~ +1.79E308 | 252 = 4503599627370496也就是16 |
decimal | 16 | -(296 - 1) to 296 - 1 | 28 |
内存存储
- float(32位):
float的指数部分有8bit(2^8),由于是有符号型,所以得到对应的指数范围-128~128。由于float的指数部分对应的指数范围为-128~128,所以取值范围为:
-2128到2128,约等于-3.4E38 — +3.4E38
浮点数的计算有一篇文章写的非常好,写出了浮点型的内部存储详细规则以及为什么会有精度损失
- double(64位):
double的指数部分有11bit(2^11),由于是有符号型,所以得到对应的指数范围-1024~1024。
- decimal(128位):
decimal 内部使用 4 个 32-bit 的 System.Int32 来存储,占用 128 bits = 16 bytes。这 128 bits 分配如下:
96 bits 表示从 0 至 296 - 1 的整数,分布在 3 个 32-bit 的 System.Int32 中。
剩下的 1 个 32-bit 的 System.Int32 包括符号位和比例因子。
第 31 bit 是符号位,0 表示正数,1 表示负数。
第 16 至 23 bit 表示比例因子,必须包含一个 0 至 28 之间的指数,指示 10 的幂,即小数点的位置,也就是小数点右边有几位数字。
其实表示 0 至 28 之间的指数只需 5 bits 就够了,而上面的第 16 至 23 bit 共 8 bits = 1 byte。也就是说剩下的 3 bits (第 21 至 23 bit) 一定是零。
其余 bits (0 - 15 bit 和 24 - 30 bit)不被使用,必须为零。
比较
由上面2个表可以看出来,浮点型和decimal是完全不同的存储方式
对于浮点型,
首先我们要搞清楚下面两个问题: (1) 十进制整数如何转化为二进制数 算法很简单。举个例子,11表示成二进制数: 11/2=5 余 1 5/2=2 余 1 2/2=1 余 0 1/2=0 余 1 0结束 11二进制表示为(从下往上):1011 (2) 十进制小数如何转化为二进制数 算法是乘以2直到没有了小数为止。举个例子,0.9表示成二进制数 0.9*2=1.8 取整数部分 1 0.8(1.8的小数部分)*2=1.6 取整数部分 1 0.6*2=1.2 取整数部分 1 0.2*2=0.4 取整数部分 0 0.4*2=0.8 取整数部分 0 0.8*2=1.6 取整数部分 1 0.6*2=1.2 取整数部分 0 ......... 0.9二进制表示为(从上往下): 1100100100100......
上面的计算过程循环了,也就是说*2永远不可能消灭小数部分,这样算法将无限下去。很显然,小数的二进制表示有时是不可能精确的 。其实道理很简单,十进制系统中能不能准确表示出1/3呢?同样二进制系统也无法准确表示1/10。这也就解释了为什么浮点型减法出现了”减不尽”的精度丢失问题。
而对于decimal,整数部分和小数部分都放在后面12个字节内,不存在精度丢失的问题,小数点后面位数保存在另外4个字节的16-23个bit,只要不超出28,就不会有精度损失。下面的代码由字符串转换成decimal,然后获取到了具体的小数位数。
所以假如在有效位数里面,decimal是不会有精度损失的,财务计算以及位数比较多的科学计算推荐decimal
相互转换
这边只考虑精度损失的问题,精度比较大的转换成小的有可能会造成精度损失。
float -> double, decimal不会造成精度损失
double-> float可能造成精度损失,double->decimal不会造成精度损失
decimal->float, double可能会造成精度损失
decimal和浮点型的相互转换或者加减乘除操作,必须加强制转换
内容总结
以上是互联网集市为您收集整理的c# folat, double, decimal分析全部内容,希望文章能够帮你解决c# folat, double, decimal分析所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。