Link to home
Start Free TrialLog in
Avatar of perlperl
perlperl

asked on

convert uint32 to uint16

What is the best way to conver uint32 to uint16

uint32_t val = 0x000F; // This is never greater than 16 in decimal.
uint16_t new_val = (uint16_t) val;  // Is this the right way to do it.
ASKER CERTIFIED SOLUTION
Avatar of evilrix
evilrix
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
If you want to be sure the cast is safe and you're ok with using Boost...

http://www.boost.org/doc/libs/1_54_0/libs/numeric/conversion/doc/html/index.html

<boost/numeric/conversion/cast.hpp>
uint32_t val = 0x000F;
uint16_t new_val = boost::numeric_cast_cast<uint16_t>(val);

Open in new window

Avatar of perlperl
perlperl

ASKER

I believe this should work too ?

uint32_t num = <some value>; // lets value is something between 0 and 16.
uint16_t new_num = num;
It will but you may get a compiler warning (this is implementation defined) because it is a narrowing conversion. The cast tells the compiler, "shut-up, I know what I am doing".
I didnt get the warning..
Like I said, you may get a warning. It depends on your compiler and warning level setting. It's implementation defined.
Depends on which compiler you are using.  uint32_t and uint16_t are not standard C++ types if you are using one of the older compilers which doesn't have stdint.h.  If they are typedef'd then you will probably need the cast but if they are classes with the = operator defined to copy from one class to the other, then you probably won't.
the c cast is as good as the c++ static_cast if the cast is necessary at all. there are renowned experts for both ways. my preferred way is to avoid casts whenever possible. in the sample you posted it obviously would be the best to use an unsigned int

unsigned int ui = 0xf;

Open in new window


i dropped all leading zeros cause zeros would put an information into the literal which got lost when you make the assignment. of course, if you have more constants to assign you might use zeroes to make the easier to compare to to read.

casting of integers is a dangerous thing especially if you deal with signed/unsigned and integers where the most significant bit was used. that is the case for all negative signed integers.

void func(uint32_t dw);
....
uint16_t ui = (uint16_t)(-1);  // gives 0xffff
func(ui);  // compiles without warning
...
#define NIL (-1)   
void func(uint32_t dw)
{
     if (dw == NIL)   // would compare dw with 0xffffffff
     {
          ....
}

Open in new window


the above code doesn't use signed integers. so, it is not a way out of the issues by only using unsigned or size_t types. on the contrary, by using unsigned integers for counters which might be decremented you may run in a commonly made mistake:

for (size_t i = count-1; i >= 0; --i)
{
    ...

Open in new window


if size_t is unsigned the loop would not end but go infinite. but that isn't the only flaw, then: if count is 0, count-1 would overflow and may the loop cause to run a significant time if it doesn't crash before.

Sara