# Double char to single short? Easy C++ question.

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

## Recommended Posts

Hello!
Recently I posted a thread for my memory leaks. I managed to fix them, but I didn't want to bring the topic again so I didn't answer.
So I said: Why shoud I believe in what other software says about my program? Lets track all the allocation and dellocations. This way I'll be sure everything is alright. But if I start... hmh it would be better if I create a whole memory pool. It would be more experience for me...

-Intro & reasons why I need the answer of the questions. Skip if you want, I just can't ask the question without giving more information than it is needed -

## How do I take two bytes(chars) and convert them to a single short? (everything is unsigned) char a[2]; a[0] = 1; a[1] = 2; short b = a;(!?!? how shoud I cast it) cout << b; It shoud print 258  EDIT: Didn't notice I have posted it in game programming. Sorry! Edited September 13, 2012 by Nickie

##### Share on other sites
[font=courier new,courier,monospace]short b = short(a[0])<<8 | short(a[1]);[/font]
or
[font=courier new,courier,monospace]short b = *reinterpret_cast<short*>(a);[/font]

##### Share on other sites
Ohhh... Seriously.. I'm playing with bitwise oprations only in the last 48 hours. And I absolutely forgot that I can do this...
I tried the second option but I messed with the C style casting I used. And it returned me a number around 65000..
Thanks.

##### Share on other sites
The bit-wise method is arguably "safer"...but perhaps this is faster?

[source lang="cpp"]char ch[2] = { 'A', 'B' };

char *cPtr = &ch;

short sh = *((short *)cPtr);[/source]

All we're doing here is obtaining the address (pointer) of "ch". Then, in one line, we cast it to a short* and dereference it. Just a quick and easy way of doing things when you're working with simple data-types of a known, fixed size.

EDIT:

Before anyone jumps my case on this I just wanted to show the OP what goes on "under the hood". As Hodgman suggest, *reinterpret_cast<short*>(a) is probably a much cleaner way to go about things and reduces the potential of programming error. But if the OP has no idea how it works then using it won't be very helpful. And what I showed is valid in C, C++, C# and quite a few other languages other than C++. Edited by ATC

##### Share on other sites
what I showed is valid in C, C++...
Unfortunately, you're code is invalid char ch[2] = { 'A', 'B' }; char *cPtr = ch;//correct - a T[] can decay into a T* (this is what's going on in the reinterpret_cast example) char *cPtr = &ch;//error - cannot convert from address-of-T[] to T* char *cPtr = &ch[0];//correct - the address of the first item will be a pointer to the start of the array short sh = *((short *)cPtr);//this is equivalent to the reinterpret_cast above, known as a C-style cast. // I actually prefer these C-style casts as 'reinterpret_cast' is (IMHO) ugly short sh = *((short *)ch);//also correct - just folding line 1 into the cast Edited by Hodgman

##### Share on other sites

Unfortunately, you're code is invalid Posted Image

Say waaahhhh!?

Here, run this:

///////////////////////////////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include <iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
char ch[2] = { 'A', 'B' };
char *cPtr = ch;
short sh = *((short *)cPtr);

char dst[2];
short *pSh = (short *)dst;
*pSh = sh;

cout << dst[0] << dst[1] << endl;

return 0;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////

Output: AB

So I don't see how my code was invalid? </scratch head>

EDIT: Oh, were you talking about how I accidentally used an ampersand in front of the array indentifier, which would actually create a char**? Twas just a typo, but your reply was nonetheless correct; as is my above example, where I didn't make the same typo!

EDIT (AGAIN): BTW, did you fix that in my first post for me? ;-) Edited by ATC

##### Share on other sites
1) [font=courier new,courier,monospace]char *cPtr = &ch;[/font]
vs
2) [font=courier new,courier,monospace]char *cPtr = ch;[/font]

##### Share on other sites
Don't do the array-cast-thing if you want your bytes to be laid out in a predefined order. It is not portable. It works on Intel-style (x86, x86-64) and other little endian machines, but will may fail on some other architectures, like big endian ARM or PowerPC. If you get your data into your bytes using it as a short, you're fine though.

The shift-operator on the other hand "knows" about endianness and will produce the correct result. You should however use unsigned char instead of char, or else very funny things may happen (shift handles negative number in a special way, preserving the sign bit, thus messing up all your nice computations). Consider this for example:

 char y[2] = {0x00, 0x80}; std::cout << std::hex << short(y[0]) << ", " << short(y[1]) << ", " << (short(y[0]) << 8 | short(y[1]))<< std::endl; 

You'd expect it to print "0, 80, 80", but in reality it's more likely to print "0, ff80, ffffff80" which is not at all what you want. Do the same with unsigned data types and it will work... Edited by rnlf

##### Share on other sites

You should however use unsigned char instead of char, or else very funny things may happen (shift handles negative number in a special way, preserving the sign bit, thus messing up all your nice computations).

Well... char is a bit strange anyways because char, signed char and unsigned char are three distinct types. A char may be signed or unsigned if not specified.

1. 1
2. 2
3. 3
4. 4
Rutin
11
5. 5

• 12
• 19
• 10
• 14
• 10
• ### Forum Statistics

• Total Topics
632665
• Total Posts
3007711
• ### Who's Online (See full list)

There are no registered users currently online

×