Why write putc(s.i16 & 0xff, fp);

J

Jorge Peixoto

Yes. Bitwise operators must be implemented as if operating on a binary
representation of the value, which would presumably not be a simple
operation on such a machine. Trinary machines (which have some
interesting advantages in certain contexts compared to binary machines)
would also be problematic.

So the code here *is* redundant! This call
putc((unsigned)((s.i32 >> 24) & 0xff), fp);

is equivalent to this

putc((unsigned)(s.i32 >> 24), fp);

In the second call, you cast to unsigned char, which means taking the
remainder modulo 256.
In the first call, you perform bitwise and with 0xff; you are telling
me that this will behave (for unsigned numbers, and this one is
unsigned) as if the number was represented in two's complement; so
this is equivalent to taking the remainder modulo 256.

And I think that even the cast to unsigned is unneeded. Can you get
different results from casting an integer to unsigned, then to
unsigned char, instead of directly casting from integer to unsigned
char?
 
J

Jorge Peixoto

So the code here *is* redundant! This call
putc((unsigned)((s.i32 >> 24) & 0xff), fp);

is equivalent to this

putc((unsigned)(s.i32 >> 24), fp);

In the second call, you cast to unsigned char, which means taking the
remainder modulo 256.
In the first call, you perform bitwise and with 0xff; you are telling
me that this will behave (for unsigned numbers, and this one is
unsigned) as if the number was represented in two's complement; so
this is equivalent to taking the remainder modulo 256.
Oh wait, he casts to unsigned *after* the and.

In any event, that FAQ answer needs clarification !
 
C

Charlie Gordon

James Kuyper said:
Jorge Peixoto wrote:
...

Yes. Bitwise operators must be implemented as if operating on a binary
representation of the value, which would presumably not be a simple
operation on such a machine. Trinary machines (which have some interesting
advantages in certain contexts compared to binary machines) would also be
problematic.

BCD representations would be problematic for integer types, but not for
floating point where they actually have interesting properties, especially
for financial and accounting applications.
 
C

Charlie Gordon

CBFalconer said:
You mistake the criticism. It is not about 1's vs 2's complement
vs sign-magnitude (which is easily handled by dealing with values,
rather than bit pattern), but about the size of CHAR_BIT,
specifying the size of a byte on that machine.

But the OP did specify that chars are assumed to be 8 bit wide.
Indeed no one responded to his question: is masking by 0xff necessary if
chars are assumed to be 8 bit wide? The answer is no, masking is not
necessary in this case. But bear in mind that it would be if CHAR_BIT != 8
and, a lesser known fact, it would be necessary for passing the value to
ungetc instead of putc, as ungetc would refuse to unget the value EOF. Of
course at most one character can be pushed back into the stream.
 
C

Charlie Gordon

James Kuyper said:
That char should be assumed to be 8 bits is part of the design
specifications for this code, so that can't be the justification for the
&0xff.

That's the beauty of this code, it does not even assume char to be eight bit
wide. It is not fully portable to weird obsolete non 2's complement
architectures, but it does produce 4 octets on the stream even if CHAR_BIT
!= 8.

If CHAR_BIT == 8, the mask is not necessary.
 
C

CBFalconer

Jorge said:
So the code here *is* redundant! This call
putc((unsigned)((s.i32 >> 24) & 0xff), fp);
is equivalent to this
putc((unsigned)(s.i32 >> 24), fp);

No it isn't. What if a byte (or char) is larger than 8 bits?
 
A

Army1987

In the answer to question 12.42 of the C FAQ, we have this code:

putc((unsigned)((s.i32 >> 24) & 0xff), fp);
putc((unsigned)((s.i32 >> 16) & 0xff), fp);
putc((unsigned)((s.i32 >> 8) & 0xff), fp);
putc((unsigned)(s.i32 & 0xff), fp);


putc((s.i16 >> 8) & 0xff, fp);
putc(s.i16 & 0xff, fp);

Why the & 0xff ? The putc function casts its argument to an unsigned
char, so anything but the 8 lower bits is automatically discarded. And
the code already assumes the a char is 8 bits.

Well, suppose you have a 9-bit machine and you want to write a
file in a 8-bit format. The most reasonable thing to do is not to
use the most significant bit in each byte, i.e. only using bytes
from 0000 to 0377. Now, suppose that you must read from such a
file. You could simply assume that the most significant bit is
never set, but could also discard it anyway, simply ignoring it.
This way the code wouldn't break if, er..., alpha particles set
the most significant bit of a byte.
 
A

Army1987

James Kuyper said:
Jorge said:
So a machine that uses BCD would have to do emulation to be the target
of a C implementation?
Yes. [...]
BCD representations would be problematic for integer types, but not for
floating point where they actually have interesting properties, especially
for financial and accounting applications.
Indeed, the standard doesn't require FLT_RADIX to be a power of 2.
 
K

Keith Thompson

Army1987 said:
On Fri, 26 Oct 2007 12:30:16 -0700, Jorge Peixoto wrote: [...]
Well, suppose you have a 9-bit machine and you want to write a
file in a 8-bit format.
[...]

I don't think there's enough information to determine the correct way
to do that. Transferring such a file from a 9-bit system to an 8-bit
system has to involve some kind of conversion, but we don't know
*what* kind of conversion. It could drop the high-order bit, losing
information, or it could just copy the bits, mapping 8 9-bit bytes to
9 8-bit bytes, or it could write each 9-bit byte to two 8-bit bytes.

If you want portability, write plain text (assuming consistent
character sets or well-defined translation).
 

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

Similar Threads


Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top