作者在 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
————————————
*/
时间: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楼