473,324 Members | 2,370 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,324 software developers and data experts.

conversion...

unsigned short int i;
char c[] = { 0x00, 0x04, 0x00, 0x0C, 'A', 'B', 'C', 0x00 };
^^^^^^^^^^^
The 3rd and 4th byte represent the short value "12".
Q: what is the easiest way to copy these 2 bytes from c to i?
Herwig
Nov 14 '05 #1
17 1252
Herwig wrote:
unsigned short int i;
char c[] = { 0x00, 0x04, 0x00, 0x0C, 'A', 'B', 'C', 0x00 };
^^^^^^^^^^^
The 3rd and 4th byte represent the short value "12".
Q: what is the easiest way to copy these 2 bytes from c to i?
Herwig


memcpy(&i, &c[2], 2);

That said, you have some portability issues to consider

1) endianness (you may have to reverse the bytes), along the lines of
unsigned char *p = i;
p[0] = c[3];
p[1] = c[2];

2) relative size of char and short is assumed to be 1 byte for
char (guaranteed by standard that sizeof(char) == 1), and
2 bytes for short (not guaranteed).

3) Probably some others I'm ignorant of but you'll no doubt hear
of shortly...

-David
Nov 14 '05 #2
Herwig wrote:
unsigned short int i;
char c[] = { 0x00, 0x04, 0x00, 0x0C, 'A', 'B', 'C', 0x00 };
^^^^^^^^^^^
The 3rd and 4th byte represent the short value "12".
Q: what is the easiest way to copy these 2 bytes from c to i?


Dunno about the *easiest*; I'd like to have a fighting chance of
being portable, as well.

I'd go for

i = ((unsigned char) c[2] << CHAR_BIT) + (unsigned char) c[3];

What problems didn't I see?

--
Chris "electric hedgehog" Dollin
Nov 14 '05 #3
In article <d4**************************@posting.google.com >,
Herwig <in**@bitart.at> wrote:
:unsigned short int i;
:char c[] = { 0x00, 0x04, 0x00, 0x0C, 'A', 'B', 'C', 0x00 };

:The 3rd and 4th byte represent the short value "12".
:Q: what is the easiest way to copy these 2 bytes from c to i?

i = (unsigned short) c[2] <<8 || (unsigned short) c[3];
--
Ceci, ce n'est pas une idée.
Nov 14 '05 #4
In article <d1**********@malatesta.hpl.hp.com>,
Chris Dollin <ke**@hpl.hp.com> wrote:
:> unsigned short int i;
:> char c[] = { 0x00, 0x04, 0x00, 0x0C, 'A', 'B', 'C', 0x00 };

:> The 3rd and 4th byte represent the short value "12".
:> Q: what is the easiest way to copy these 2 bytes from c to i?

:Dunno about the *easiest*; I'd like to have a fighting chance of
:being portable, as well.

: i = ((unsigned char) c[2] << CHAR_BIT) + (unsigned char) c[3];

:What problems didn't I see?

If the source is taken to a different platform with a different
CHAR_BIT then with the same literal constants you would get a
different short. The shift value should probably be an application
constant rather than an implimentation constant.
--
'The short version of what Walter said is "You have asked a question
which has no useful answer, please reconsider the nature of the
problem you wish to solve".' -- Tony Mantler
Nov 14 '05 #5
David Resnick wrote:
Herwig wrote:
unsigned short int i;
char c[] = { 0x00, 0x04, 0x00, 0x0C, 'A', 'B', 'C', 0x00 };
^^^^^^^^^^^
The 3rd and 4th byte represent the short value "12".
Q: what is the easiest way to copy these 2 bytes from c to i?
Herwig

memcpy(&i, &c[2], 2);

That said, you have some portability issues to consider

1) endianness (you may have to reverse the bytes), along the lines of
unsigned char *p = i;
p[0] = c[3];
p[1] = c[2];

2) relative size of char and short is assumed to be 1 byte for
char (guaranteed by standard that sizeof(char) == 1), and
2 bytes for short (not guaranteed).

