bytes calculation

S

seema

Hi all,

How to calculate upper 4 bytes and lower 4 bytes of a value? Can
somebody please explain??
say for example,
unsigned int scnlen_lo;
int scnlen_hi;
unsigned long long scnlen;

scnlen=888888;
scnlen_hi= ??//how to calculate upper 4 bytes of scnlen?
scnlen_lo =?? //how to calculate lower 4 bytes of scnlen??

Thanks in advance,
Seema Rao
 
J

jacob navia

seema said:
Hi all,

How to calculate upper 4 bytes and lower 4 bytes of a value? Can
somebody please explain??
say for example,
unsigned int scnlen_lo;
int scnlen_hi;
unsigned long long scnlen;

scnlen=888888;
scnlen_hi= ??//how to calculate upper 4 bytes of scnlen?
scnlen_lo =?? //how to calculate lower 4 bytes of scnlen??

Thanks in advance,
Seema Rao

Assuming sizeof(int)==4 (32 bits)

scnlen_hi=(scnlen>>32);
scnlen_lo=(scnlen&0xffffffff);
 
P

Pietro Cerutti

seema said:
Hi all,

How to calculate upper 4 bytes and lower 4 bytes of a value? Can
somebody please explain??
say for example,
unsigned int scnlen_lo;
int scnlen_hi;
unsigned long long scnlen;

scnlen=888888;
scnlen_hi= ??//how to calculate upper 4 bytes of scnlen?
scnlen_lo =?? //how to calculate lower 4 bytes of scnlen??

sclen_hi = scnlen >> 32;
sclen_lo = scnlen & 0xFFFFFFFF;

Assuming that sizeof(unsigned long long) == 64 and sizeof(int) == 32
 
R

Richard

jacob navia said:
Assuming sizeof(int)==4 (32 bits)

scnlen_hi=(scnlen>>32);
scnlen_lo=(scnlen&0xffffffff);

Assuming sizeof int ==4 then scnlen>>32 doesnt give the top 4 bytes.

Did he mean 2 bytes?

Or should we be assuming 64 bit ints in which case you are right.
 
R

Richard Heathfield

jacob navia said:
Assuming sizeof(int)==4 (32 bits)

scnlen_hi=(scnlen>>32);
scnlen_lo=(scnlen&0xffffffff);

Wrong. Your "solution" invokes undefined behaviour.
 
S

Spoon

Pietro said:
Assuming that sizeof(unsigned long long) == 64 and sizeof(int) == 32

I think you meant "Assuming CHAR_BIT == 8, sizeof(int) == 4, and
sizeof(unsigned long long) == 8".
 
R

Richard Heathfield

Pietro Cerutti said:
sclen_hi = scnlen >> 32;
sclen_lo = scnlen & 0xFFFFFFFF;

Assuming that sizeof(unsigned long long) == 64 and sizeof(int) == 32

Under those assumptions and assuming CHAR_BIT is 8, sclen_hi now
actually contains the top 28 bytes of scnlen, which isn't what was
asked.

If you meant those to be bit counts rather than byte counts, your code
invokes undefined behaviour.
 
M

Mark Bluemel

Richard said:
jacob navia said:




Wrong. Your "solution" invokes undefined behaviour.
Would it do anyone any harm if you were to a) explain why this is the
case, and b) explain how to solve the original poster's problem correctly?
 
R

Richard

Mark Bluemel said:
Would it do anyone any harm if you were to a) explain why this is the
case, and b) explain how to solve the original poster's problem
correctly?

"Mr" Heathfield is having a hissy fit because he doesn't feel he is
getting the appreciation and the kudos to the level at which he thinks
he deserves.
 
R

Richard Heathfield

Mark Bluemel said:
Would it do anyone any harm if you were to a) explain why this is the
case, and b) explain how to solve the original poster's problem
correctly?

I'll let Mr Navia explain why he's wrong.

Here's a solution that I believe to be correct - I don't have a C99
compiler, so I can't check it (because of the unsigned long long) - but
corrections are most welcome:

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int rc = EXIT_SUCCESS;
unsigned int scnlen_lo;
int scnlen_hi;
unsigned long long scnlen;
scnlen = 888888ULL;

/* first ensure that a result is possible */
if(sizeof scnlen_lo < 4 || scnlen_hi < 4)
{
puts("No solution exists.\n");
rc = EXIT_FAILURE;
}
else
{
/* build a mask with all bits set */
unsigned long long mask = -1;

/* we need to shift the mask leftward by 4 bytes,
i.e. 4 * CHAR_BIT */
size_t n = CHAR_BIT;
while(n--)
{
mask <<= 4;
}
/* now we can flip */
mask = ~mask;

/* that gives us half the solution with a simple & */
if(scnlen & mask <= UINT_MAX)
{
scnlen_lo = scnlen & mask;
}
else
{
puts("No solution exists for the low four bytes");
rc = EXIT_FAILURE;
}

/* now we need to go the other way */
mask = -1;
n = CHAR_BIT;
while(n--)
{
mask >>= 4;
}
/* same ol' same ol' */
mask = ~mask;
if(scnlen & mask <= INT_MAX)
{
scnlen_hi = scnlen & mask;
}
else
{
puts("No solution exists for the high four bytes");
rc = EXIT_FAILURE;
}
}
return rc;
}
 
P

Pietro Cerutti

Richard said:
Pietro Cerutti said:


Under those assumptions and assuming CHAR_BIT is 8, sclen_hi now
actually contains the top 28 bytes of scnlen, which isn't what was
asked.

Yes, sorry. I meant sizeof(unsigned long long) == 8, and sizeof(int) == 4
If you meant those to be bit counts rather than byte counts, your code
invokes undefined behaviour.

