Am I Crazy? V. simple math question.

E

Eric Sosman

MS said:
[...]
As far as my Java programming is concerned, I should be careful when
using real numbers and integers together, that the integers are
converted to reals, either done explicitly or by their position in the
evaluation order.

More to the point: You should use the kinds of numbers that
are suited to the calculation at hand. Sometimes these are
integers (of various sizes), sometimes these are reals (of two
precisions), sometimes these are things like BigInteger objects.
And sometimes a calculation needs to mix the effects of more than
one kind of arithmetic: for example, you might use floating-point
arithmetic to compute the 0.52617% monthly interest due on your
mortgage, but then use integer arithmetic to round the product
to a whole number of pennies.
Can you cast in Java --as you can in C-- like this,
which would allow the first formula to work?

double celsius = (double) 5 / (double) 9 * (fahrenheit - (double) 32);

Yes. It strikes me -- no insult intended -- that if you don't
know this sort of thing, you would do well to invest in a Java
textbook. Usenet is a poor channel for transmitting large amounts
of information in comprehensible form.
 
J

Joshua Cranmer

MS said:
double celsius = (double) 5 / (double) 9 * (fahrenheit - (double) 32);

Should be:
double celsius = ((double) 5)/((double) 9) * (fahrenheit - (double) 32);

