encoding matter

E

Evangelista Sami

hello

i have a program which manipulates ints which have their value in a
limited range, for instance, [-100..+100].
in a hash table i store these values. as this hash table can grow very
large, i whish to store this ints in a minimal number of characters
(1 for the previous range). so for each range of the program i create
an appropriate structure. for instance,
typedef struct
{
char c1;
char c2;
} __2chars;
if the int can have between 256 and 65536 values.

my problem is that i don't know hot to pass from an int to a __2chars
without making a big function.

any idea?

Sami Evangelista
 
L

lallous

Evangelista Sami said:
hello

i have a program which manipulates ints which have their value in a
limited range, for instance, [-100..+100].
in a hash table i store these values. as this hash table can grow very
large, i whish to store this ints in a minimal number of characters
(1 for the previous range). so for each range of the program i create
an appropriate structure. for instance,
typedef struct
{
char c1;
char c2;
} __2chars;
if the int can have between 256 and 65536 values.

my problem is that i don't know hot to pass from an int to a __2chars
without making a big function.

any idea?

Sami Evangelista

Try making a union:

typedef struct

{

char c1;

char c2;

} __2chars;

typedef union

{

__2chars x;

int y;

} __2charsu;



Or try something like:

int x = c1 << 8 | c2; (or swap c1 w/ c2 for endian issues)
 
S

Sean Kenwrick

Evangelista Sami said:
hello

i have a program which manipulates ints which have their value in a
limited range, for instance, [-100..+100].
in a hash table i store these values. as this hash table can grow very
large, i whish to store this ints in a minimal number of characters
(1 for the previous range). so for each range of the program i create
an appropriate structure. for instance,
typedef struct
{
char c1;
char c2;
} __2chars;
if the int can have between 256 and 65536 values.

my problem is that i don't know hot to pass from an int to a __2chars
without making a big function.

any idea?

What about casting and letting the compiler do it?

E.g.

#include <stdio.h>

typedef struct{
char a,b;
} __2chars;

typedef struct {
char a;
} __1char;

main(){
__2chars a;
short int b;
__1char c;

short int * p;

b=257; // a two byte integer value to test with
p=(short int *)&a; // Make p point to the structure (but cast as an int
*)
*p=b; // Now assign the struct elements to the value of b
printf("a=%d b=%d\n",(int) a.a, (int) a.b); // this outputs 1 and 1
for 257

b=99; // Smaller value for single byte ints
p=(int *) &c; // make p point to the 1 byte struct
*p= (char) b; // truncate b by casting to a char..
printf("a=%d\n",(int) c.a); // c.a is set to 99


}

Sean
 
E

Evangelista Sami

lallous said:
Evangelista Sami said:
hello

i have a program which manipulates ints which have their value in a
limited range, for instance, [-100..+100].
in a hash table i store these values. as this hash table can grow very
large, i whish to store this ints in a minimal number of characters
(1 for the previous range). so for each range of the program i create
an appropriate structure. for instance,
typedef struct
{
char c1;
char c2;
} __2chars;
if the int can have between 256 and 65536 values.

my problem is that i don't know hot to pass from an int to a __2chars
without making a big function.

any idea?

Sami Evangelista

Try making a union:

typedef struct

{

char c1;

char c2;

} __2chars;

typedef union

{

__2chars x;

int y;

} __2charsu;



Or try something like:

int x = c1 << 8 | c2; (or swap c1 w/ c2 for endian issues)

the problem is that u assume (in this case) that only the 16 last bits
of the int are used which is not necessarely the case.
 
P

Peter Pichler

Evangelista Sami said:
"lallous" <[email protected]> wrote in message
Evangelista Sami said:
hello

i have a program which manipulates ints which have their value in a
limited range, for instance, [-100..+100].
in a hash table i store these values. as this hash table can grow very
large, i whish to store this ints in a minimal number of characters
(1 for the previous range). so for each range of the program i create
an appropriate structure. for instance,
typedef struct
{
char c1;
char c2;
} __2chars;
if the int can have between 256 and 65536 values.

my problem is that i don't know hot to pass from an int to a __2chars
without making a big function.

any idea?

Sami Evangelista

Try making a union:

typedef struct

{

char c1;

char c2;

} __2chars;

typedef union

{

__2chars x;

int y;

} __2charsu;



Or try something like:

int x = c1 << 8 | c2; (or swap c1 w/ c2 for endian issues)

the problem is that u assume (in this case) that only the 16 last bits
of the int are used which is not necessarely the case.

And you seem to assume that only the last 8 bits of the char are used ;-)

If you want portability, a funtion is your only option. Everything else,
including unions and pointers, relies on an implementation-defined
behaviour at best, an undefined behaviour at worst.

