Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6457311
  • 博文数量: 579
  • 博客积分: 1548
  • 博客等级: 上尉
  • 技术积分: 16635
  • 用 户 组: 普通用户
  • 注册时间: 2012-12-12 15:29
个人简介

http://www.csdn.net/ http://www.arm.com/zh/ https://www.kernel.org/ http://www.linuxpk.com/ http://www.51develop.net/ http://linux.chinaitlab.com/ http://www.embeddedlinux.org.cn http://bbs.pediy.com/

文章分类

全部博文(579)

文章存档

2018年(18)

2015年(91)

2014年(159)

2013年(231)

2012年(80)

分类: C/C++

2013-04-11 09:31:58

操作系统:ubuntu11.10

在编程中,需要对边界值进行判断,程序的异常很多是对边界值的忽略,
      而且这种异常往往很难发现,增加了开发,调试的难度。


加法:

点击(此处)折叠或打开

  1. #include <stdio.h>

  2. //type : char,short,int,long;     but not:float,double
  3. typedef char    type;

  4. //success ,return 0;    error     ,return error_num(-1,...)
  5. int    add(type a, type b,type *result)
  6. {
  7.     if(result == NULL)    return -1;
  8.     *result = a+b;

  9. //    printf("result : %d\n",*result);
  10.     return (-(((a>=0) && (b>=0) && (*result < 0)) || \
  11.             ((a<0) && (b<0) && (*result >= 0))));
  12. }

  13. int main(void)
  14. {
  15.     type    a = 80;
  16.     type    b = 100;
  17.     type    result = 0;
  18.     type    ret= 0;

  19.     ret = add(a,b,&result);        //(80,100,-76)
  20.     printf("result : %d\t + %d\t = %d\t,%d\t\n",a,b,result,ret);

  21.     ret = add(-a,b,&result);    //(-80,100,20)
  22.     printf("result : %d\t + %d\t = %d\t,%d\t\n",-a,b,result,ret);

  23.     ret = add(a,-b,&result);    //(80,-100,-20)
  24.     printf("result : %d\t + %d\t = %d\t,%d\t\n",a,-b,result,ret);

  25.     ret = add(-a,-b,&result);    //(-80,-100,76)
  26.     printf("result : %d\t + %d\t = %d\t,%d\t\n",-a,-b,result,ret);

  27.     return 0;
  28. }
结果:


解说:
当前 type = char
add(a,b,&result);        //(80,100,-76)
a    = 80    = 0101 0000
b    = 100  = 0110 0100  
result         = 1011 0100 
数据是以补码方式存放在内存中,result 内存空间保存的值 1011 0100 是结果的补码,则:
(result)源码 = (~(result - 1)) = (~(1011 0011)) = (1100 1100) = -76



减法:

点击(此处)折叠或打开

  1. #include <stdio.h>

  2. //type : char,short,int,long;     but not:float,double
  3. typedef char    type;

  4. //success ,return 0;    error     ,return error_num(-1,...)
  5. int    add(type a, type b,type *result)
  6. {
  7.     if(result == NULL)    return -1;
  8.     *result = a+b;

  9. //    printf("result : %d\n",*result);
  10.     return (-(((a>0) && (b>0) && (*result < 0)) || \
  11.             ((a<0) && (b<0) && (*result > 0))));
  12. }

  13. int    sub(type a,type b,type *result)
  14. {
  15.     if(b == (type)(~b + 1))
  16.     {//判断b 是不是机器可以表示的最小负整数。此式可以适用于32位及64位机器。
  17.  
  18.         printf("a - b = %d\n",(type)(a - b));
  19.         return (-(a <= 0));
  20.         /*    注意: 此处要有=,因为:如果不加=
  21.                  当0 - (-2147483648)=2147483648在32位机中是无法表示的,
  22.                  得出的结果仍然是-2147483648,这显然是不对的。
  23.         */
  24.     }
  25.     else
  26.     {
  27.         return add(a,-b,result);
  28.     }
  29. }

  30. int main(void)
  31. {
  32.     type    a = -30;
  33.     type    b = -120;
  34.     type    result = 0;
  35.     type    ret= 0;

  36.     ret = sub(a,b,&result);        //(-30,-120,90)
  37.     printf("result : %d\t - %d\t = %d\t,%d\t\n",a,b,result,ret);

  38.     ret = sub(-a,b,&result);    //(30,-120,-106)
  39.     printf("result : %d\t - %d\t = %d\t,%d\t\n",-a,b,result,ret);

  40.     ret = sub(a,-b,&result);    //(-30,120,106)
  41.     printf("result : %d\t - %d\t = %d\t,%d\t\n",a,-b,result,ret);

  42.     ret = sub(-a,-b,&result);    //(-30,-120,-90)
  43.     printf("result : %d\t - %d\t = %d\t,%d\t\n",-a,-b,result,ret);

  44.     return 0;
  45. }
结果:


解说:
当前 type = char

1,sub(-a,b,&result);    //(30,-120,-106)
-a - b = result;
(-a)     = 30    = 0001 1110
(-b)     = 120  = 0111 1000   

(-a) + (-b) = result
result   = 0001 1110
           + 0111 1000
           -------------------
               1001 0110
