Re: byte + byte -> int

Discussion in 'Java' started by Lew, Mar 20, 2009.

  1. Lew

    Lew Guest

    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
     
    Lew, Mar 20, 2009
    #1
    1. Advertising

  2. Lew

    Lew Guest

    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 <> 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
     
    Lew, Mar 20, 2009
    #2
    1. Advertising

  3. Lew

    blue indigo Guest

    On Fri, 20 Mar 2009 23:49:24 +0000, Thomas Pornin wrote:

    > According to Eric Sosman <>:
    >> 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
     
    blue indigo, Mar 21, 2009
    #3
  4. 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.
     
    Mike Schilling, Mar 21, 2009
    #4
  5. 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
     
    Joshua Cranmer, Mar 21, 2009
    #5
  6. Thomas Pornin wrote:
    > According to Eric Sosman <>:
    >> 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.)
     
    Mike Schilling, Mar 21, 2009
    #6
  7. 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
     
    Arne Vajhøj, Mar 21, 2009
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Schnoffos
    Replies:
    2
    Views:
    1,221
    Martien Verbruggen
    Jun 27, 2003
  2. Hal Styli
    Replies:
    14
    Views:
    1,646
    Old Wolf
    Jan 20, 2004
  3. arun
    Replies:
    8
    Views:
    457
    Dave Thompson
    Jul 31, 2006
  4. aling
    Replies:
    8
    Views:
    958
    Jim Langston
    Oct 20, 2005
  5. Replies:
    9
    Views:
    436
    James Kanze
    Apr 17, 2007
Loading...

Share This Page