Can you explain me this point, please?
At least, is it so under C99?
cat ctemp.c
#include <stdio.h>

int main(void)
{
/**** START ****/
int hi, lo;
unsigned long long full;

full = 0xaaaaaaaabbbbbbbb;

hi = full >> 32;
lo = full & 0xFFFFFFFF;

printf("full is %llx\n", full);
printf("hi is %x\n", hi);
printf("low is %x\n", lo);

/**** STOP ****/
return(0);
}
gcc -Wall -std=c99 -o ctemp ctemp.c && ./ctemp
full is aaaaaaaabbbbbbbb
hi is aaaaaaaa
low is bbbbbbbb
 
J

jacob navia

Pietro said:
Yes, sorry. I meant sizeof(unsigned long long) == 8, and sizeof(int) == 4


Can you explain me this point, please?
At least, is it so under C99?

#include <stdio.h>

int main(void)
{
/**** START ****/
int hi, lo;
unsigned long long full;

full = 0xaaaaaaaabbbbbbbb;

hi = full >> 32;
lo = full & 0xFFFFFFFF;

printf("full is %llx\n", full);
printf("hi is %x\n", hi);
printf("low is %x\n", lo);

/**** STOP ****/
return(0);
}

full is aaaaaaaabbbbbbbb
hi is aaaaaaaa
low is bbbbbbbb

Please do not believe everything heathfield says...

He is a language lawyer, and those people do not live by the
same rules as the rest of us

:)
 
J

jacob navia

Richard said:
Assuming sizeof int ==4 then scnlen>>32 doesnt give the top 4 bytes.

Did he mean 2 bytes?

Or should we be assuming 64 bit ints in which case you are right.

scnlen is unsigned long long, 64 bits!
 
R

Richard

Richard Heathfield said:
I'll let Mr Navia explain why he's wrong.

Here's a solution that I believe to be correct - I don't have a C99
compiler, so I can't check it (because of the unsigned long long) - but
corrections are most welcome:

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int rc = EXIT_SUCCESS;
unsigned int scnlen_lo;
int scnlen_hi;
unsigned long long scnlen;
scnlen = 888888ULL;

/* first ensure that a result is possible */
if(sizeof scnlen_lo < 4 || scnlen_hi < 4)

Interesting use of sizeof. Never realised it could be used like that.
 
R

Richard

Richard Heathfield said:
Mark Bluemel said:


I'll let Mr Navia explain why he's wrong.

Here's a solution that I believe to be correct - I don't have a C99
compiler, so I can't check it (because of the unsigned long long) - but
corrections are most welcome:

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int rc = EXIT_SUCCESS;
unsigned int scnlen_lo;
int scnlen_hi;
unsigned long long scnlen;
scnlen = 888888ULL;

/* first ensure that a result is possible */
if(sizeof scnlen_lo < 4 || scnlen_hi < 4)
{
puts("No solution exists.\n");
rc = EXIT_FAILURE;
}
else
{
/* build a mask with all bits set */
unsigned long long mask = -1;

/* we need to shift the mask leftward by 4 bytes,
i.e. 4 * CHAR_BIT */
size_t n = CHAR_BIT;
while(n--)
{
mask <<= 4;
}
/* now we can flip */
mask = ~mask;

/* that gives us half the solution with a simple & */
if(scnlen & mask <= UINT_MAX)
{
scnlen_lo = scnlen & mask;
}
else
{
puts("No solution exists for the low four bytes");
rc = EXIT_FAILURE;
}

/* now we need to go the other way */
mask = -1;
n = CHAR_BIT;
while(n--)
{
mask >>= 4;
}
/* same ol' same ol' */
mask = ~mask;
if(scnlen & mask <= INT_MAX)
{
scnlen_hi = scnlen & mask;
}
else
{
puts("No solution exists for the high four bytes");
rc = EXIT_FAILURE;
}
}
return rc;
}

Possibly you could explain this program since it seems incredibly long
winder for an apparently "mask and shift" type question. Is it the 64
bits issues? Can C not rotate or mask a 64 bit long long?
 
J

jacob navia

Spoon said:
I think you meant "Assuming CHAR_BIT == 8, sizeof(int) == 4, and
sizeof(unsigned long long) == 8".

Please, are you a lawyer?

Can you tell me of a machine where char_bit != 8 ?

And please, a machine in use 2007 ok?
 
P

Pietro Cerutti

jacob said:
Please do not believe everything heathfield says...

He is a language lawyer, and those people do not live by the
same rules as the rest of us

:)

I can't get the point.
Does my code invokes undefined behavior or not?
 
J

jacob navia

Pietro said:
I can't get the point.
Does my code invokes undefined behavior or not?

I do not see any. It works in linux/windows/Mac/and many others.
But heathfield sees something, I do not know what, he is the lawyer,
not me!
 
M

Mark Bluemel

Pietro said:
....
I can't get the point.
Does my code invokes undefined behavior or not?

My guess is that if Richard H says it invokes undefined behaviour, it
does. I'm a little disappointed that he has not felt fit to explain why
and give chapter and verse, but that's his perogative.

However, the undefined behaviour on the implementations you happen to
use (or indeed most or even all implementations) may be for the code to
do what you expect.

Here we enter into the realms of philosophy and personal taste - Mr
Heathfield wishes for all C code to be provably correct (loosely
speaking) for a general abstract C implementation which sticks to the
letter of the language specification, while Mr Navia will accept C code
working on the sample of machines he happens to work with.
[Disclaimer - I do not speak for either party here, and my comments
above are my interpreations of their positions]
 

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,773
Messages
2,569,594
Members
45,119
Latest member
IrmaNorcro
Top