好多年没更新了,工作后的第一个更新。
言归正传,前几天碰上一个小问题,简单地说就是将核对给机械臂的发的运动指令是否正确,但指令码是16进制补码,看得云里雾里,用自带的计算器发现,并没有将负数的补码转成10进制的指令,因此,就写了一个简单的转换程序,代码如下:
// 计算一个16进制补码表示的整数对应的十进制数
#include <tchar.h>
#include <cmath>
#include <iostream>
#define MAXCHAR 9
#define MAXDIGIT 8
using namespace std;
int HexChar2Digit(char NumInComplement[], int NumDigit[], int charsize);
// 主函数
int _tmain(int argc, _TCHAR* argv[])
{
int bitnum = 0, charsize = 16;
int isNegNum = 0;
int i, numbase;
long long resultInDec = 0;
char NumInComplement[MAXCHAR];
int NumDigit[MAXDIGIT];
cout << "输入计算的位数(8位,16位,32位):" << endl;
cin >> bitnum;
charsize = bitnum / 4;
// 清空缓存区
cin.clear();
cin.ignore(numeric_limits<std::streamsize>::max(), '\n');
cout << "输入16进制表示的补码(输入 'q', 退出):" << endl;
cin.getline(NumInComplement, MAXCHAR);
while (NumInComplement[0] != 'q') {
// 判断是否为负数
isNegNum = ((NumInComplement[0] - '0' >= 8) && (NumInComplement[0] - '0' <= 9))||
((NumInComplement[0] - 'a' >= 0) && (NumInComplement[0] - 'a' <= 5))||
((NumInComplement[0] - 'A' >= 0) && (NumInComplement[0] - 'A' <= 5));
// 将补码字符串转换为十进制数
HexChar2Digit(NumInComplement, NumDigit, charsize);
resultInDec = 0;
for (i = 0; i < charsize; i++) {
resultInDec += NumDigit[charsize-1-i] * pow(16, i);
}
// 如果为负数,补码求补得到十进制数真值
if (isNegNum) {
resultInDec = resultInDec - pow(2, bitnum);
}
cout << "补码0x" << NumInComplement << "对应的十进制数:" << resultInDec << endl;
cout << "输入16进制表示的补码(输入 'q', 退出):" << endl;
cin.getline(NumInComplement, MAXCHAR);
}
return 0;
}
/* 函数名称:HexChar2Digit
* 函数功能:将字符表示的16进制码转换成对应的16进制基数(0,1,2,...,15)
* 函数输入:
* NumInComplement:16进制码对应的字符串
* charsize: 16进制码的长度
*
* 函数输出:
* NumDigit: 对应的16进制基数
*
* 函数返回值:
* 1-转换正确,0-转换错误,字符串中有非法字符
*/
int HexChar2Digit(char NumInComplement[], int NumDigit[], int charsize)
{
int i;
for (i = 0; i < charsize; i++) {
switch (NumInComplement[i])
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
NumDigit[i] = NumInComplement[i] - '0';
break;
case 'a':
case 'A':
NumDigit[i] = 10;
break;
case 'b':
case 'B':
NumDigit[i] = 11;
break;
case 'c':
case 'C':
NumDigit[i] = 12;
break;
case 'd':
case 'D':
NumDigit[i] = 13;
break;
case 'e':
case 'E':
NumDigit[i] = 14;
break;
case 'f':
case 'F':
NumDigit[i] = 15;
break;
default:
// 出现非法字符,失败返回
return 0;
}
}
// 转换成功
return 1;
}
这里简单解释一下补码的概念,计算机中整数均采用补码的方式存储,补码相比于原码和反码,其0的表示方式是唯一的。
(1)对于正整数:其补码与原码相等,直接采用除基数取余方式可以直接得到,将正整数补码还原成十进制正整数直接按权相加即可;
(2)对于负整数:其处理比较麻烦,书上教材也给出了相应的转换公式,但实际上可以直接从字面上理解,比如,16位补码表示的-1为0xFFFF,其0xFFFF与其对应的相反数1,相加刚好为2的16次方,而2的16次方刚好是10000000000000000(1是溢出位,其实得到的是16个0),这就是“补”的直接含义:负数的补码+其相反数的补码=0(2的n次方)。
因此,负数补码对应的十进制数=按权展开的后的十进制数-(2的n次方)
测试结果如下:
以十进制-30431为例,采用自带的计算器校核,结果正确。
更多推荐
C++将16进制补码转换为十进制数
发布评论