首页 > 解决方案 > 这行代码翻译成什么?为什么要除以 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++;
}

标签: c

解决方案


看来,上面的函数旨在添加两个十六进制字符串。我相信这一点,因为有问题的行编码了十六进制字符和溢出,当添加两位数字被以某种方式处理时发生的溢出,只有当数字被视为 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

最后的输出似乎可疑。这真的是故意的吗?


推荐阅读