在无符号整数运算中低于零

时间:2013-06-10 14:18:23

标签: c algorithm unsigned-integer

我想从另一个16位无符号整数列表中推导出16位无符号整数的列表。

例如,给定列表:

10000, 12349, 32333, 3342

我知道另一个列表的第一个整数是0,现在我想推断其余的。映射是从它们中减去10000,我得到了

0, 2349, 22333, 58878

其中58878 =(3342-10000 + 65536)以65565为模数包装。

伪代码类似于:

 void deduce(u_int16_t list1[100], u_int16_t *list2[100], u_int16_t first)
 {
      int diff = first - list1[0];
      for (i = 0; i < 100; i++)
          (*list2)[i] = (list1[i] + diff + 65536) % 65536;
 }

但我们知道无符号整数中没有减号。

那么如何进行映射(或演绎)?

谢谢!

3 个答案:

答案 0 :(得分:2)

如果我理解正确的话,

无符号整数变量可以减去它们包含的数量。

u_int16_t u = 10;
u -= 20; // => u = u - 20;
printf("%x, %u\n", u, u); // => fff6, 65526

区别在于

  • 显示时, u 不显示负值 - 即MSb(最高有效位,即第15位)被解释为(此处)为2 15 ,接着是2 14 等...
  • 当扩展(例如,32位)时,MBb不会从第16位传播到第31位(如果签名则会如此) - 它们是0
  • 右移时,值MSb始终为0(如果已签名,则与之前的MSb相同,例如1为负值)

因此,您的映射将继续使用u_int16_t(如果您在任何地方使用该类型,则不需要%模65536,因为无论如何值都是16位 - 模数是隐式的)。

答案 1 :(得分:0)

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

void deduce(uint16_t list1[], uint16_t list2[], size_t size){
    int32_t i, first = list1[0];

    for(i=0;i<size;++i){
    //  list2[i]= list1[i] - first;
        int32_t wk = list1[i];
        wk -= first;
        if(wk<0)
            wk += 65536;
        list2[i] = wk;
    }
}

int main(void){
    uint16_t list1[100] = {
        10000,
        12349,
        32333,
         3342
    };
    uint16_t list2[100];
    int i;

    deduce(list1, list2, 4);
    for(i = 0; i<4; ++i)
        printf("%5" PRIu16 "\n", list2[i]);

    return 0;
}

答案 2 :(得分:0)

我不太明白你的问题,但如果你想要的是通过两个列表的第一个元素之间的不同来减去第一个列表的每个元素。这段代码应该有用。

void deduce(uint16_t list1[], uint16_t list2[], int size)
{
    uint16_t diff = list1[0] - list2[0];
    int i;
    for (i=0; i<size; i++)
        list2[i] = list1[i] - diff;
}

您不需要将list2作为u_int16_t * list2 []传递,因为您实际上可以使用u_int16_t list2 []编辑数组的内容。如果要在此函数中进行动态内存分配,请仅使用u_int16_t * list2 []。