casting from int to byte problem

B

buu

it looks like I have a strange problem.
I have a small class with several byte 'properties'

and I put a values into them from int values casting them to byte..
but for some values (like 143), casting result (with (byte)) is -113???
it's the same with 147 casted to -109...
and it should be a byte value (means, there should be no negative values)..

value is lowered for 256
why?

did I missed something?
 
P

Patricia Shanahan

buu said:
it looks like I have a strange problem.
I have a small class with several byte 'properties'

and I put a values into them from int values casting them to byte..
but for some values (like 143), casting result (with (byte)) is -113???
it's the same with 147 casted to -109...
and it should be a byte value (means, there should be no negative values)..

value is lowered for 256
why?

did I missed something?

You missed the fact that Java byte is a signed data type, value range
-128 through +127.

Is there a particular reason for using byte, rather than a wider data
type, such as int, whose value range includes 143 and 147?

Patricia
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

buu said:
it looks like I have a strange problem.
I have a small class with several byte 'properties'

and I put a values into them from int values casting them to byte..
but for some values (like 143), casting result (with (byte)) is -113???
it's the same with 147 casted to -109...
and it should be a byte value (means, there should be no negative values)..

value is lowered for 256
why?

did I missed something?

The valid range for a byte in Java is -128 to 127.

Arne
 
H

Hunter Gratzner

it looks like I have a strange problem.
I have a small class with several byte 'properties'

and I put a values into them from int values casting them to byte..
but for some values (like 143), casting result (with (byte)) is -113???

Get a Java book. Bytes in Java are signed.
 
M

Mike Schilling

Hunter Gratzner said:
Get a Java book. Bytes in Java are signed.

Which was, by the way, a bad idea.. I've never seen a program that wants to
do signed arithmetic on bytes. I've seen lots that assemble bytes into
chars and ints by shifting and or-ing, which would be much simpler and more
reliable if the damned things didn't sign-extend.
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

Mike said:
Which was, by the way, a bad idea.. I've never seen a program that wants to
do signed arithmetic on bytes. I've seen lots that assemble bytes into
chars and ints by shifting and or-ing, which would be much simpler and more
reliable if the damned things didn't sign-extend.

C# got that one right: int, uint, byte and sbyte.

Arne
 
C

Curt Welch

Mike Schilling said:
Which was, by the way, a bad idea.. I've never seen a program that wants
to do signed arithmetic on bytes. I've seen lots that assemble bytes
into chars and ints by shifting and or-ing, which would be much simpler
and more reliable if the damned things didn't sign-extend.

Yeah, signed bytes are stupid.

I don't know the actual history of what happened in Java, but I assume Java
just copied the C and C++ convention of chars being signed. The reason
bytes are signed in C is because of the PDP-11. When you did a byte move
into a register (registers were all 16 bits) it was sign extended by
default. There was no way to do a byte move to a register without the sign
extension happening and there were no ways to reference the high and low
bytes of the register as if they were separate byte registers. All you
could do was a byte-move from a memory location to one of the general 16
bit registers and you got the sign extension whether you wanted it or not.
If you wanted to undo the sign extension, you just had to zero out the high
order bits with a bit clear instruction.

Given the limited complexity of the computers in those days (very limited
sized instruction sets) you can see why the designers of the PDP-11 might
have chosen it to work that way. They couldn't justify having both signed,
and unsigned, byte move instructions, so they had to pick one behavior for
the byte move. It was a 16 bit machine, with byte addressable memory. All
the registers were 16 bits (including the program counter and stack
pointer). If you did a byte move to the register, and performed math on it
(16 bit), and did a byte move back to memory, or to an IO device, what
happened in the high order 8 bits wasn't important. It didn't matter if it
was sign extended or not. In those days, use of 8 bit signed ints was more
common because of the size of machines (64K of memory was possible) - today
we have so much memory we would never bother to use a signed 8 bit variable
just to save memory - we use signed 32 variables even when all we do is
count from 1 to 10. The design trade off was whether it was better to make
the byte move signed or unsigned. If unsigned, the programmer would have
to use two more instructions to do the sign extend (a test, and a bit set).
But if the hardware did the sign extend by default, and the programmer
didn't want it, all they would have to do is add an unconditional bit
clear. So, given the fact that when doing 8 bit operations, it made no
difference which way it worked, and when doing 8 bit to 16 bit conversion,
one default required 2 extra instructions to do the inverse, and the other
default only required 1 extra instruction, they picked the default that
made the inverse easier.

