Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > Re: byte + byte -> int

Reply
Thread Tools

Re: byte + byte -> int

 
 
Lew
Guest
Posts: n/a
 
      03-20-2009
Eric Sosman wrote:
> * * *This feature of the definition of Java is a little bit
> arbitrary, to be sure. *For example, in
>
> * * * * int x = Integer.MIN_VALUE + 10;
> * * * * int y = Integer.MIN_VALUE + 20;
> * * * * int z = x + y;
>
> ... the arguments in the preceding paragraph still apply, with
> the obvious changes. *The compiler doesn't know that x and y are
> constant, the compiler can't be sure that their mathematical sum
> is in range for an int (in fact, it isn't), but allows the line
> anyhow. *Java doesn't complain about the loss of precision when


That's because Java doesn't see this as a loss of precision but as an
overflow, and the rules specifically address overflow.

> an int (or long) calculation wraps around, but whines loudly when
> it thinks precision might be lost in a down-conversion. *It's not
> consistent, it may not be defensible -- but That's The Way It Is.


It's both consistent and defensible. The operation of integer
addition always results in a 32-bit value, so there's no loss of
precision when you assign the result to an integer.

--
Lew
 
Reply With Quote
 
 
 
 
Lew
Guest
Posts: n/a
 
      03-20-2009
Lew wrote:
>> It's both consistent and defensible. *The operation of integer
>> addition always results in a 32-bit value, so there's no loss of
>> precision when you assign the result to an integer.

>


Eric Sosman <(E-Mail Removed)> wrote:
> * * *That's just defining the problem away, not solving it or even
> avoiding it. *Java adds a couple numbers and delivers an answer,


I'm not saying it isn't a problem, I'm saying it's not a loss-of-
precision problem.

As for "just defining the problem away", the language is exactly what
it's defined to be. Its operations are exactly what they are defined
to be. Whether you see integer overflow as a problem or not, the
language is never going to be what it's not defined to be.

Java delivers exactly the result it promises to deliver, in exactly
the precision of the operands.

> an answer that would earn a failing mark on a third-grade arithmetic
> quiz, and proudly boasts "That's not a bug; that's a feature!" *It
> crosses my mind that the JLS is akin to Newspeak.
>


Java is not attempting to pass third-grade arithmetic. And it isn't a
bug; it is a feature. It just happens to be a feature you personally
want implemented differently.

> * * *The old steam-powered computers I shovelled coal for as a lad[*]
> had one nice feature that our sleek fast modern machines have lost:


If the machines have lost it, it makes it "blasted inconvenient" for
Java to enforce it.

> They'd trap when a computation overflowed. *Blasted inconvenient now


And if Java were running on such a machine, it would have to ignore
that trap.

> and then, but a great safety feature for programs that would otherwise
> have produced results that were wrong, R-O-N-G, wrong.
>


The results of a Java addition are only wrong if they differ from what
the JLS promises.

You can avoid the whole "problem" by using BigInteger.
<http://java.sun.com/javase/6/docs/api/java/math/BigInteger.html>
If you use int, you have to put up with its range limitation. An int
can only hold 32 bits; any attempt to go beyond that will fail one way
or another. Too bad. Also too bad that it fails in a way different
from how you wish it would.

--
Lew
 
Reply With Quote
 
 
 
 
blue indigo
Guest
Posts: n/a
 
      03-21-2009
On Fri, 20 Mar 2009 23:49:24 +0000, Thomas Pornin wrote:

> According to Eric Sosman <(E-Mail Removed)>:
>> That's just defining the problem away, not solving it or even
>> avoiding it. Java adds a couple numbers and delivers an answer,
>> an answer that would earn a failing mark on a third-grade arithmetic
>> quiz, and proudly boasts "That's not a bug; that's a feature!" It
>> crosses my mind that the JLS is akin to Newspeak.

>
> The feature here is that Java expressions compute things somewhat
> similarly to what happens with C on the most common architectures (those
> on which Java runs, at least).


Mostly I have no gripes with Java's behavior in this area, but for the
"byte" type I make an exception. It really should have been unsigned, with
pure byte arithmetic always having type byte, so explicitly an unsigned
modulo-256 arithmetic. This better corresponds with how bytes are actually
used in working with low-level bit-twiddling and IO.

Well, being able to add-with-carry would be useful, so perhaps it should
still have produced wider intermediate results, but without any casts
needed to assign those results back to a byte again.

They also mishandled long -- it really shouldn't be necessary to stick an
extra L on the end of a long literal; literal integers should have been
treated as longs to begin with, and if they happened to fit in a narrower
type, been assignable to them without complaint. Instead, this is true for
int but you need to specify that a long literal is a long literal. That's
half-assed.

Warnings when constant expressions lose precision or get truncated would
also have been nice. Things like double d = Long.MAX_VALUE; and int i =
Integer.MAX_VALUE + 1; and so forth.

> Another, unrelated point, is that having integer types with automatic
> reduction modulo 2^32 is quite convenient when implementing algorithms
> which are defined in such operations. Many cryptographic algorithms
> (mostly symmetric encryption, MAC and hashing) are defined thus. But
> providing arithmetic modulo 2^32, and making it the default way of
> handling everything which looks like an integer (e.g. array indices),
> are two distinct things.


They probably considered that people might not want to have
potentially-slow bignum math suddenly cropping up unexpectedly, so decided
that bignums should only be used if explicitly called for by the
programmer. For which purpose they supplied BigInteger and BigDecimal.
Furthermore, the programmer has freedom to use some other kind of bignum
implementation instead of being stuck with one choice specified by the
language.

The real problem here is that it's painful to do byte arithmetic of the
most usual kinds, such as to read jpeg headers or whatever, because of the
need to worry about >> vs. >>>, signedness, casting back down to byte here
and there, and other such nuisances that make the code more verbose.
Simple things like hi_nybble = my_byte >> 4; don't work, you need to use
(my_byte >> 4) & 0xf or maybe my_byte >>> 4.

Of course it's too late to change any of this now without breaking tons of
existing code.

--
blue indigo
UA Telecom since 1987
 
Reply With Quote
 
Mike Schilling
Guest
Posts: n/a
 
      03-21-2009
Eric Sosman wrote:
>
> The old steam-powered computers I shovelled coal for as a lad[*]


I used to work with disk drives that literally required oil changes.


 
Reply With Quote
 
Joshua Cranmer
Guest
Posts: n/a
 
      03-21-2009
blue indigo wrote:
> Mostly I have no gripes with Java's behavior in this area, but for the
> "byte" type I make an exception. It really should have been unsigned, with
> pure byte arithmetic always having type byte, so explicitly an unsigned
> modulo-256 arithmetic. This better corresponds with how bytes are actually
> used in working with low-level bit-twiddling and IO.


I think everyone will agree that making byte signed and not unsigned was
a really stupid decision.

About explicitly being modulo-256, I'm not entirely sure; I'm thinking
that most byte-level operations would essentially be ~, ^, &, and |,
although I seem to recall that those still require casting.

> They also mishandled long -- it really shouldn't be necessary to stick an
> extra L on the end of a long literal; literal integers should have been
> treated as longs to begin with, and if they happened to fit in a narrower
> type, been assignable to them without complaint. Instead, this is true for
> int but you need to specify that a long literal is a long literal. That's
> half-assed.


I'm not sure I agree with you that integer literals should be assumed to
be long (i.e., 1 is a long), but making a literal that's too large to be
an int a long might be helpful.

> Of course it's too late to change any of this now without breaking tons of
> existing code.


It would be extremely feasible to make a new signed byte type: the only
thing you need to do to the JVM is pick a new letter for signatures,
toss something for the anewarray opcode, and utilize & 0xff for the
int-to-signed byte opcode. The hardest part is the keyword.

--
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth
 
Reply With Quote
 
Mike Schilling
Guest
Posts: n/a
 
      03-21-2009
Thomas Pornin wrote:
> According to Eric Sosman <(E-Mail Removed)>:
>> That's just defining the problem away, not solving it or even
>> avoiding it. Java adds a couple numbers and delivers an answer,
>> an answer that would earn a failing mark on a third-grade arithmetic
>> quiz, and proudly boasts "That's not a bug; that's a feature!" It
>> crosses my mind that the JLS is akin to Newspeak.

>
> The feature here is that Java expressions compute things somewhat
> similarly to what happens with C on the most common architectures
> (those on which Java runs, at least). Besides, it does so with a
> strikingly similar syntax (almost identical operators, with the same
> precedence rules) and even the integer type names are close. This
> really looks like a plan to induce C programmers into switching to
> Java, and from what I have heard about the market status, it seems
> that the plan worked out great in that area.


It's a simplified C, though, since C had unsigneds integer types and Java
does not. Since unsigneds are must useful for being values that are rarely
modified or holders of bitfields, it would have been plausible to support
them with overflows allowed, while overflows on signed operations cause
exceptions. (I've whined enough in the past about the idiocy of signed
bytes that I won't repeat that here.)


 
Reply With Quote
 
Arne Vajhøj
Guest
Posts: n/a
 
      03-21-2009
Joshua Cranmer wrote:
> blue indigo wrote:
>> Mostly I have no gripes with Java's behavior in this area, but for the
>> "byte" type I make an exception. It really should have been unsigned,


> I think everyone will agree that making byte signed and not unsigned was
> a really stupid decision.


>> Of course it's too late to change any of this now without breaking
>> tons of
>> existing code.

>
> It would be extremely feasible to make a new signed byte type: the only
> thing you need to do to the JVM is pick a new letter for signatures,
> toss something for the anewarray opcode, and utilize & 0xff for the
> int-to-signed byte opcode. The hardest part is the keyword.


It could easily look like a kludge.

The right way (if practicality overrules purism) is:

long
int
short
signed byte

unsigned long
unsigned int
unsigned short
byte

(or use s and u prefix if we want to completely copy C#)

Arne

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
why is int a[0] not allowed, but int* a = new int[0] is? haijin.biz@gmail.com C++ 9 04-17-2007 09:01 AM
Difference between int i, j; and int i; int j; arun C Programming 8 07-31-2006 05:11 AM
int a[10]; int* p=(int*)((&a)+1); But why p isn't equal to ((&a)+1)? aling C++ 8 10-20-2005 02:42 PM
int main(int argc, char *argv[] ) vs int main(int argc, char **argv ) Hal Styli C Programming 14 01-20-2004 10:00 PM
dirty stuff: f(int,int) cast to f(struct{int,int}) Schnoffos C Programming 2 06-27-2003 03:13 AM



Advertisments