If you know the target platform well enough, and if you know that you
will never port your program anywhere else, by all means use some kind
of optimization such as unions, but only after you have made sure that
your structure contains no padding bytes. In that case (if you know your
target platform well, that is) you presumably also know a suitable type
with sizeof(type)==2. On many platforms, short fits the bill.
 
P

Peter Pichler

Sean Kenwrick said:
Evangelista Sami said:
hello

i have a program which manipulates ints which have their value in a
limited range, for instance, [-100..+100].
in a hash table i store these values. as this hash table can grow very
large, i whish to store this ints in a minimal number of characters
(1 for the previous range). so for each range of the program i create
an appropriate structure. for instance,
typedef struct
{
char c1;
char c2;
} __2chars;
if the int can have between 256 and 65536 values.

What I forgot to mention in my other post is that it is not entirely clear
how you represent negative numbers in this representation.
What about casting and letting the compiler do it?

E.g.

#include <stdio.h>

typedef struct{
char a,b;
} __2chars;

typedef struct {
char a;
} __1char;

main(){
__2chars a;
short int b;
__1char c;

short int * p;

b=257; // a two byte integer value to test with
p=(short int *)&a; // Make p point to the structure (but cast as an int
*)

What makes you think that sizeof(short int)==2?
*p=b; // Now assign the struct elements to the value of b
printf("a=%d b=%d\n",(int) a.a, (int) a.b); // this outputs 1 and 1
for 257

What makes you think that char has 8 bits?
Even if it had, can you predict what would get printed for, let's say,
b==19500? A free hint: try it on a) PC and b) Macintosh.
And finally, what would get printed for b==-42?
b=99; // Smaller value for single byte ints
p=(int *) &c; // make p point to the 1 byte struct
*p= (char) b; // truncate b by casting to a char..
printf("a=%d\n",(int) c.a); // c.a is set to 99
}

Peter
 
J

Jack Klein

hello

i have a program which manipulates ints which have their value in a
limited range, for instance, [-100..+100].
in a hash table i store these values. as this hash table can grow very
large, i whish to store this ints in a minimal number of characters
(1 for the previous range). so for each range of the program i create
an appropriate structure. for instance,
typedef struct
{
char c1;
char c2;
} __2chars;

This is an illegal name in your C program. All symbols beginning with
either two underscores or an underscore followed by an upper case
letter are reserved for the implementation in all contexts.
 
E

Evangelista Sami

Peter Pichler said:
Sean Kenwrick said:
Evangelista Sami said:
hello

i have a program which manipulates ints which have their value in a
limited range, for instance, [-100..+100].
in a hash table i store these values. as this hash table can grow very
large, i whish to store this ints in a minimal number of characters
(1 for the previous range). so for each range of the program i create
an appropriate structure. for instance,
typedef struct
{
char c1;
char c2;
} __2chars;
if the int can have between 256 and 65536 values.

What I forgot to mention in my other post is that it is not entirely clear
how you represent negative numbers in this representation.

that's the problem in fact. in other words, i only know that my ints
have their value in a specific range so i would like to encode them in
a minimum number of characters.
i may have a solution. its not very pretty, surely not portable, but
it could perhaps work. here it is :
if my integer's range is [-2500 .. 635] i first convert it into a long
int i then add -2500 to i and then put i into c1, i >> 8 into c2,
etc...
what do you think of it ? i know this is ugly, but could it work?
 
P

Peter Pichler

Evangelista Sami said:
"Peter Pichler" <[email protected]> wrote in message
What I forgot to mention in my other post is that it is not entirely clear
how you represent negative numbers in this representation.

that's the problem in fact. in other words, i only know that my ints
have their value in a specific range so i would like to encode them in
a minimum number of characters.
i may have a solution. its not very pretty, surely not portable, but
it could perhaps work. here it is :
if my integer's range is [-2500 .. 635] i first convert it into a long
int i then add -2500 to i and then put i into c1, i >> 8 into c2,
etc...
what do you think of it ? i know this is ugly, but could it work?

Ugly it might be, but it would work and it would even be portable. The only
problem is that you need to store the offset somewhere as well. How else
would you know that you need to subtract 2500 when you convert it back?

On the other hand, your range [-2500..635] fits comfortably in a short int.
You could use chars for the smallest range, shorts for larger etc, up to
long longs for the largest...

You could also use chars as per your original suggestions, converting your
number to unsigned first, before splitting it into several chars. When
converting it back, combine it to unsigned and convert to signed afterwards.

Peter
 

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

No members online now.

Forum statistics

Threads
474,138
Messages
2,570,804
Members
47,349
Latest member
jojonoy597

Latest Threads

Top