我目前正在尝试在c中实现一个基本的配对功能。配对函数将接收 2 个无符号整数并输出一个无符号长整型值。为了取消结果配对并检索原始值,必须使用模运算符。但是由于某种原因,模运算符返回的是商,而不是预期的余数。
这是代码:
unsigned long pair(unsigned int x, unsigned int y)
{
return (unsigned long)UINT_MAX * y + x;
}
unsigned int depair_x(unsigned long z)
{
return (unsigned int)(z % UINT_MAX);
}
unsigned int depair_y(unsigned long z)
{
return (unsigned int)(z / UINT_MAX);
}
一个很好的例子是,当我输入值1058242433
和1063370847
时,我得到的结果4567143011379691298
.然而,模运算符的结果大致是1063370847
,这是不正确的(随意检查它(。然而,这个结果是商数。这是怎么回事?
看起来像"off-by-1"。
为了实现"取消配对结果并检索原始值",需要UINT_MAX + 1UL
的刻度,而不是UINT_MAX
。
// return (unsigned long)UINT_MAX * y + x;
return (UINT_MAX + 1UL)* y + x;
//return (unsigned int)(z % UINT_MAX);
return (unsigned int)(z % (UINT_MAX + 1ul));
// Likewise for `/`
如果unsigned long
的范围与unsigned
相同,请考虑使用unsigned long long
而不是unsigned long
。