3) Probably some others I'm ignorant of but you'll no doubt hear
of shortly...

-David


Other's solutions appear much better than mine, calculation avoids
the problems above. I saw the word "copy" and suggested a way to copy,
rather than "use arithmetic".

-David
Nov 14 '05 #6
Walter Roberson wrote:
:unsigned short int i;
:char c[] = { 0x00, 0x04, 0x00, 0x0C, 'A', 'B', 'C', 0x00 };

:The 3rd and 4th byte represent the short value "12".
:Q: what is the easiest way to copy these 2 bytes from c to i?

i = (unsigned short) c[2] <<8 || (unsigned short) c[3];


I'm pretty sure that one of the '|' characters is superfluous, but I can't
seem to work out which...
Christian

Nov 14 '05 #7
Herwig wrote:

unsigned short int i;
char c[] = { 0x00, 0x04, 0x00, 0x0C, 'A', 'B', 'C', 0x00 };
^^^^^^^^^^^
The 3rd and 4th byte represent the short value "12".
Q: what is the easiest way to copy these 2 bytes from c to i?


int ix;
char *p

for (p = &c[3], ix = 0, i = 0; ix < 2; ix++)
i = i * 256 + (unsigned char) p[ix];

This is independant of endianess and of the size of a byte,
provided the char array doesn't contain values over 255. The point
is to design around the input format.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 14 '05 #8
In article <39*************@individual.net>,
Christian Kandeler <ch****************@hob.de_invalid> wrote:
:Walter Roberson wrote:

:> i = (unsigned short) c[2] <<8 || (unsigned short) c[3];

:I'm pretty sure that one of the '|' characters is superfluous, but I can't
:seem to work out which...

It's the middle one...

[After programming tables of regular expressions for days on end, I'm mostly
surprised that I didn't start the line with '^ ]
--
'ignorandus (Latin): "deserving not to be known"'
-- Journal of Self-Referentialism
Nov 14 '05 #9
Christian Kandeler wrote:
Walter Roberson wrote:
:unsigned short int i;
:char c[] = { 0x00, 0x04, 0x00, 0x0C, 'A', 'B', 'C', 0x00 };

:The 3rd and 4th byte represent the short value "12".
:Q: what is the easiest way to copy these 2 bytes from c to i?

i = (unsigned short) c[2] <<8 || (unsigned short) c[3];
I'm pretty sure that one of the '|' characters is superfluous, but I

can't seem to work out which...


The code is wrong anyway. For example, if c[3] is -1 then
(unsigned short)c[3] will be 0xFFFF (on a typical system),
which overwrites whatever you got from c[2] .

Then (extra for pedants..) you have the possibility of creating
a trap representation; if int is bigger than short then the type
of each operand of the '|', after the usual promotions,
will be 'signed int'.

Chris Dollin's version was correct.

Nov 14 '05 #10
Herwig wrote:

unsigned short int i;
char c[] = { 0x00, 0x04, 0x00, 0x0C, 'A', 'B', 'C', 0x00 };
^^^^^^^^^^^
The 3rd and 4th byte represent the short value "12".
Q: what is the easiest way to copy these 2 bytes from c to i?
Herwig


i = c[2] << 8 + c[4];

--
pete
Nov 14 '05 #11
CBFalconer wrote:

Herwig wrote:

unsigned short int i;
char c[] = { 0x00, 0x04, 0x00, 0x0C, 'A', 'B', 'C', 0x00 };
^^^^^^^^^^^
The 3rd and 4th byte represent the short value "12".
Q: what is the easiest way to copy these 2 bytes from c to i?


int ix;
char *p

for (p = &c[3], ix = 0, i = 0; ix < 2; ix++)
i = i * 256 + (unsigned char) p[ix];

This is independant of endianess and of the size of a byte,
provided the char array doesn't contain values over 255. The point
is to design around the input format.


