c - 这行代码翻译成什么?为什么要除以 16?
问题描述
我一直在尝试翻译这段代码,以便用简单的术语来理解,但不能完全理解。
有人可以帮助我更好地理解它,为什么下一行要除以 16?
char r = (c+n1+n2)>=16 ?
((c+n1+n2)-16+'0') :
((c+n1+n2)>9?((c+n1+n2)+55):(c+n1+n2)+'0');
c = (c+n1+n2)/16;
上面的行是一个 while 循环,用于打印多个数字,并且是:
int i=s1-1, j=s2-1, c=0, k=0;// sets up for the calculations -1
// for the s1 and s2 because you do not want null character included here
// k is the number of places we use for addition
printf("COL d d c\n");
while(i>=0 || j>=0){
int n1 = i<0?0:num1[i]-'0';// is converting from the character representation
// of a number to the actual integer value of the same digit if not 0
int n2 = j<0?0:num2[j]-'0';
char r = (c+n1+n2)>=16 ?
((c+n1+n2)-16+'0') :
((c+n1+n2)>9?((c+n1+n2)+55):(c+n1+n2)+'0');
c = (c+n1+n2)/16;
printf("%3d : %d+%d+%d = %c\n", k, n1, n2, c, r);
i--;
j--;
k++;
}
解决方案
看来,上面的函数旨在添加两个十六进制字符串。我相信这一点,因为有问题的行编码了十六进制字符和溢出,当添加两位数字被以某种方式处理时发生的溢出,只有当数字被视为 4 位数字(十六进制数字)时才有意义。例如,因为除以 16。
如果我是对的,十六进制解码包含一个错误,而用于输出结果的十六进制编码似乎几乎是正确的。几乎,因为如果我做对了,原始版本将无法正确计算像“00F”+“00F”这样的字符串加法(参见下面的最后一个输出)。似乎,就连原作者也被他的代码弄得不知所措。
这是一个版本,应该做的是原作者打算做的事情:
void string_add(char num1[], char num2[], int s1, int s2) {
int i=s1-1, j=s2-1, c=0, k=0;// sets up for the calculations -1 for the s1 and s2 because you do not want null character included here
int z=0;
// k is the number of places we use for addition
printf("COL d d c\n");
while(i>=0 || j>=0){
/*
* the following lines represent the expressions
* int n1 = i<0?0:num1[i]-'0';// is converting from the character representation of a number to the actual integer value of the same digit if not 0
* int n2 = j<0?0:num2[j]-'0';
* I added the conversion of hex digits in the range A-F
*/
int n1, n2= 0;
char r;
if(i>=0) {
n1= num1[i];
if(n1>='A') {
n1-= 'A'-10;
} else {
n1-= +'0';
}
}
if(j>=0) {
n2= num2[j];
if(n2>='A') {
n2-= 'A'-10;
} else {
n2-= '0';
}
}
/*
* the following code is, what the line
* char r = (c+n1+n2)>=16?((c+n1+n2)-16+'0'):((c+n1+n2)>9?((c+n1+n2)+55):(c+n1+n2)+'0');
* originally did (I also do a partial calculation of the line
* c = (c+n1+n2)/16;
* to avoid repeating the term
*/
c= c+n1+n2;
r= c&15; // only take the lower 4 bits (ignore overflow bits)
z|= r << (4*k);
// construct the binary representation (shift the 4 bits into position and use bitwise or to add them to z)
if(r>9) {
r+= 'A'-10; // produces chars in range A-F = (ascii('G')-16+c
} else {
r+= '0'; // produces chars in range 0-9 if no overflow occurs
}
/*
* now just do the /16 part of
* c = (c+n1+n2)/16;
*/
c/= 16;
printf("%3d : %d+%d+%d = %c\n", k, n1, n2, c, r);
i--;
j--;
k++;
}
printf("%d\n", z);
}
void main(void) {
char s1[]= "0100";
char s2[]= "0B01";
string_add(s1, s2, 4, 4);
}
测试(第一个输出来自上面的版本,第二个来自原始版本):“0005”+“0005”=
COL d d c
0 : 5+5+0 = A
1 : 0+0+0 = 0
2 : 0+0+0 = 0
3 : 0+0+0 = 0
10
COL d d c
0 : 5+5+0 = A
1 : 0+0+0 = 0
2 : 0+0+0 = 0
3 : 0+0+0 = 0
“9989”+“0987”=
COL d d c
0 : 9+7+1 = 0
1 : 8+8+1 = 1
2 : 9+9+1 = 3
3 : 9+0+0 = A
41744
COL d d c
0 : 9+7+1 = 0
1 : 8+8+1 = 1
2 : 9+9+1 = 3
3 : 9+0+0 = A
“000F”+“000F”=
COL d d c
0 : 15+15+1 = E
1 : 0+0+0 = 1
2 : 0+0+0 = 0
3 : 0+0+0 = 0
30
COL d d c
0 : 22+22+2 = L
1 : 0+0+0 = 2
2 : 0+0+0 = 0
3 : 0+0+0 = 0
最后的输出似乎可疑。这真的是故意的吗?
推荐阅读
- sql - 如何在 PySpark 中运行 .sql 文件
- c# - Azure 存储 blob 下载旧文件版本
- node.js - 使用 typescript 从 markdown 中删除一些 url
- android - adb 备份 - 手机上没有提示
- node.js - 云存储 bitbucket 管道忽略目录
- c++ - 回调函数和空指针 C++
- javascript - Expresss.js static() 不适用于深度超过一个文件夹的子目录(似乎)
- sql - SELECT * 复制表的结果,但选择每个字段不
- linux - 在 max_sectors_kb 处写入 IO
- laravel - Laravel - belongsToMany 的关系和最后一个 belongsToMany 的关系