C#double类型精度丢失问题
我们先看⼀段代码,可以在控制台程序中执⾏看看结果
{
double d = 500;
double d1 = 233.84;
double d2 = d - d1;
//d2=266.15999999999997
}
{
double d = 0.4;
double d1 = d + d + d;
/
/d1=1.2000000000000002
double d2 = d * 3;
//d2=1.2000000000000002
}
float数值范围{
double d = 1.2;
double d1 = d / 0.4;
//d1=2.9999999999999996
}
看到结果,你可能惊讶或者不惊讶,认为计算机计算出现这种精度问题很正常,但是当你做判断时,发现1.2!=0.4*3或者3!=1.2/0.4,你就会懵逼了
bool b1 = 1.2 == 0.4 * 3;//false
bool b2 = 3 == 1.2 / 0.4;//false
更有甚者,将计算出来的double类型直接保存在数据库,那保存的也是上⾯那⼀堆的⼩数,后来者看到这个也是奔溃的!
更⼤的影响是在做⾦额运算时,我们⼀般都是精确到分,但是有时会计会发现⾃⼰计算出来的数据和我们系统中的对不上,我们的第⼀感觉也是精度问题,往往会做⼀个四舍五⼊,向上取值,向下取值等等操作,那么更⼤的问题来了,⽐如向下取值,你会发现1.2/0.4向下取整等于2!
double b = Math.Floor(1.2 / 0.4);//b=2
⼼中⼀万只奔腾⽽过!
float、double和decimal
float、double和decimal是C#中表⽰浮点数的类型
类型名称bit有效数字数值范围是否基础类型
float单精度浮点数327±1.5×10E−45 ~ ±3.4×10E38是
double双精度浮点数6415/16±5.0×10E−324 ~ ±1.7×10E308是
decimal⾼精度浮点数12828±1.0×10E−28 ~ ±7.9×10E28否
float和double都是基础类型,区别就是表⽰的数值范围和精度不⼀样,⽽decimal是C#作为补充加上来的⼀个类型,不是基础类型,它拥有更⾼的精度,但是表⽰的数值范围却⼩多了,⽽且计算速度相对来说要慢⼀些,但是也⾜够⼀般的业务需求了,⽐如上⾯的例⼦,如果把double都换成decimal就不会出现问题了。
float、double和decimal都有精度丢失问题,只不过他们在丢失时的精度条件不⼀样,⽽且精度丢失了还不报异常。
个⼈建议
1、在项⽬中尽可能的使⽤decimal,虽然decimal也会出现精度丢失问题,但是⼀般业务需求是没问题的。
2、当⽅法返回浮点类型时,或者返回的实体包含有浮点类型,那么在返回时⼀定要考虑要不要处理精度问题。
3、在对外输出或者存储时,如保存到数据库,⼀定要根据⾃⼰的需求做个精度处理。
4、当基础类型在不同类型之间转换时,尽可能的使⽤Convert类中的⽅法,少⽤强制转换。
5、尽量避免使⽤浮点数做⽐较,如果愣是⽐较,可以先做精度处理或者先转换成整型再⽐较。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论