Skip to main content
gamedev.net
🔒 Locked

Signed to unsigned

Started by ToohrVyk Dec 17, 2005 at 1:46 PM 11 replies 1k views
Original Post
ToohrVyk
ToohrVyk
In order to be able to use an API function, I need to convert a signed integer into an unsigned integer, under some constraints. Only these constraints need to be verified, the conversion is not require to conserve the actual values, only the order between them. The function is of type : unsigned long F( signed long ) and verifies that: ∀i, ∀j assert( (i > j) == (F(j) > F(i)) ); I can safely assume that long is 32 bits on the platform I am targeting. Please ask any additional necessary questions.
SiCrane
SiCrane
Just double checking, is that F(j) > F(i) or F(i) > F(j)?
ToohrVyk
ToohrVyk
The post is correct, I do want to reverse the comparison.
darookie
darookie
The only relevant question is, do you mean (signed)i > (signed)j or abs(i) > abs(j)?
SiCrane
SiCrane
Also, can you assume 2's complement representation of negative signed integers?
darookie
darookie
Assuming you want a signed compare:
unsigned long F( signed long x ) {      return (x & 0x80000000) ? (static_cast<unsigned long>(x) & ~0x80000000) << 16 : static_cast<unsigned long>(x) >> 16;}

The above will result in negative values falling into the range of [0,2^16-1] (preserving their order) and [2^16, 2^32-1] for positive values.
I could be mistaken, though - already had a beer or two [smile].
The idea, however, should work - mask out the sign bit and make two ranges for positive and negative values (possibly evenly distributes if the input is evenly distributed across the whole signed range).

[edit]
Looks as if I already had too much beer - the above code cannot work, since the returned values cannot meet the constraint. I am sorry [smile]
[/edit]
ToohrVyk
ToohrVyk
darookie: What I want is described clearly in the original post; I want that assertion to be true for any signed integers i and j. And thank you for your suggestion, I will try that shortly.

SiCrane: yes, I can assume that as well.
Enigma
Enigma
#include <boost/cstdint.hpp>using boost::int64_t;unsigned long F(signed long i){	return (int64_t(1) << sizeof(long)) - (i + (int64_t(1) << (sizeof(long) - 1)));}

? (assuming your compiler provides boost::int64_t).

Enigma
doynax
doynax
Maybe I'm missing something but couldn't you just add the signed bias and complement the result?
unsigned long F(signed long value) { value += 0x80000000; return ~value;}
Which should be equivalent to:
unsigned long F(signed long value) { return value ^ LONG_MAX;}
Nemesis2k2
Nemesis2k2
doynax is corrext. The following preserves the order when mapping a signed integer to an unsigned integer:
unsigned long F(signed long num){	return (unsigned long)num ^ 0x80000000;}


To reverse the order, reverse the XOR.
unsigned long F(signed long num){	return (unsigned long)num ^ 0x7FFFFFFF;}
iMalc
iMalc
Quote:
Original post by ToohrVyk
The post is correct, I do want to reverse the comparison.
It looks very much to me like your OP is reversing the comparison. If 5 > 3 you want F(3) > F(5).

I would simply add the offset required to make the most negative value equal to zero (which would be 0x80000000), then cast it to an unsigned.
In fact, that's exactly what I did in my signed bigint class. For a signed comparison it does just that, then calls the unsigned comparison functions.

I'm impressed that Nemesis2k2 also describes the reversal, which I hdan't thought of, and as others have mentioned, the add can be replaced with an xor.
graveyard filla
graveyard filla
TBH, i didn't fully understand your question.

however, you might want to look into boost. theres a something called something along the lines of "numeric_cast"... this has saved my ass plenty of times (in networking code where i was always casting from signed / unsigned). it throws an exception if there is any loss of data.
FTA, my 2D futuristic action MMORPG
ToohrVyk
ToohrVyk
Thank you, everyone. I settled for the XOR-based solution.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.