The cast converts a char type expression to unsigned char
just prior to be converted to either int or unsigned.
I don't see the point of doing that with the cast.

--
pete
Nov 14 '05 #12
pete wrote:

Herwig wrote:

unsigned short int i;
char c[] = { 0x00, 0x04, 0x00, 0x0C, 'A', 'B', 'C', 0x00 };
^^^^^^^^^^^
The 3rd and 4th byte represent the short value "12".
Q: what is the easiest way to copy these 2 bytes from c to i?
Herwig


i = c[2] << 8 + c[4];


That's assuming that c is an array
initialised with integer constants.

--
pete
Nov 14 '05 #13
pete wrote:

CBFalconer wrote:

Herwig wrote:

unsigned short int i;
char c[] = { 0x00, 0x04, 0x00, 0x0C, 'A', 'B', 'C', 0x00 };
^^^^^^^^^^^
The 3rd and 4th byte represent the short value "12".
Q: what is the easiest way to copy these 2 bytes from c to i?


int ix;
char *p

for (p = &c[3], ix = 0, i = 0; ix < 2; ix++)
i = i * 256 + (unsigned char) p[ix];

This is independant of endianess and of the size of a byte,
provided the char array doesn't contain values over 255. The point
is to design around the input format.


The cast converts a char type expression to unsigned char
just prior to be converted to either int or unsigned.
I don't see the point of doing that with the cast.


I think my problem is that I assumed that c was being
initialised with integer constants within the range of char.

--
pete
Nov 14 '05 #14
pete wrote:
CBFalconer wrote:
Herwig wrote:

unsigned short int i;
char c[] = { 0x00, 0x04, 0x00, 0x0C, 'A', 'B', 'C', 0x00 };
^^^^^^^^^^^
The 3rd and 4th byte represent the short value "12".
Q: what is the easiest way to copy these 2 bytes from c to i?


int ix;
char *p

for (p = &c[3], ix = 0, i = 0; ix < 2; ix++)
i = i * 256 + (unsigned char) p[ix];

This is independant of endianess and of the size of a byte,
provided the char array doesn't contain values over 255. The
point is to design around the input format.


The cast converts a char type expression to unsigned char
just prior to be converted to either int or unsigned.
I don't see the point of doing that with the cast.


If the native char type is signed, without the cast negative values
will be sign extended on conversion to int and things won't work.

BTW, the index [3] above should be [2].

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson

Nov 14 '05 #15
Chris Dollin wrote:
Herwig wrote:
unsigned short int i;
char c[] = { 0x00, 0x04, 0x00, 0x0C, 'A', 'B', 'C', 0x00 };
^^^^^^^^^^^
The 3rd and 4th byte represent the short value "12".
Q: what is the easiest way to copy these 2 bytes from c to i?

.
Dunno about the *easiest*; I'd like to have a fighting chance of
being portable, as well.
.
I'd go for
.
i = ((unsigned char) c[2] << CHAR_BIT)
+ (unsigned char) c[3];
.
What problems didn't I see?


1. Theoretically, sizeof(short) can be 1, therefore left
shifting by CHAR_BIT bits can invoke undefined behaviour.

In such cases, how does one copy _two_ bytes to a single
byte entity?

Whilst a 'robust' replacement for the above is...

i = ((c[2] + 0u) << (CHAR_BIT-1) << 1) + c[3];

....there is another issue...

