The C standard guarantees that int64_t
uses two's-complement representation with no padding bits, so it's implicitly guaranteed that there's a one-to-one mapping. (I believe it's still possible for the most negative value to be a trap representation, but that's unlikely in practice. Unlike ordinary signed integer types, the intN_t
types cannot make the most negative value a trap representation; all 2N possible representations are well-defined and have distinct values.)
On the other hand, there's no guarantee that int64_t
exists.
A conversion from uint64_t
to int64_t
yields an implementation-defined result for values outside the range of int64_t
. The result is almost certain to be the one you'd probably expect, produced by simply reinterpreting the representation, but it's not guaranteed.
So in practice, you can very probably get away with converting between int64_t
and uint64_t
.
But why do you need to? You say it's "because it is not convenient for unsigned integer to compare value". What's inconvenient about it? The relational operators are well defined for both signed and unsigned types.