粗糙的补码计算程序

作者在 2011-10-08 14:56:34 发布以下内容
/*
时间:2011年10月8日14:41:27
功能:输入一个整形数,输出它的补码
目的:掌握补码的计算方法,了解不同类型的整形数的取值范围
*/

# include <stdio.h>
# include <math.h>

int main()
{
    void selectmode (int * pmode);
    void calsize (int mode, int * size, unsigned long int * max, unsigned long int * min);
    void output (int * pArr, int len);    
    void input(int* pmode, int * x);
    
    int n;
    long int x;
    unsigned long int y;
    int i;
    int a[64];
    int mode;
    unsigned long int max,min;
    
    
    selectmode(&mode);        
    calsize(mode,&n,&max,&min);        
    
    
    if (1==mode%2)
    {
        printf("输入要转换的十进制数(%ld~%ld)\n",min,max);
        scanf("%ld",&x);
        if (x<0)
        {
            x += pow(2,n-1);    
            a[0] = 1;
        }
        else
        {
            a[0] = 0;
        }
        for (i=n-1; i>0; --i)
        {
            a[i] = x%2;
            x /= 2;
        }
    }
    else
    {
        printf("输入要转换的十进制数(%lu~%lu)\n",min,max);
        scanf("%lu",&y);
        if (y >= pow(2,n-1))
        {
            y -= pow(2,n-1);
            a[0] = 1;
        }
        else
        {
            a[0] = 0;
        }
    for (i=n-1; i>0; --i)
    {
        a[i] = y%2;
        y /= 2;
    }
    }
    
    output (a,n);
    
    return 0;
}


//输出补码
void output (int * pArr, int len)
{
    int i;    
    printf("计算出的补码是:\n");
    for(i=0; i<len; ++i)
    {
        printf("%d", *(pArr+i));
        if (3 == i%4)
        {
            printf(" ");
        }
    }
    printf("\n");
    return;
}

//选择输入的数据类型
void selectmode (int * pmode)
{
    printf("请选择输入的整形变量类型\n");
    printf("1.基本整形\(int\)\n");
    printf("2.无符号基本整形\(unsigned int\)\n");
    printf("3.长整形\(long int\)\n");
    printf("4.无符号长整形\(unsigned long int\)\n");
    printf("5.短整形\(short int\)\n");
    printf("6.无符号短整形\(unsigned short int\)\n");
//    printf("7.双长整形\(long long int\)\n");        //VC++6.0不支持双长整型
//    printf("8.无符号双长整形\(unsigned long long int\)\n");  //VC++6.0不支持
    
    scanf("%d", pmode);
    return;
}

//计算补码长度,求取值范围
void calsize (int mode, int * size, unsigned long int * max, unsigned long int * min)
{
    switch (mode)
    {
    case 1: *size = 8*sizeof(int);
        break;
    case 2: *size = 8*sizeof(unsigned int);
        break;
    case 3: *size = 8*sizeof(long int);
        break;
    case 4: *size = 8*sizeof(unsigned long int);
        break;
    case 5: *size = 8*sizeof(short int);
        break;
    case 6: *size = 8*sizeof(unsigned short int);
        break;
//    case 7: *size = 8*sizeof(long long int);
//        break;
//    case 8: *size = 8*sizeof(unsigned long long int);
//        break;
    }
    
    if (1 == mode%2)
    {
        *max = pow(2,(*size-1))-1;
        *min = pow(2,(*size-1))*(-1);
    }
    else
    {
        *max = pow(2,(*size))-1;
        *min = 0;
    }
    
    return;
}
/*
在VC++6.0中的输出结果为:
————————————
请选择输入的整形变量类型
1.基本整形(int)
2.无符号基本整形(unsigned int)
3.长整形(long int)
4.无符号长整形(unsigned long int)
5.短整形(short int)
6.无符号短整形(unsigned short int)
1
输入要转换的十进制数(-2147483648~2147483647)
5
计算出的补码是:
0000 0000 0000 0000 0000 0000 0000 0101
Press any key to continue

1
输入要转换的十进制数(-2147483648~2147483647)
-5
计算出的补码是:
1111 1111 1111 1111 1111 1111 1111 1011
Press any key to continue

1
输入要转换的十进制数(-2147483648~2147483647)
-2147483648
计算出的补码是:
1000 0000 0000 0000 0000 0000 0000 0000
Press any key to continue

1
输入要转换的十进制数(-2147483648~2147483647)
2147483647
计算出的补码是:
0111 1111 1111 1111 1111 1111 1111 1111
Press any key to continue

2
输入要转换的十进制数(0~4294967295)
0
计算出的补码是:
0000 0000 0000 0000 0000 0000 0000 0000
Press any key to continue

2
输入要转换的十进制数(0~4294967295)
4294967295
计算出的补码是:
1111 1111 1111 1111 1111 1111 1111 1111
Press any key to continue

5
输入要转换的十进制数(-32768~32767)
-32768
计算出的补码是:
1000 0000 0000 0000
Press any key to continue

5
输入要转换的十进制数(-32768~32767)
-1
计算出的补码是:
1111 1111 1111 1111
Press any key to continue

5
输入要转换的十进制数(-32768~32767)
0
计算出的补码是:
0000 0000 0000 0000
Press any key to continue

5
输入要转换的十进制数(-32768~32767)
32767
计算出的补码是:
0111 1111 1111 1111
Press any key to continue

6
输入要转换的十进制数(0~65535)
0
计算出的补码是:
0000 0000 0000 0000
Press any key to continue

6
输入要转换的十进制数(0~65535)
32767
计算出的补码是:
0111 1111 1111 1111
Press any key to continue

6
输入要转换的十进制数(0~65535)
32768
计算出的补码是:
1000 0000 0000 0000
Press any key to continue

6
输入要转换的十进制数(0~65535)
65535
计算出的补码是:
1111 1111 1111 1111
Press any key to continue
————————————
*/
《C程序设计(第4版)》中介绍的求负数的补码的方法为:现将此数的绝对值写成二进制形式,然后对其后面所有二进制位按位取反,再加1.
int型取值范围为(-2147483648~2147483647),对于最小值-2147483648依此方式计算会出错,原因是-2147483648取绝对值后会溢出
坛友 czsbc 提供了很有效的解决办法,在此感谢。原帖地址:http://bbs.bccn.net/thread-351358-1-1.html 第8楼
默认分类 | 阅读 1361 次
文章评论,共0条
游客请输入验证码
最新评论