Velocity Reviews > C++ > Convert 32 bit unsigned int to 16 bit signed int.

# Convert 32 bit unsigned int to 16 bit signed int.

Fore
Guest
Posts: n/a

 09-11-2008
Hello
I am looking for some effecient way to convert a 32 bit unsigned
integer to a 16 bit signed integer. All I want is the lower 16 bits
of the 32 bit unsigned integer , with bit 15 (0..15) to used as the
sign bit for the 16 bit signed integer. Any ideas/help greatly
appreciated.

Thanks.

red floyd
Guest
Posts: n/a

 09-11-2008
On Sep 11, 12:56*pm, Fore <(E-Mail Removed)> wrote:
> Hello
> I am looking for some effecient way to convert a 32 bit unsigned
> integer to a 16 bit signed integer. *All I want is the lower 16 bits
> of the 32 bit unsigned integer , with bit 15 (0..15) to used as the
> sign bit for the 16 bit signed integer. *Any ideas/help greatly
> appreciated.

1. Remove the word "efficient" from your lexicon. Study Knuth's/
Hoare's law.
2. Have you not studied the bitwise operators?

Fore
Guest
Posts: n/a

 09-11-2008
On 11 Sep, 21:31, red floyd <(E-Mail Removed)> wrote:
> On Sep 11, 12:56*pm, Fore <(E-Mail Removed)> wrote:
>
> > Hello
> > I am looking for some effecient way to convert a 32 bit unsigned
> > integer to a 16 bit signed integer. *All I want is the lower 16 bits
> > of the 32 bit unsigned integer , with bit 15 (0..15) to used as the
> > sign bit for the 16 bit signed integer. *Any ideas/help greatly
> > appreciated.

>
> 1. Remove the word "efficient" from your lexicon. *Study Knuth's/
> Hoare's law.
> 2. Have you not studied the bitwise operators?

Answer to 1. I accept removal of efficient and no to ...laws.
Answer to 2. is yes, but I also want to be able to achieve this
without a host of complier warnings about the possible loss of data.

Kai-Uwe Bux
Guest
Posts: n/a

 09-12-2008
Jack Klein wrote:

> On Thu, 11 Sep 2008 12:56:54 -0700 (PDT), Fore
> <(E-Mail Removed)> wrote in comp.lang.c++:
>
>> Hello
>> I am looking for some effecient way to convert a 32 bit unsigned
>> integer to a 16 bit signed integer. All I want is the lower 16 bits
>> of the 32 bit unsigned integer , with bit 15 (0..15) to used as the
>> sign bit for the 16 bit signed integer. Any ideas/help greatly
>> appreciated.

>
> Aside from the obvious nonsense of "efficient", as others have already
> mentioned, you haven't provided an adequate enough definition of the
> problem to allow anyone to suggest ANY implementation.
>
> You haven't told us how you plan to translate an larger unsigned value
> to a smaller unsigned value. How do you decide which values are
> negative?

From what you quoted, he said to use lower order bits (0..15) only and to
use bit 15 for the sign. To me that suggests something like this:

int low_16 ( unsigned long n ) {
n %= ( 1l << 16 );
if ( n >= ( 1l << 15 ) ) {
int i = n % ( 1l << 15 );
return ( - i );
} else {
return ( n );
}
}

I do agree, though, that the specs do leave room for debate.

Best

Kai-Uwe Bux

Triple-DES
Guest
Posts: n/a

 09-12-2008
On 12 Sep, 05:00, Kai-Uwe Bux <(E-Mail Removed)> wrote:
> Jack Klein wrote:
> > On Thu, 11 Sep 2008 12:56:54 -0700 (PDT), Fore
> > <(E-Mail Removed)> wrote in comp.lang.c++:

>
> >> Hello
> >> I am looking for some effecient way to convert a 32 bit unsigned
> >> integer to a 16 bit signed integer. *All I want is the lower 16 bits
> >> of the 32 bit unsigned integer , with bit 15 (0..15) to used as the
> >> sign bit for the 16 bit signed integer. *Any ideas/help greatly
> >> appreciated.

>
> > Aside from the obvious nonsense of "efficient", as others have already
> > mentioned, you haven't provided an adequate enough definition of the
> > problem to allow anyone to suggest ANY implementation.

>
> > You haven't told us how you plan to translate an larger unsigned value
> > to a smaller unsigned value. *How do you decide which values are
> > negative?