If C had made chars unsigned by default, it would have ended up generating
a lot of extra code to constantly undo the sign extension every time a char
was returned from a function since all function returns were promoted to
ints in those days. So C simply followed the convention of the very
limited PDP-11 hardware of those early days.

So now, we have it in Java, even though it really makes no sense at all in
our modern environment to be doing it - except for the advantage of
backward compatibility (which is important).
 
M

Mike Schilling

Arne Vajhøj said:
C# got that one right: int, uint, byte and sbyte.

With int (signed) and byte (unsigned) being the ones commonly used, yes,
they did.
 
N

nebulous99

I don't know the actual history of what happened in Java, but I assume Java
just copied the C and C++ convention of chars being signed.

ISTR char signedness actually being mentioned as implementation-
dependent somewhere.
The reason
bytes are signed in C is because of the PDP-11. When you did a byte move
into a register (registers were all 16 bits) it was sign extended by
default. There was no way to do a byte move to a register without the sign
extension happening and there were no ways to reference the high and low
bytes of the register as if they were separate byte registers. All you
could do was a byte-move from a memory location to one of the general 16
bit registers and you got the sign extension whether you wanted it or not.
If you wanted to undo the sign extension, you just had to zero out the high
order bits with a bit clear instruction.

Given the limited complexity of the computers in those days (very limited
sized instruction sets) you can see why the designers of the PDP-11 might
have chosen it to work that way.

I have something of a background in 6502/6510 assembly, and it used
signed bytes in conditional-branch instructions as arguments. So it
could only jump up to 128 back or 127 forward. If you wanted more you
needed to conditional-branch to a JMP instruction.
So, given the fact that when doing 8 bit operations, it made no
difference which way it worked, and when doing 8 bit to 16 bit conversion,
one default required 2 extra instructions to do the inverse, and the other
default only required 1 extra instruction, they picked the default that
made the inverse easier.

ITYM "obverse"; inverse has a narrower meaning.
 
S

Stefan Ram

bytes are signed in C

ISO/IEC 9899:1999 (E), 6.2.5, #15, Sentence 2:

»The implementation shall define char
to have the same range, representation,
and behavior as either signed char
or unsigned char.«
 
L

Lew

ITYM "obverse"; inverse has a narrower meaning.

"Obverse" means either "front" / "facing" or "corresponding". It's most
common use is in numismatics. It is unlikely that's what Curt meant, as I
read his post.
 
A

Andreas Leitgeb

Lew said:
"Obverse" means either "front" / "facing" or "corresponding". It's most
common use is in numismatics. It is unlikely that's what Curt meant, as I
read his post.

Don't tell us you're calling our twisted nebulous a liar! Don't you dare ... ;-)
 
L

Lew

Andreas said:
Don't tell us you're calling our twisted nebulous a liar! Don't you dare ... ;-)

Please, I'm doing nothing of the sort.

