新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论.NET,C#,ASP,VB技术
    [返回] 中文XML论坛 - 专业的XML技术讨论区计算机技术与应用『 Dot NET,C#,ASP,VB 』 → 详解C#的数学类,Math,浮点数 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 10258 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: 详解C#的数学类,Math,浮点数 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 Dot NET,C#,ASP,VB 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客楼主
    发贴心情 详解C#的数学类,Math,浮点数

    C#语言支持表B-1所示的11种数值类型,分别为整数,浮点数和小数。


    在一个c#程序中,整数(没有小数点的数)被认为是一个int类型(除非其值大于最大的int值),根据数据值,该数据依次被视为uint,long,ulong,带小数点的数被认为是一个double值。这就是说(1.0).GetType()==typeof(double).

    你可以在数字说明上使用前缀来表明自己的意图。


    其中u代表无符号的意思。因为无符号,所以u代表了数据是正数或0,不可能是负数。

    A:检查整数溢出

    考虑下面的代码:

    short s=32767;s+=1;

    ushort us=0;us-=1;

    在第一种情况下,一个有符号的数加1,经过其最大值,由于整数在内存中存储方式的原因,结果是-32768.

    在第二种情况下,一个无符号的数被减为小于0,结果将是65535.

    在这两道例子中,分别出现了上溢和下溢的情况,如果想避免这种情况的发生,可以使用checked关键字,

    或者使用下面的编译器开关:

    /checked+

    默认编译器开关对应为:/checked-

    如果使用checked关键字:

    short s=32767;

    checked

    {

      s+=1; //将产生一个OverFlowException.

    }

    迄今为止,我一直都在独自介绍运行时的整数向上或向下溢出检查,在默认情况下编译器会将编译时的向上和向下溢出标记为一个错误,而和你的编译器开关无关。

    例如语句short s=32767+1;

    会产生一个编译时错误,因为在编译期间对加法进行求值.

    例如下面的例子:

    const int i1=65536;

    const int i2=65536;

    int i3=i1*i2;

    因为i1,i2都是const值,所以编译器在编译的时候会尝试对i3=i1*i2进行求值,并遇到一个向上溢出。所以会导致编译错误。

    编译器开关不会覆盖这一行为,但是unchecked关键字可以覆盖这种行为。

    int i3=unchecked(i1*i2).可以正常编译.

    B:小数类型  

    decimal 关键字表示 128 位数据类型。同浮点型相比,decimal 类型具有更高的精度和更小的范围,这使它适合于财务和货币计算。decimal 类型的大致范围和精度如下表所示。

    它使用16字节(128位)存储每一个值。128位被划分为96位整数位,一个符号位,以及一个可以在0~28之间变化的比例因子。在数学上,这个比例因子是一个10的负指数幂,表示数值中小数点位置的编号。

    例如,如果一个小数定义等于12.34,那么这个数的存储方式是整数0x4D2(或1234),以及一个比例因子2,

    只要一个小数具有(或小于)28个有效数字以及(或小于)28个小数位置,decimal数据类型就可以准确的存储它。对于浮点数而言,这是不成立的!,如果定义一个float值等于12.34,那么它会被存储为0xC570A4(或12939428)除以0x100000(或1048576),这个值等于12.340000152587890625 约等于12.34。即使您将一个double值定义为等于12.34,它也是被存储为:0x18AE147AE147AE(或6 946 802 425 218 990)除以0x2000000(或562 949 953 421 312),它也只是约等于12.34.

    这就是你在不想让美分神秘的出现和消失的地方执行计算时应该使用decimal的原因,因为浮点数不精确。

    浮点数据类型在科学和工程应用方面很合适,但不是金融应用所期望的。

    Decimal的构造函数(节选)

    Decimal(int iLow,int iMiddle,int iHigh,bool bNegative,byte byScale)

    例如表达式:new Decimal(123456789,0,0,false,5)

    创建了一个decimal类型的小数:1234.56789.,

    5代表小数点从左边开始往右边开始算。移动5位。

    如果最后一个参数为1,则为12345678.9.

    最后一个参数为2,则为1234567.89.

    最后一个参数为3,则为123456.789

    ...

    小数正值的最大值是:new Decimal(-1,-1,-1,false,0) ==Decimal.MaxValue.

    接近0的最小Decimal值是:new Decimal(1,0,0,false,28)==0.0000000000000000000000000001==1*10-28.

    如果在C#程序中将这个数除以2,那么结果将是0.

    在上面我已经指出浮点表示法为什么经常是近似值。当你开始在浮点数上执行算术运算时,近似情况可能更严重。

    例如,几乎每一个使用浮点数的人都很清楚的知道,应该存储为4.55的数经常被存储为4.549999或4.550001.

    小数表示的情况要好很多,例如假设m1被定义为

    decimal m1=12.34

    在内部m1有一个整数部分1234和一个比例因子2,同时假设m2被定义为

    decimal m2=56.789;

    整数部分是56789,比例因子为3,现在将两个数相加:

    decimal m3=m1+m2;

    在内部,m1的整数部分被乘以10(得到12340),比例因子被设置为3.现在整数部分直接相加:12340+56789等于69129,比例因子为3,实际值是69.129.每一个数都是准确的。

    现在将这两个数相乘:

    decimal m4=m1*m2;

    在内部,两个整数部分相乘(1234*56789等于70 077 626),比例因子相加(2+3等于5)。实际的数值结果为:70.077626。这一次,计算也是准确的。

    在相除时....哦,My god,除法是杂乱的,无论你怎样去做都是如此,但是对于大多数情况而言,使用Decimal你可以更好的控制结果


       收藏   分享  
    顶(0)
      




    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2010/6/8 11:02:00
     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 Dot NET,C#,ASP,VB 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客2
    发贴心情 
    两种浮点数据类型--float和double,是为了与ANSI/IEEE Std 754-1985(它是一种用于二进制浮点算术的IEEE标准)相一致而定义的.

    float值由24位有符号尾数和一个8位有符号指数组成。精度大于为小数点后7位。值的范围是从-3.402823*1038到3.402823*1038 大于0的最小float值是1.401298*10-45这三个值分别对应的是float.MinValue,float.MaxValue,float.Epsilon.

    double值由53位有符号尾数和11位有符号指数组成,精度大约为小数点后15位到16位。值的范围从-1.79769313486232*10308到1.79769313486232*10308.大于0的最小double值是:4.94065645841247*10-324分别对应:

    double.MinValue,double.MaxValue,double.Epsilon.

    下面的代码使一个浮点数除以0;

    float f1=1;

    float f2=0;

    float f3=f1/f2;

    看到上面的代码,你是否会立马想到DividedByZeroException。如果这些数是整数的话,的确会抛出异常,但是这些数是浮点数,这里不会产生异常,

    事实上,浮点数运算从来不会产生异常,因为f2并不是真正意义上的0,它只是一个与0非常接近的数(具体可以看我上篇文章)。在这种情况下f3等于一个特殊的值。它是Infinity(正无穷大),

    如果将f1更改为-1,那么f3的符号将是负的,它是-Infinity(负无穷大)。

    你甚至可以对Infinity执行算术运算,例如,表达式1/f3等于0。

    如果将f1更改为0,那么f3将等于NaN(Not a Number,未知数).

    判断一个数是Infinity或者是NaN使用的是Single的静态方法:

    bool IsInfinity(float fValue);                      //判断是否为无穷大

    bool IsPositiveInfinity(float fValue);           //判断是否为正无穷大

    bool IsNegativeInfinty(float fValue);          //判断是否为负无穷大

    bool IsNaN(float fValue);                          //判断是否为NaN

    Single结构还定义了一些常量字段。

    Single.PositiveInfinity.

    Single.NegativeInfinity.

    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2010/6/8 11:07:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 Dot NET,C#,ASP,VB 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/12/27 1:55:14

    本主题贴数2,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    93.262ms