result的内存空间中保存的值为 1001 0110,由于 result 是 char 类型,
即 result 中保存的值 1001 0110 是计算所得的需求的值的补码(内存中数据都是以 补码 方式保存)。
(result)源码 = (~(result - 1)) = (~(1001 0110 - 1)) = (~(1001 0101)) = (1110 1010) = -106

2,sub(a,-b,&result);    //(-30,120,106)
a - (-b) = result;
(a)源码         = -30     = 1001 1110
(a)补码         = (~((a)源码) + 1) = (~(1001 1110) + 1) = (1110 0001 + 1) = (1110 0010)
则系统分配给 a 的内存中保存的数值为 1110 0010

(-(-b))源码    = (b)源码        = -120    = 1111 1000
(b)补码        = (~((b)源码) + 1) = (~(1111 1000) + 1) = (1000 0111 + 1) = (1000 1000
则系统分配给 b  的内存中保存的数值为 1000 1000

(a) + (-(-b)) = result
result        = 1110 0010
                + 1000 1000
                -------------------
                    0110 1010
result的内存空间中保存的值为 0110 1010,由于result值的最高位为 0,表示这个数为正数,
(value)源码 = (value)补码 = result = 0110 1010 = 106


乘法:

点击(此处)折叠或打开

  1. #include <stdio.h>

  2. //type : char,short,int,long;     but not:float,double
  3. typedef char    type;

  4. //success ,return 0;    error     ,return error_num(-1,...)
  5. int    mut(type a, type b,type *result)
  6. {
  7.     if(result == NULL)    return -1;

  8.     if((a == 0) || (b == 0))    
  9.     {
  10.         *result = 0;
  11.         return 0;
  12.     }

  13.     *result = a*b;

  14.     return (-(((*result)/a) != b));
  15. }


  16. int main(void)
  17. {
  18.     type    a = 23;
  19.     type    b = 121;
  20.     type    result = 0;
  21.     type    ret= 0;

  22.     ret = mut(a,3,&result);    //(23,3,)
  23.     printf("result : %d\t * %d\t = %d\t,%d\t\n",a,3,result,ret);

  24.     ret = mut(0,b,&result);    //(0,121,)
  25.     printf("result : %d\t * %d\t = %d\t,%d\t\n",0,b,result,ret);

  26.     ret = mut(a,0,&result);    //(23,0,)
  27.     printf("result : %d\t * %d\t = %d\t,%d\t\n",a,0,result,ret);

  28.     ret = mut(0,0,&result);    //(0,0,)
  29.     printf("result : %d\t * %d\t = %d\t,%d\t\n",0,0,result,ret);

  30.     ret = mut(a,b,&result);    //(23,121,)
  31.     printf("result : %d\t * %d\t = %d\t,%d\t\n",a,b,result,ret);

  32.     return 0;
  33. }
结果:


解说:
当前 type = char

1,mut(a,b,&result);    //(23,121,-33)
a * b     = result;
a           = 23    =  0001 0111
b           = 121  =  0111 1001

b            = 0100 0000 + 0010 0000 + 0001 0000 + 0000 1000 + 0000 0001 = 2^6 + 2^5 + 2^4 + 2^3 + 2^0;
result      = 0001 0111 <<6    --> 0000 0101 1100 0000  --> 1100 0000
                 0001 0111 <<5    --> 0000 0010 1110 0000  --> 1110 0000
                 0001 0111 <<4    --> 0000 0001 0111 0000  --> 0111 0000
                 0001 0111 <<3    --> 0000 0000 1011 1000  --> 1011 1000
              + 0001 0111 <<0    -->                 0001 0111  --> 0001 0111
              ------------------------------------------------------------------------------------------
                                                                                         1101 1111
result的内存空间中保存的值为 1101 1111,由于 result 是 char 类型,由于result值的最高位为 1,表示这个数为负数,
(value)补码 = (~((value)源码) + 1) = result = 1101 1111
(value)源码 = (~((value)补码 -1))   = (~(1101 1111 -1) = (~(1101 1110 = 1010 0001 = -33


无符号:

点击(此处)折叠或打开

  1. #include <stdio.h>

  2. //type : char,short,int,long;     but not:float,double
  3. typedef unsigned char    type;

  4. //success ,return 0;    error     ,return error_num(-1,...)
  5. int    add(type a, type b,type *result)
  6. {
  7.     if(result == NULL)    return -1;
  8.     *result = a+b;

  9. //    printf("result : %d\n",*result);
  10.     return (-((*result < a) || (*result < b)));
  11. }



阅读(11410) | 评论(1) | 转发(3) |
给主人留下些什么吧!~~

CU博客助理2013-06-09 15:38:36

嘉宾点评:是一个比较有想法的文章,通过封装的函数,实现原有功能并可以确定是否发生了溢出。有几个地方值得改进:1.
函数参数使用type类型,可读性不高;2.
无法兼容无符号整数。其实把方法稍稍改进一下就可以兼容无符号整数。比如当a+b时,如果b>=0,那么*result <
a,就可以判定为溢出。b < 0,那么*result > a,也是溢出。
(感谢您参与“原创博文评选”获奖结果即将公布)