473,432 Members | 2,010 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,432 software developers and data experts.

GetByte(int x, int n)

GetByte(x, 3) should return the 3rd byte of the 32 bit integer x. Allowed
operators: ! ~ & ^ | + << >> (no assignment!).

Would the easiest way to do this be just creating 4 bit masks... and using
x&bitmask ?

Any other ideas?

Nov 14 '05
53 8914
Eric Sosman wrote:

pete wrote:
Dan Pop wrote:
The apparent objection that the >> operator has > >>implementation-defined
behaviour if its left operand is signed and negative is moot,
because
the bits not well defined by the standard are masked away from the
final result.


If an intermediate result is undefined, then it's all undefined.


First, "implementation-defined" is not "undefined."

Second, although the result is implementation-defined
for the case `(negative_int >> n) & UCHAR_MAX' under
discussion, an implementation-defined operand need not
always produce an implementation-defined result. Here
are a few examples of perfectly predictable results from
expressions involving implementation-defined values:

INT_MAX > INT_MIN == 1
(-1 >> 3) * 0 == 0
(-5 / 3) * 3 + (-5 % 3) == 3

(The last example involves implementation-defined values
in C89, but not in C99.)
The result of a left shift of an int value,
may result in a negative zero.
I believe that can be a trap.


Yes, but we were discussing right shifts.


Sorry, I get left and right mixed up too much on this newsgroup.
A right shift can result in negative zero.

(1000...0001 >> 1) can be (1000...0000), -0 in signed magnitude
(1111...1110 >> 1) can be (1111...1111), -0 in one's complement

--
pete
Nov 14 '05 #51
In <41***********@mindspring.com> pete <pf*****@mindspring.com> writes:
A right shift can result in negative zero.

(1000...0001 >> 1) can be (1000...0000), -0 in signed magnitude
(1111...1110 >> 1) can be (1111...1111), -0 in one's complement


But, since an implementation-defined value *must* be a valid value,
such implementations must treat -0 as an alternate representation of 0.
If they treat -0 as a trap representation, then they must make sure
that no right shift can generate the corresponding bit pattern.
3.17.1
1 implementation-defined value
unspecified value where each implementation documents how the
choice is made

3.17.3
1 unspecified value
valid value of the relevant type where this International Standard
^^^^^^^^^^^
imposes no requirements on which value is chosen in any instance

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Currently looking for a job in the European Union
Nov 14 '05 #52
ma*********@chello.at (Mark Piffer) wrote in message news:<41*************@news.chello.at>...
On Fri, 22 Oct 2004 19:43:50 +0200, Michael Mair
<Mi**********@invalid.invalid> wrote:


Mark Piffer wrote:
Michael Mair <Mi**********@invalid.invalid> wrote:

Dan Pop wrote:

>In <41***********@mindspring.com> pete <pf*****@mindspring.com> writes:
>
>
>>#define GetByte(x, u) \
>>((x & UCHAR_MAX << u * CHAR_BIT) >> u * CHAR_BIT)
>
>Please have the minimal decency not to expose newbies to badly implemented
>macros! Both x and u MUST be protected by parentheses in the expression.
>
>Besides, you have chosen the worst algorithm.

I could bet that the macro will invoke UB if sizeof long > sizeof int,
and also for invokations with u = sizeof int - 1 on most
implementations. But then again, I'm used to being totally wrong about
the simplest of C's rules, so it could be totally the other way
'round.
Umh, are you referring to the given macro or the function/macro I was
describing?

The macro 20 lines above which I quoted.
The macro at hand will give you not more problems if
sizeof long > sizeof int.
What sizeof int - 1 has to do with it, I am not sure at all.

Let us, for a moment, assume that we do not use the macro for negative
x and have inserted the parentheses. UCHAR_MAX << u*CHAR_BIT will not
have overlapping non-zero bits with x if u >= sizeof x. As
UCHAR_MAX << u*CHAR_BIT is considered unsigned and a multiple of

Why is it considered unsigned? I can't find any indication for it
being unsigned.
exp2(u*CHAR_BIT), it is effectively 0 if we shift "out of" the largest
unsigned type. Now we consider the case u == sizeof x - 1.
What can go wrong? Assume CHAR_BIT==8, sizeof x==2, x=(T*2<<12) +
(U*2<<8) + (V*2<<4) + W, written symbolically as 0xTUVW:
0xff << 1*8 --> 0xff00
0xTUVW & 0xff00 --> 0xTU00
0xTU00 >> 1*8 -->0x$$TU. We assumed nonnegative x -->0xTU
If x was negative, we also could have non-zero nibbles instead
of the $ signs. However, this is only unspecified, not undefined.

Maybe you want to elaborate where you think the UB creeps in.


[guess mode]
Lets assume an architecture where sizeof long == 4 and sizeof int ==
2. If you want to extract byte #2 (the byte starting at
2^(2*CHAR_BIT)) of the long argument,

[Edit: I assume an unsigned long argument given as macro parameter
'x'] your expression will try to
shift the signed integer constant UCHAR_MAX left 2*CHAR_BIT, which is
equal to the width of int, which is UB following 6.5.7/3.
OTOH, if you have sizeof long == sizeof int and both > 1 and want to
extract the highest byte (i.e. sizeof int - 1), you invoke UB because
you shift a positive signed integer so many places left that it can't
be represented in an int, which will cause UB following 6.5.7/4 (last
sentence).
[/guess mode]

Where do I err?

Mark


Sorry to bump this post again, but I didn't get a definitive answer
and I am really interested if my conclusions about the macro
#define GetByte(x, u)\
((x & UCHAR_MAX << u * CHAR_BIT) >> u * CHAR_BIT)
are wrong.

Mark
Nov 14 '05 #53
so************@yahoo.com (Mark Piffer) writes:
ma*********@chello.at (Mark Piffer) wrote in message news:<41*************@news.chello.at>...


[SNIP, SNIP, SNIP!]
[guess mode]
Lets assume an architecture where sizeof long == 4 and sizeof int ==
2. If you want to extract byte #2 (the byte starting at
2^(2*CHAR_BIT)) of the long argument,

[Edit: I assume an unsigned long argument given as macro parameter
'x']
your expression will try to
shift the signed integer constant UCHAR_MAX left 2*CHAR_BIT, which is
equal to the width of int, which is UB following 6.5.7/3.
OTOH, if you have sizeof long == sizeof int and both > 1 and want to
extract the highest byte (i.e. sizeof int - 1), you invoke UB because
you shift a positive signed integer so many places left that it can't
be represented in an int, which will cause UB following 6.5.7/4 (last
sentence).
[/guess mode]

Where do I err?


Sorry to bump this post again, but I didn't get a definitive answer
and I am really interested if my conclusions about the macro
#define GetByte(x, u)\
((x & UCHAR_MAX << u * CHAR_BIT) >> u * CHAR_BIT)
are wrong.


I believe the answer is, it depends on the definition of UCHAR_MAX.
If UCHAR_MAX is defined

#define UCHAR_MAX (255)

or

#define UCHAR_MAX ((int) 255)

or

#define UCHAR_MAX ((unsigned char) 255)

then the conclusions above are correct (in the last case because of
the ANSI "value preserving rule" for promotions, and assuming that
sizeof(int) > sizeof(char) is true). If UCHAR_MAX is defined

#define UCHAR_MAX (255U)

then the conclusion about the case when sizeof(long) > sizeof(int) is
right but the other conclusion is wrong. If UCHAR_MAX is defined

#define UCHAR_MAX (255UL)

then both conclusions are wrong.

Reading 5.2.4.2.1 p1, the type of UCHAR_MAX is the same as an unsigned
char "converted according to the integer promotion rules", which is
like the first two cases above.

Hence, I believe your conclusions are correct.
Nov 14 '05 #54

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

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.