Jump to content
  • Advertisement
Sign in to follow this  
ToohrVyk

Signed to unsigned

This topic is 4663 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
Advertisement
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]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
#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

Share this post


Link to post
Share on other sites
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;
}

Share this post


Link to post
Share on other sites
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;
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!