2. More generally, CHAR_BIT needn't be 8. The question has
to be asked what the OP actually wants to happen! Are they
joining two octet values to form a 16-bit word? If so, then
your code could fail on machines where CHAR_BIT isn't 8.
[But also, the OP's choice of _plain_ char becomes suspect.]

--
Peter

Nov 14 '05 #16
pete wrote:

Herwig wrote:

unsigned short int i;
char c[] = { 0x00, 0x04, 0x00, 0x0C, 'A', 'B', 'C', 0x00 };
^^^^^^^^^^^
The 3rd and 4th byte represent the short value "12".
Q: what is the easiest way to copy these 2 bytes from c to i?
Herwig


i = c[2] << 8 + c[4];


c[4] should be c[3],
and assumptions have been made.

--
pete
Nov 14 '05 #17
Peter Nilsson wrote:
Chris Dollin wrote:
Herwig wrote:
> unsigned short int i;
> char c[] = { 0x00, 0x04, 0x00, 0x0C, 'A', 'B', 'C', 0x00 };
> ^^^^^^^^^^^
> The 3rd and 4th byte represent the short value "12".
> Q: what is the easiest way to copy these 2 bytes from c to i? .
Dunno about the *easiest*; I'd like to have a fighting chance of
being portable, as well.
.
I'd go for
.
i = ((unsigned char) c[2] << CHAR_BIT)
+ (unsigned char) c[3];
.
What problems didn't I see?


1. Theoretically, sizeof(short) can be 1, therefore left
shifting by CHAR_BIT bits can invoke undefined behaviour.


<fx:headMeetsWall/> Of course. Still, as you say ...
In such cases, how does one copy _two_ bytes to a single
byte entity?
I think we have to assume that shorts are twice as long as chars.
If not, it's not clear the problem is soluble ...
Whilst a 'robust' replacement for the above is...

i = ((c[2] + 0u) << (CHAR_BIT-1) << 1) + c[3];

...there is another issue...

2. More generally, CHAR_BIT needn't be 8. The question has
to be asked what the OP actually wants to happen! Are they
joining two octet values to form a 16-bit word? If so, then
your code could fail on machines where CHAR_BIT isn't 8.
[But also, the OP's choice of _plain_ char becomes suspect.]


I picked CHAR_BIT precisely because it might not be 8. But I
think we need stronger guards, because the code relies on short
being *at least* twice as long as char.

I'm now contemplating the possibility of a machine with 9-bit
chars and 16-bit shorts.

--
Chris "electric hedgehog" Dollin
Nov 14 '05 #18

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Stub | last post by:
Docs says that "The compiler does not use an explicit constructor to implement an implied conversion of types. It's purpose is reserved explicitly for construction." I put up code of three cases...
7
by: Michael Lehn | last post by:
Hi, I have a question regarding the conversion of objects. When is the conversion done by the constructor and when by the operator. My feeling tells me that the constructor is preferred. But...
16
by: TTroy | last post by:
Hello, I'm relatively new to C and have gone through more than 4 books on it. None mentioned anything about integral promotion, arithmetic conversion, value preserving and unsigned preserving. ...
31
by: Bjørn Augestad | last post by:
Below is a program which converts a double to an integer in two different ways, giving me two different values for the int. The basic expression is 1.0 / (1.0 * 365.0) which should be 365, but one...
11
by: Steve Gough | last post by:
Could anyone please help me to understand what is happening here? The commented line produces an error, which is what I expected given that there is no conversion defined from type double to type...
2
by: Alex Sedow | last post by:
Why explicit conversion from SomeType* to IntPtr is not ambiguous (according to standart)? Example: // System.IntPtr class IntPtr { public static explicit System.IntPtr (int); public...
3
by: Steve Richter | last post by:
here is a warning I am getting in a C++ .NET compile: c:\SrNet\jury\JuryTest.cpp(55) : warning C4927: illegal conversion; more than one user-defined conversion has been implicitly applied while...
0
by: Lou Evart | last post by:
DOCUMENT CONVERSION SERVICES Softline International (SII) operates one of the industry's largest document and data conversion service bureaus. In the past year, SII converted over a million...
0
by: dataentryoffshore | last post by:
Get a Discount up to 60% on data entry, data capture, dataentry services, large volume data processing and data conversion services through offshore facilities in India. Offshore data entry also...
21
by: REH | last post by:
It it permissible to use the constructor style cast with primitives such as "unsigned long"? One of my compilers accepts this syntax, the other does not. The failing one chokes on the fact that the...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.