Saving an unsigned short integer to string

T

Test

I need to save ant interger with values ranging from 0-65535 (0-FFFF) to a
string and later retrieve the value.

For example:

...
int i;
char mytxt[2];

i=55;
...

What would be the fastest way to save i to mytxt and later retrieve it? I am
looking from a simple cast if possible. I want to avoid using fuction calls.
 
E

Eric Sosman

I need to save ant interger with values ranging from 0-65535 (0-FFFF) to a
string and later retrieve the value.

For example:

..
int i;
char mytxt[2];

i=55;
..

What would be the fastest way to save i to mytxt and later retrieve it? I am
looking from a simple cast if possible. I want to avoid using fuction calls.

Nomenclature: What you describe is not a "string" as C uses
the term. In C, a "string" is an array of `char' containing zero
or more non-zero "payload" characters followed by one zero byte
to mark the end. You've got an array of `char', but it's not a
"string" unless by coincidence.

Moving on: The first thing you should do is change `char' to
`unsigned char', avoiding potential mysteries on systems where
`char' is a signed type. An `unsigned char' can hold values from
0 through 255 (possibly higher, but that's rare), but a plain
`char' might go only as high as 127. And then:

int i = ... something between 0 and 65535 ...
unsigned char mybytes[2]; // `mytxt' is a misleading name
mybytes[0] = i & 0xff;
mybytes[1] = i >> 8;
...
int j = (mybytes[1] << 8) + mybytes[0];

(You could reverse the positions of the low- and high-order bytes,
if you like, so long as the encoding and decoding use the same
convention.)

There are no guarantees about speed, but one approach that
is likely to be faster is

int i = ... something between 0 and 65535 ...
unsigned short mybytes;
mybytes = i;
...
int j = mybytes;

Whether you can use this depends on whether you truly need a
two-character array; you haven't explained that requirement.
 
R

Rui Maciel

wrote:
I need to save ant interger with values ranging from 0-65535 (0-FFFF) to
a string and later retrieve the value.

For example:

..
int i;
char mytxt[2];

i=55;
..

What would be the fastest way to save i to mytxt and later retrieve it? I
am looking from a simple cast if possible. I want to avoid using fuction
calls.

How about a good old fashion union?

<code>
#include <stdio.h>

union Foo
{
int i;
char mytext[2];
};


int main(void)
{
union Foo foo;

foo.i = 55;
printf("foo.mytext: %c, %c\n", foo.mytext[0], foo.mytext[1]);
return 0;
}
</code>


Rui Maciel
 
R

Rui Maciel

Rui said:
union Foo
{
int i;
char mytext[2];
};

It must be said that it isn't a good idea to use the char and int data type,
because the number of bits that are used to define those types are platform-
dependent.

Considering the range that was mentioned, which was 0-65535, the following
union might be more appropriate:

union Foo
{
uint16_t i;
uint8_t mytext[2];
};


Rui Maciel
 
K

Keith Thompson

Rui Maciel said:
Rui said:
union Foo
{
int i;
char mytext[2];
};

It must be said that it isn't a good idea to use the char and int data type,
because the number of bits that are used to define those types are platform-
dependent.

Considering the range that was mentioned, which was 0-65535, the following
union might be more appropriate:

union Foo
{
uint16_t i;
uint8_t mytext[2];
};

That's certainly better than using int, but byte ordering varies from
one system to another. Storing a value in i could result in the
high-order byte being stored in mytext[0] and the low-order byte in
mytext[1], or vice versa. If you want to be able to share the byte
values across different systems, you'll want to control the byte order
yourself -- which is why we have "network byte order".

See http://en.wikipedia.org/wiki/Endianness
 
F

Fred K

Rui Maciel <[email protected]> writes: > Rui Maciel wrote: >> union Foo >> { >> int i; >> char mytext[2]; >> }; > > It must be said that it isn'ta good idea to use the char and int data type, > because the number of bits that are used to define those types are platform- > dependent. > > Considering the range that was mentioned, which was 0-65535, the following > union might be more appropriate: > > union Foo > { > uint16_t i; > uint8_t mytext[2]; > }; That's certainly better than using int, but byte ordering varies from one system to another. Storing a value in i could result in the high-order byte being stored in mytext[0] and the low-order byte in mytext[1], or vice versa. If you want to be able to share the byte values across different systems, you'll want to control the byte order yourself -- which is why we have "network byte order". See http://en.wikipedia.org/wiki/Endianness

These solutions assume that a byte on the OP's platform is eight bits. While this is almost always true today, ther are platforms where this is not so..

The important thing is that 16 bits are needed to store any value in the specified range. And yes, byte-order will also be of concern if the store andrestore operations are on different platforms even if the size of a byte is the same on both.
 
R

Rui Maciel

Fred said:
These solutions assume that a byte on the OP's platform is eight bits.
While this is almost always true today, ther are platforms where this is
not so.

The standard states that the intN_t types have exactly N bits, without
padding, and if an implementation provides types with N bits then it must
define those types. If the implementation doesn't provide those types then
those types are considered optional, and the implementation doesn't need to
provide them.

Therefore, when we are dealing with a platform which doesn't support these
types, those types won't exist, and that code won't compile.

That isn't exactly a problem. It's instead a moment to celebrate, because
finally someone actually found one of those mythical platforms where it was
impossible to implement a 8-bit data type.


Rui Maciel
 
M

Malcolm McLean

I need to save ant interger with values ranging from 0-65535 (0-FFFF) to a
string and later retrieve the value.
char mytxt[2];

i=55;


What would be the fastest way to save i to mytxt and later retrieve it? I am
looking from a simple cast if possible. I want to avoid using fuction calls.

Read Eric Sosman on strings and buffers.

Assuming you really want a buffer

make mytxt unsigned char.

then you want

mytxt[0] = ((i >> 8) & 0xFF);
mytxt[1] = (i & 0xFF);

Modern compilers will usually optimise these sorts of operations out.
But even if it doesn't, logical operations are so fast that it's highly
unlikely to be a rate-limiting step in your program.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top