I am simply expressing my interpretation of Curt's message. Interpretation is
by nature subjective, albeit rooted in reality. It is certainly possible for
me to interpret Curt's message differently from nebulous without in any way
calling anyone a liar, or even necessarily making them wrong, since I might
be. (Of course, I'm not in this case.)

I just don't think Curt meant "obverse",
<http://en.wiktionary.org/wiki/obverse>,
since it doesn't fit the argument that he was making. I think I know what he
means by "inverse". It's mathematical, as in, "Expanding from 8 to 16 bits is
the inverse of collapsing from 16 to 8 bits." In that sense it makes sense,
at least to me.
 
C

Curt Welch

Lew said:
Please, I'm doing nothing of the sort.

I am simply expressing my interpretation of Curt's message.
Interpretation is by nature subjective, albeit rooted in reality. It is
certainly possible for me to interpret Curt's message differently from
nebulous without in any way calling anyone a liar, or even necessarily
making them wrong, since I might be. (Of course, I'm not in this case.)

I just don't think Curt meant "obverse",
<http://en.wiktionary.org/wiki/obverse>,
since it doesn't fit the argument that he was making. I think I know
what he means by "inverse". It's mathematical, as in, "Expanding from 8
to 16 bits is the inverse of collapsing from 16 to 8 bits." In that
sense it makes sense, at least to me.

I guess I should be more careful with my word usage. :)

I don't know if "obverse" is better or worse than "inverse" in what I wrote
but I also don't really care. I was just making the point that the
designers of the PDP-11 had to pick between two different behavior options
(signed or unsigned) when moving a byte to a 16 bit register and I tried to
show there were some rational reasons for picking signed behavior instead
of picking unsigned behavior. I just thought some people in the group
might not know this part of the history of signed bytes and might like to
know about it.
 
M

Mike Schilling

ISTR char signedness actually being mentioned as implementation-
dependent somewhere.

You are correct. Both C and C++ have three distinct types:

char
unsigned char
signed char

where "char" must act the same as one of the other two, but it's
implementation-dependent which one that is..

As Curt goes on to explain, bytes were treated as signed in PDP-11 (and
later VAX) machine language. Since these were for many years the most
common C (and especially Unix/C) platforms [1], it became common to think
of C chars as signed. I have no idea how influential this was on Java's
byte type.

1. One of the popular mantras for teaching portable C programming being "The
whole world isn't a VAX!".
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

Mike said:
As Curt goes on to explain, bytes were treated as signed in PDP-11 (and
later VAX) machine language. Since these were for many years the most
common C (and especially Unix/C) platforms [1], it became common to think
of C chars as signed. I have no idea how influential this was on Java's
byte type.

1. One of the popular mantras for teaching portable C programming being "The
whole world isn't a VAX!".

A lot of VAX'es did not have a good C compiler at all (VAX C 3.x on
VMS had a rather bad reputation).

Arne
 
M

Mike Schilling

Arne Vajhøj said:
Mike said:
As Curt goes on to explain, bytes were treated as signed in PDP-11 (and
later VAX) machine language. Since these were for many years the most
common C (and especially Unix/C) platforms [1], it became common to
think of C chars as signed. I have no idea how influential this was on
Java's byte type.

1. One of the popular mantras for teaching portable C programming being
"The whole world isn't a VAX!".

A lot of VAX'es did not have a good C compiler at all (VAX C 3.x on
VMS had a rather bad reputation).

Vaxen running BSD had a pretty good one :)

The problems with the VMS compilers, to my mind, are outgrowths of the fact
VMS and Unix are quite different. The Unix emulation (e.g. open(),
create(), fork()) didn't work very well, and the fact that VMS defaulted to
record-oriented rather than stream files made stdio difficult to use. Also,
while the VMS-specific features (globalref/globaldef, #include from text
libraries, etc.) worked fine, they looked decidedly odd to anyone who was a
C programmer rather than a VMS programmer.
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

Mike said:
Arne Vajhøj said:
Mike said:
As Curt goes on to explain, bytes were treated as signed in PDP-11 (and
later VAX) machine language. Since these were for many years the most
common C (and especially Unix/C) platforms [1], it became common to
think of C chars as signed. I have no idea how influential this was on
Java's byte type.

1. One of the popular mantras for teaching portable C programming being
"The whole world isn't a VAX!".
A lot of VAX'es did not have a good C compiler at all (VAX C 3.x on
VMS had a rather bad reputation).

Vaxen running BSD had a pretty good one :)

The problems with the VMS compilers, to my mind, are outgrowths of the fact
VMS and Unix are quite different. The Unix emulation (e.g. open(),
create(), fork()) didn't work very well, and the fact that VMS defaulted to
record-oriented rather than stream files made stdio difficult to use. Also,
while the VMS-specific features (globalref/globaldef, #include from text
libraries, etc.) worked fine, they looked decidedly odd to anyone who was a
C programmer rather than a VMS programmer.

I was a VMS programmer so they made perfectly sense to me.

No I am talking about bugs that require code to be compiled with
/NOOPT, not being ANSI compliant etc..

Arne
 

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,774
Messages
2,569,596
Members
45,129
Latest member
FastBurnketo
Top