Casting is right-associative, so this is what the compiler sees:
(double) (5 / (double) (9 * (fahreinheit - (double) (32) ) )

If you wonder why, it's because you want (double) (c.foo()) and not
((double)c).foo() generally.
 
J

Joshua Cranmer

Arne said:
I do not think so.

It is not a trivial thing to do on many processors including x86.

Arne

Are you sure? I'm pretty sure the x86 has an instruction to jump if the
overflow bit is set, but I'm not sure if multiplication sets the
overflow bit...
 
?

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

Joshua said:
Are you sure? I'm pretty sure the x86 has an instruction to jump if the
overflow bit is set, but I'm not sure if multiplication sets the
overflow bit...

I think it has.

But setting a test using that instruction in for all
integer arithmetic is not trivial.

The nice way of doing is to have a bit somewhere
and it it is set then overflow generates the exception.

Arne
 
T

Tom Hawtin

Joshua said:
Are you sure? I'm pretty sure the x86 has an instruction to jump if the
overflow bit is set, but I'm not sure if multiplication sets the
overflow bit...

IIRC, there's no easy way to check if a multiplication overflows, other
than actually calculating the extended value. (That's probably stated in
Hacker's Delight, but I don't think my copy is in this country.) If a
multiplication instruction sets the overflow flag, I don't think it'll
have anything particularly meaningful in the result.

Tom Hawtin
 
S

Stefan Ram

Joshua Cranmer said:
Casting is right-associative, so this is what the compiler sees:
(double) (5 / (double) (9 * (fahreinheit - (double) (32) ) )
If you wonder why, it's because you want (double) (c.foo()) and not
((double)c).foo() generally.

It is perfectly legitimate to be ignorant of Java operators or
the notion of associativity, but then you should not write
unfounded assertions about those topics. Instead you might
read about them, ask about them, or just do something
completely different, such as watching a movie.
 
P

Patricia Shanahan

Joshua said:
Should be:
double celsius = ((double) 5)/((double) 9) * (fahrenheit - (double) 32);

Casting is right-associative, so this is what the compiler sees:
(double) (5 / (double) (9 * (fahreinheit - (double) (32) ) )


Huh? That is not what the JLS says. See
http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.16

Casts operate on unary expressions, and
5 / (double) (9 * (fahreinheit - (double) (32) )
is a multiplicative expression, so it could not be the operand of cast.

If you were right, (double)5/9 would be parsed as (double)(9/5), with
result 1.0. This program:

public class CastTest {
public static void main(String[] args) {
System.out.println((double)9/5);
}
}

prints "1.8". (double)9 is a double expression, so arithmetic
promotion is applied, converting the 5 to double, followed by a double
divide.
>
> If you wonder why, it's because you want (double) (c.foo()) and not
> ((double)c).foo() generally.

The grouping implied by c.foo() has very high effective precedence. That
has nothing at all to do with the relative precedence of cast and divide.

Patricia
 
Z

Z.

Mark said:
I think it's strange Java doesn't provide for any kind of overflow
error. Anyone know if it's possible to get Java to throw an overflow
for calculations like this?

Me, too. It seems there are exceptions for everything else, so why not
integer overflow?
 
?

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

Z. said:
Me, too. It seems there are exceptions for everything else, so why not
integer overflow?

As I tried to explain earlier then at many platforms it is problematic
to implement.

Arne
 
S

Stefan Ram

Z. said:
why not integer overflow?

What would be an example (an application), where you need to
use an integral numeric type with integer arithmetics and need
to detect overflow, and which action would be appropriate in
this example for the case of non-overflow and overflow,
respectively?
 
P

Patricia Shanahan

Stefan said:
What would be an example (an application), where you need to
use an integral numeric type with integer arithmetics and need
to detect overflow, and which action would be appropriate in
this example for the case of non-overflow and overflow,
respectively?

The example would be any Java program that uses int arithmetic.

In the non-overflow case the program should continue executing.

An overflow would indicate a serious programming error, and should be
handled the same way as NullPointerException. For almost all programs,
it should cause an abort with stack trace.

It may be too late to do int overflow in Java because there is no
separate signed and unsigned 32 bit int.

However, some sort of range-limited integer type should be possible on
any processor that supports Ada.

Patricia
 
C

Chris Uppal

Stefan said:
What would be an example (an application), where you need to
use an integral numeric type with integer arithmetics and need
to detect overflow,

Any application where the designer or coder has not considered the possibility
of arithmetic overflow.

Add in all the cases where the designer or coder /has/ considered the
possibility of arithmetic overflow and wishes to detect it, and I don't think
there are all that many valid arithmetic examples which don't fall into one
camp or the other.

and which action would be appropriate in
this example for the case of non-overflow and overflow,
respectively?

Not sure I'm addressing your question, but the correct (default) action in the
case of unexpected arithmetic overflow would be to abort the application (since
integer primitives don't have any equivalent of floating point's NaNs and
infinities).

Better, of course, not to allow overflow in the first place.

-- chris
 
?

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

Stefan said:
What would be an example (an application), where you need to
use an integral numeric type with integer arithmetics and need
to detect overflow, and which action would be appropriate in
this example for the case of non-overflow and overflow,
respectively?

If you Google you will find lots of request for this
functionality in C and C++.

I am sure there are plenty of Java programmers who would
prefer their program to crash instead of calculating
on garbage data (yes - it can in some cases be that they
want the current overflow handling, but in most cases
it is an error situation).

Arne
 
L

Luc The Perverse

Patricia Shanahan said:
An overflow would indicate a serious programming error, and should be
handled the same way as NullPointerException. For almost all programs,
it should cause an abort with stack trace.

You may want to include that an overflow would typically indicate a serious
error.

I have seen deliberate uses of overflow.
 
K

Karl Uppiano

Luc The Perverse said:
You may want to include that an overflow would typically indicate a
serious error.

I have seen deliberate uses of overflow.

Yup, given that ints are often used for bit twiddling, I think we would be
handling more overflow exceptions than we might like otherwise. If you want
real numbers (in the mathematical sense), use the IEEE floating point types.
 
P

Patricia Shanahan

Karl said:
Yup, given that ints are often used for bit twiddling, I think we would be
handling more overflow exceptions than we might like otherwise. If you want
real numbers (in the mathematical sense), use the IEEE floating point types.

One of the worst mistakes in the initial design of Fortran was calling
floating point numbers "real". It has caused confusion for over 50 years.

Every floating point number is a rational, and a rational with a
denominator that is an integer power of a predetermined constant at
that. There is no general way to represent the mathematical reals
in computer arithmetic. There cannot be, because there are more real
numbers in any non-empty interval than there are finite length strings.

IEEE floating point arithmetic has its own rules that commonly result in
different answers from the same operation done in real number
arithmetic. It lacks several of the nice properties of real number
arithmetic, for example:

Associativity: In real number arithmetic, a+(b+c) == (a+b)+c. That is
often false in floating point arithmetic.

Reversibility of some operations: (a*b)/b is not necessarily equal to a,
even if b is non-zero.

In any case, range limited integer arithmetic and floating point
arithmetic are very different things, solving different problems.

Patricia
 
E

Eric Sosman

Karl said:
Yup, given that ints are often used for bit twiddling, I think we would be
handling more overflow exceptions than we might like otherwise. If you want
real numbers (in the mathematical sense), use the IEEE floating point types.

This was (I think) what Patricia Shanahan alluded to when
she mentioned Java's lack of unsigned integer arithmetic. The
language would be pleasanter, IMHO, if "plain" integer arithmetic
threw ArithmeticException on overflow. For occasions requiring
a "bag of bits" instead of a number you would use another flavor
of integer featuring silent wrap-around. (Whether this flavor
should be "unsigned" a la C or "signed but modular" would be a
matter for debate, were the debate not already over.)

Efficient trapping of overflows is neither rocket science nor
new art. In the late 1960's I wrote extensively for IBM S/360
machines (ancestors of today's zSeries), and their ordinary mode
of operation generated traps for integer overflow. Nowadays I
imagine that the vogue in machine design would avoid "modes" and
would instead offer variants of the instructions: You would have
a plain ADD instruction that trapped on overflow and an ADDNT
instruction that ignored it but was otherwise identical. (C.f.
the use of different flavors of floating-point instructions to
implement different rounding "modes.")

Anyway: Water under the bridge, horse non-proximal to the
barn, "It might have been," the moving finger moves on.
 
L

Lew

Eric said:
Anyway: Water under the bridge, horse non-proximal to the
barn, "It might have been," the moving finger moves on.

A preferred programming environment is a jug of wine and a loaf of bread.
 
P

Patricia Shanahan

Eric said:
This was (I think) what Patricia Shanahan alluded to when
she mentioned Java's lack of unsigned integer arithmetic. The
language would be pleasanter, IMHO, if "plain" integer arithmetic
threw ArithmeticException on overflow. For occasions requiring
a "bag of bits" instead of a number you would use another flavor
of integer featuring silent wrap-around. (Whether this flavor
should be "unsigned" a la C or "signed but modular" would be a
matter for debate, were the debate not already over.)

Efficient trapping of overflows is neither rocket science nor
new art. In the late 1960's I wrote extensively for IBM S/360
machines (ancestors of today's zSeries), and their ordinary mode
of operation generated traps for integer overflow. Nowadays I
imagine that the vogue in machine design would avoid "modes" and
would instead offer variants of the instructions: You would have
a plain ADD instruction that trapped on overflow and an ADDNT
instruction that ignored it but was otherwise identical. (C.f.
the use of different flavors of floating-point instructions to
implement different rounding "modes.")

Anyway: Water under the bridge, horse non-proximal to the
barn, "It might have been," the moving finger moves on.

Potentially, there is the possibility of building a new barn, with lock
on door from the start, right where the horse is now.

How about adding a new type, freely convertible to int and usable in
every context that requires int, that represents a checked overflow
signed int? The current int would remain as a "signed but modular"
integer type.

Patricia
 

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

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,565
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top