>
> From what you quoted, he said to use lower order bits (0..15) only and to
> use bit 15 for the sign. To me that suggests something like this:
>
> int low_16 ( unsigned long n ) {
> * n %= ( 1l << 16 );
> * if ( n >= ( 1l << 15 ) ) {
> * * int i = n % ( 1l << 15 );
> * * return ( - i );
> * } else {
> * * return ( n );
> * }
>
> }

I interpreted the OP's specification as if he wanted to extract the
value of the lower 16 bits interpreted as a 2's complement bit
pattern.

short low_16_2sc(unsigned n)
{
return (n & 0x7fffu) - (n & 0x8000u);
}

>
> I do agree, though, that the specs do leave room for debate.
>

Certainly

Fore
Guest
Posts: n/a

 09-12-2008
On Sep 12, 6:20*am, Triple-DES <(E-Mail Removed)> wrote:
> On 12 Sep, 05:00, Kai-Uwe Bux <(E-Mail Removed)> wrote:
>
>
>
>
>
> > Jack Klein wrote:
> > > On Thu, 11 Sep 2008 12:56:54 -0700 (PDT), Fore
> > > <(E-Mail Removed)> wrote in comp.lang.c++:

>
> > >> Hello
> > >> I am looking for some effecient way to convert a 32 bit unsigned
> > >> integer to a 16 bit signed integer. *All I want is the lower 16 bits
> > >> of the 32 bit unsigned integer , with bit 15 (0..15) to used as the
> > >> sign bit for the 16 bit signed integer. *Any ideas/help greatly
> > >> appreciated.

>
> > > Aside from the obvious nonsense of "efficient", as others have already
> > > mentioned, you haven't provided an adequate enough definition of the
> > > problem to allow anyone to suggest ANY implementation.

>
> > > You haven't told us how you plan to translate an larger unsigned value
> > > to a smaller unsigned value. *How do you decide which values are
> > > negative?

>
> > From what you quoted, he said to use lower order bits (0..15) only and to
> > use bit 15 for the sign. To me that suggests something like this:

>
> > int low_16 ( unsigned long n ) {
> > * n %= ( 1l << 16 );
> > * if ( n >= ( 1l << 15 ) ) {
> > * * int i = n % ( 1l << 15 );
> > * * return ( - i );
> > * } else {
> > * * return ( n );
> > * }

>
> > }

>
> I interpreted the OP's specification as if he wanted to extract the
> value of *the lower 16 bits interpreted as a 2's complement bit
> pattern.
>
> short low_16_2sc(unsigned n)
> {
> * return (n & 0x7fffu) - (n & 0x8000u);
>
> }
>
> > I do agree, though, that the specs do leave room for debate.

>
> Certainly - Hide quoted text -
>
> - Show quoted text -

Thanks for the constructive criticism on the specification and
suggestions given.
I will make sure any further topics are less ambiguous.

Juha Nieminen
Guest
Posts: n/a

 09-12-2008
Fore wrote:
> Hello
> I am looking for some effecient way to convert a 32 bit unsigned
> integer to a 16 bit signed integer. All I want is the lower 16 bits
> of the 32 bit unsigned integer , with bit 15 (0..15) to used as the
> sign bit for the 16 bit signed integer. Any ideas/help greatly
> appreciated.

Maybe it's just me, but I fail to see how a simple

short n = short(value);

wouldn't do what you want (well, assuming 'short' is 16 bits in your
system, which it usually is). I'm probably missing something.

James Kanze
Guest
Posts: n/a

 09-12-2008
On Sep 12, 10:16 am, Juha Nieminen <(E-Mail Removed)> wrote:
> Fore wrote:

> > I am looking for some effecient way to convert a 32 bit
> > unsigned integer to a 16 bit signed integer. All I want is
> > the lower 16 bits of the 32 bit unsigned integer , with bit
> > 15 (0..15) to used as the sign bit for the 16 bit signed
> > integer. Any ideas/help greatly appreciated.

> Maybe it's just me, but I fail to see how a simple

> short n = short(value);

> wouldn't do what you want (well, assuming 'short' is 16 bits
> in your system, which it usually is). I'm probably missing
> something.

