一直很奇怪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

在声明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 了。

 
1

[转载] c#中decimal ,double,float的区别的更多相关文章

  1. C#中decimal ,double,float的区别

    浮点型 Name CTS Type Description Significant Figures Range (approximate) float System.Single 32-bit sin ...

  2. decimal和float的区别

    场景 今天在开发的时候,在mongodb中有个字段保存的数据结构是decimal,然后需要对这个字段的值进行范围的查询.结果却怎么查询值范围都是空. 解决 如图中看到的,利用Navicat,可以明显的 ...

  3. decimal与 float的区别

      decimal 数据类型最多可存储 38 个数字,所有数字都能够放到小数点的右边.decimal 数据类型存储了一个准确(精确)的数字表达法:不存储值的近似值. 定义 decimal 的列.变量和 ...

  4. [转载]C++中声明与定义的区别

    C++学了这么多年你知道为什么定义类时,类的定义放在.h文件中,而类的实现放在cpp文件中.它们为什么能够关联到一起呢?你知道什么东西可以放在.h文件中,什么不能.什么东西又可以放在cpp文件中.如果 ...

  5. 转载http中302与301的区别

    http://blog.csdn.net/qmhball/article/details/7838989 一.官方说法301,302 都是HTTP状态的编码,都代表着某个URL发生了转移,不同之处在于 ...

  6. decimal, double, float

     更新: 2019-09-08  c# and js 要 ceil floor 2 decimal point 都没有 build in 的 solution 比如 15.667 想 ceil to ...

  7. [转载]jquery中attr和prop的区别

    在高版本的jquery引入prop方法后,什么时候该用prop?什么时候用attr?它们两个之间有什么区别?这些问题就出现了. 关于它们两个的区别,网上的答案很多.这里谈谈我的心得,我的心得很简单: ...

  8. [转载]js中__proto__和prototype的区别和关系

          首先,要明确几个点:1.在JS里,万物皆对象.方法(Function)是对象,方法的原型(Function.prototype)是对象.因此,它们都会具有对象共有的特点.即:对象具有属性_ ...

  9. MySQL中 DECIMAL FLOAT DOUBLE的区别

    第一篇文章: MySQL中Decimal类型和Float Double等区别 MySQL中存在float,double等非标准数据类型,也有decimal这种标准数据类型. 其区别在于,float,d ...

随机推荐

  1. 008-js中的正则表达式

    查看地址:http://www.runoob.com/js/js-regexp.html 一.正则表达式概述 正则表达式(英语:Regular Expression,在代码中常简写为regex.reg ...

  2. golang gui library 库

    andlabs/ui已经重写,稳定性增强,但是组件很少,只提供了几种基础的控件,慎用.gxui死了,别用.linuxdeepin转QT了,所以…… windows系统最好的选择是walk. 首先,写w ...

  3. PHP 判断括号是否闭合

    一开始的思路就是判断每种括号的开闭数量是否相等,其实虽然也能实现但是搞得太复杂了: 后来查了查,只需设一个常量,左括号  +1,右括号   -1,闭合的话为0,没闭合的话不为0, 出现<0即为顺 ...

  4. docker端口映射,批量删除容器

    docker端口映射 http://blog.csdn.net/yjk13703623757/article/details/69212521 批量删除容器 http://blog.csdn.net/ ...

  5. Python Socket通信例子

    一.TCP 通信 服务端 #!/usr/bin/env python # -*- coding: utf-8 -*- # server_tcp.py import socket so = socket ...

  6. 2019.04.09 电商24 订单模快 ORM

    前面三个模块已近结束,现在看是订单模块的.想一下淘宝上的订单,在购物车中选中,提交,跳转到订单界面. 获取传过来的信息,那也要建立一个订单表,当我支付的时候,也要获取一些数据,将这些数据放到这个表中 ...

  7. [LeetCode] 422. Valid Word Square_Easy

    Given a sequence of words, check whether it forms a valid word square. A sequence of words forms a v ...

  8. jmeter BeanShell断言(一)

    原文地址https://blog.csdn.net/lijing742180/article/details/81157947 原文地址https://blog.csdn.net/zailushang ...

  9. Oracle如何重启mmon/mmnl进程(AWR自动采集)

    环境:Oracle 11.2.0.4 RAC 现象:sysaux空间满导致无法正常生成快照,清理空间后,手工生成快照可以成功,但是观察自动生成快照依然是不成功. 之前了解到awr对应的相关后台进程是m ...

  10. Eclipse集成Hibernate操作Sqlserver实例

    Eclipse搭建Hibernate开发环境,使用的数据库是Sqlserver2008 1.需要成功安装Eclipse,如果没有安装可以上网查资料. 2.Eclipse安装成功后,点击Help--&g ...