Reputation: 1
I am currenly attempting to implement a basic pairing function in c. The pairing function will take in 2 unsigned integers and output a single unsigned long value. In order to unpair the result and retrieve the original values, the modulus operator must be used. But for some reason the modulues operator is returning the quotient and not the remainder like it is supposed to.
Here is the code:
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);
}
A good example is that when I input the values 1058242433
and 1063370847
I get the result 4567143011379691298
. However the result of the modulus operator is roughly 1063370847
, which is incorrect (feel free to check it). However that result is the quotient. What is happening here?
Upvotes: 0
Views: 226
Reputation: 153303
Looks like "off-by-1".
In order to achieve "to unpair the result and retrieve the original values" a scale of UINT_MAX + 1UL
is needed, not 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 `/`
If unsigned long
has same range as unsigned
, look to using unsigned long long
instead of unsigned long
.
Upvotes: 2