According to the standard, "If the destination type is signed,
the value is unchanged if it can be represented in the
destination type (and bit-field width); otherwise, the value is
implementation-defined." The C standard is slightly more
restrictive: "When a value with integer type is converted to
another integer type other than _Bool, if the value can be
represented by the new type, it is unchanged. [...]Otherwise,
the new type is signed and the value cannot be represented in
it; either the result is implementation-defined or an
implementation-defined signal is raised."

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

James Tursa
Guest
Posts: n/a

 09-14-2008
On Thu, 11 Sep 2008 12:56:54 -0700 (PDT), Fore
<(E-Mail Removed)> wrote:

>Hello
>I am looking for some effecient way to convert a 32 bit unsigned
>integer to a 16 bit signed integer. All I want is the lower 16 bits
>of the 32 bit unsigned integer , with bit 15 (0..15) to used as the
>sign bit for the 16 bit signed integer. Any ideas/help greatly
>appreciated.
>
>Thanks.

Another method to consider:

short u32_to_i16( unsigned long ul ) {
const unsigned long ul1= 1UL;
if( *((short *)&ul1) )
return *((short *)&ul);
else
return *((short *)&ul + 1);
}

I don't have two different Endian machines to test on, but I think
this should be portable and work on either one. It could be made a bit
faster as follows (define LITTLEENDIAN or not as appropriate for the
particular machine/implementation in use):

#define LITTLEENDIAN

:

#ifdef LITTLEENDIAN

short u32_to_i16( unsigned long ul ) {
return *((short *)&ul);
}

#else

short u32_to_i16( unsigned long ul ) {
return *((short *)&ul + 1);
}

#endif

James Tursa

James Tursa
Guest
Posts: n/a

 09-14-2008
On Sun, 14 Sep 2008 07:34:35 -0500, http://www.velocityreviews.com/forums/(E-Mail Removed) (blargg)
wrote:

>In article <(E-Mail Removed)>, James Tursa
><(E-Mail Removed)> wrote:
>
>> On Thu, 11 Sep 2008 12:56:54 -0700 (PDT), Fore
>> <(E-Mail Removed)> wrote:
>>
>> >Hello
>> >I am looking for some effecient way to convert a 32 bit unsigned
>> >integer to a 16 bit signed integer. All I want is the lower 16 bits
>> >of the 32 bit unsigned integer , with bit 15 (0..15) to used as the
>> >sign bit for the 16 bit signed integer. Any ideas/help greatly
>> >appreciated.
>> >
>> >Thanks.

>>
>> Another method to consider:
>>
>> short u32_to_i16( unsigned long ul ) {
>> const unsigned long ul1= 1UL;
>> if( *((short *)&ul1) )
>> return *((short *)&ul);
>> else
>> return *((short *)&ul + 1);
>> }
>>
>> I don't have two different Endian machines to test on, but I think
>> this should be portable and work on either one. It could be made a bit
>> faster as follows (define LITTLEENDIAN or not as appropriate for the
>> particular machine/implementation in use):
>>
>> #define LITTLEENDIAN
>>
>> :
>>
>> #ifdef LITTLEENDIAN
>>
>> short u32_to_i16( unsigned long ul ) {
>> return *((short *)&ul);
>> }
>>
>> #else
>>
>> short u32_to_i16( unsigned long ul ) {
>> return *((short *)&ul + 1);
>> }
>>
>> #endif

>
>I hate to be harsh, but my god, what you just wrote could have simply been
>written as
>
>short u32_to_i16( unsigned long ul ) { return (short) ul; }
>
>As with your code, this relies on the machine being two's complement,
>having a 16-bit short, and simply taking the low 16 bits without any
>overflow checking.

Well, I disagree (but I could be wrong). Your posted method, I
believe, *does* do a value copy and invokes undefined behavior if the
ul value overflows a short. i.e., this statement

(short) ul

of converting an unsigned integer into a signed integer is only
defined in the standard if the valut to be converted fits in the
signed integer range. It is undefined and the result is implementation
dependent if the value does not fit. Isn't that correct? My posted
method attempts to avoid this and simply do a bit copy without value
checking. So I don't believe that your post is in fact equivalent to
my post. Maybe the standard gurus could comment on this and correct me
if I am wrong here.

And yes, my post does rely on some assumptions about sizes of short
and long which I should have mentioned.

I am still trying to figure out your "two's complement" comment. Not
sure what this has to do with it. Could you elaborate?

James Tursa