zoukankan      html  css  js  c++  java
  • Decimal与double类型误差

     int a = (int)(19.9 *100);   //19.9默认是double类型
     int b = (int)(19.9M *100 ); //将19.9转换成decimal类型

     Console.WriteLine(a);  //输出:1989

     Console.WriteLine(b);  //输出:1990

     

    不用说.NET,C#,就是用Java来干估计也是这个结果,这个结果具有必然性.
    19.9 作为 Double 类型表示,二进制形式是:
    1 00000000110 011111001100110011001100110011001100110011001100110
    (注意中间的两个空格,如果你不知道啥意思,就去查查double的内存表示形式吧)
    但是19.9 * 100 由于是二进制运算的结果是
    1 00000010011 111000101111111111111111111111111111111111111111111
    由于后面有n个11111所以我猜测可能发生了溢出被计算机舍去了.
    于是这个数字比 1990少那么一点点(可能是 1989.99999999...)
    但是你的取整操作却直接截断了后面的数字,于是成了1989
    至于你说9.9 29.9为什么不那样,那就是可能没有发生溢出了(不要以10进制的思维来猜测二进制)
    别的语言你只能通过保留更高的精度并且四舍五入来实现,而C#为了支持金融运算,独家引入变态的Decimal类型,于是你的问题现在可以通过decimal解决了(decimal的精度非常高,大约有好几十层楼那么高吧...够用了)
    二进制无法精确表示浮点数,小数部分一般都是用近似值来标示的。所以19.9*100的二进制标示会有那么多的11111111。而(int)(19.999999999)结果是直接截断小数点后面的结果,所以1989.999999也就是1989了。但是decimal为什么能正确呢,因为它根本就不存在真正的小数存储进制,所有的数都在小数点的右边。那它又是如何存储小数的呢,答案就是比例因子。当然还有符号位。

  • 相关阅读:
    【转】UCenter的MVC架构
    最新的windows xp sp3序列号(绝对可通过正版验证)
    马丁催眠的花园
    【转】UCenter 的 daddslashes详解
    ckEditor与ckFinder的集成
    【转】UCenter代码研究第一篇(ROOT/admin.php)
    MVC学习第三节:Controller与View
    MVC学习第二节:UrlRouting
    MVC 学习第十节 请求Controller
    MVC学习第九节 HtmlHelper
  • 原文地址:https://www.cnblogs.com/panjun/p/1913809.html
Copyright © 2011-2022 走看看