Division by zero: float vs. int

T

Thomas G. Marshall

Thomas G. Marshall coughed up:
John C. Bollinger coughed up:


I disagree, but I understand this point.

Perhaps consider this code:

double pi_1 = computePIoneWay();
double pi_2 = computePIanotherWay();
if (pi_1 == p1_2)
{
//we know mechanisms are the same...

Ah, wait. Perhaps I should make this comment "we know that the two
mechanisms produce the same result". Hmmm....

}

vs.

double pi_1 = computePIoneWay();
double pi_2 = computePIanotherWay();
if ((pi_1 == p1_2) ||
(isNaN(pi_1) && isNaN(pi_2)))
{
//we know mechanisms are the same...
}

{shrug}

--
Iamamanofconstantsorrow,I'veseentroubleallmydays.Ibidfarewelltoold
Kentucky,TheplacewhereIwasbornandraised.ForsixlongyearsI'vebeenin
trouble,NopleasureshereonearthIfound.ForinthisworldI'mboundtoramble,
Ihavenofriendstohelpmenow....MaybeyourfriendsthinkI'mjustastrangerMyface,
you'llneverseenomore.ButthereisonepromisethatisgivenI'llmeetyouonGod's
goldenshore.
 
T

Tom McGlynn

Thomas said:
Thomas G. Marshall coughed up:



Ah, wait. Perhaps I should make this comment "we know that the two
mechanisms produce the same result". Hmmm....

As you may be realizing you've give an example of
why NaN should not compare equal. If we have two
ways of computing something and we want to do a
check with a == b, then we want this to fail
if we've somehow used undefined mathematics
that has given us an undefined result.

One area where I think the discussion has
been confused is that the origin of this behavior
is not that we don't want results that are really
different to compare equal... That happens all the
time with real numbers. Inf's compare equal,
e.g., 1.e300/1.e-300 == 10.e300/1.e-300, so
I don't think arguments like
sqrt(-1) != sqrt(-10)
in complex arithmetic have anything to do with why
NaN's don't compare equal.

NaN's are supposed to be undefined. Suggesting
that they are equal to anything implies some minimal
definition. JM.02$

Regards,
Tom McGlynn
 
T

Tor Iver Wilhelmsen [TeamB]

Dimitri Maziuk said:
Think again. getString() would return null *if* the standard said so.

Hm, it actually does. "if the value is SQL NULL, the value returned is
null". My bad. (All the other non-primitive getters do the same btw.)
The reason it doesn't is integers (and booleans, but those are
usually integers under the hood anyway) -- getInt() will always
return a valid integer because there ain't no such thing as invalid
one.

By your initial logic, getFloat() and getDouble() should return NaN,
but they don't. They, too, return 0, so the idea of using NaN or
equivalent is not shared by the JDBC authors.
"Not found" is not an error.

Using the return value to indicate errors - which you were talking
about - is a hack. If it's a documented and expected return value it's
not an error.
When you have a "common" (as opposed to "exceptional") error
condition

"Common" errors aren't really errors but alternative results. Yes,
signed integer return values cannot necessarily have values indicating
such alternative results - that's when you need to rethink what the
method does, or what it returns.
Huh? Null objects are actually null pointers: unsigned integers
pointing to memory address 0x00.

Not necessarily in Java. It is a reference holding a value that can be
tested with the bytecode instructions ifnull and ifnotnull. Your
statement makes a lot of assumptions about the implementation. To
quote the spec: "The Java virtual machine specification does not
mandate a concrete value encoding null."
Where TF did you see database semantics here?

It was you who dragged in wasNull() as justification why integer
primitives needed a special value indicating an equivalent to "not a
number".
I suggest you re-read your Computer Organization 101 and Programming
Languages 102 lecture notes before discussing relative merits of
different binary representations in the future.

"Not a number" is a useful value for real numbers to represent a
result outside their domain. Integers have a totally different use
where binary efficiency is king, and have no need fo an equivalent,
despite your claims otherwise.
 
J

John C. Bollinger

Thomas said:
Perhaps consider this code:

double pi_1 = computePIoneWay();
double pi_2 = computePIanotherWay();
if (pi_1 == p1_2)
{
//we know mechanisms are the same...
}

vs.

double pi_1 = computePIoneWay();
double pi_2 = computePIanotherWay();
if ((pi_1 == p1_2) ||
(isNaN(pi_1) && isNaN(pi_2)))
{
//we know mechanisms are the same...
}

{shrug}

If you find yourself doing that sort of thing very much then I think you
are overanalyzing the problem. Computations that result in NaN involve
either buggy code or bad data; there is no sense in trying to continue a
computation after producing a NaN intermediate result. I would almost
always write the first code [if an exact floating-point comparison were
appropriate in the case in question], but if I was worried about NaN
then my solution would neither benefit from nor be hindered by any
particular behavior of == wrt NaN.

Obviously, YMMV.


John Bollinger
(e-mail address removed)
 
J

Joseph Daniel Zukiger

Mmmmm... Such an algorithm can be implemented

Do it. What type do you intend to use to implement it, however?

int is a type, not a class.
(sure why not ?!) but
its advantages will out weight the disadvantages ?

A class of SecureLong may well be useful, as a step between the raw
integer long type and the very convenient BigInteger.

Hmm. I don't see a static final BigInteger INF for the class
BigInteger, nor does it seem to inherit such a constant from Number.
especially since
generation of programmers where educated in the C/C++ way of thinking.
As Stefan Schulz has noted, many algorithms will break and a new way
of thinking must replace the old one. This is a very slow process that
could slow down Java adoption.
huh?

Basically, 'trusted ways' and legacy algorithms are the reason for
this difference.

What on earth are you talking about?
 
J

Joseph Daniel Zukiger

Thomas G. Marshall said:
...
I've often pondered on this for years. What is the advantage to disallowing

Double.Nan == Double.Nan

aside from the (IMO unimportant) fact that it might be possible for multiple
bit representations to be NaN?

What have you got against saying this:

if ( A == B || ( A.isNaN() && B.isNaN() ) )

That seems clear enough to me.
 
J

Joseph Daniel Zukiger

Eric Sosman said:
...
Oddly enough, the equals() method of Double doesn't
follow this convention, and can disagree with the ordinary
`==' operator:

Double d = new Double(Double.NaN);
System.out.println(d.doubleValue()
== d.doubleValue());
System.out.println(d.equals(d));

prints "false" first (in accordance with IEEE convention)
but then prints "true"! The rationale (or rationalization)
is in the Javadoc for the method.

Bit patterns and pointers. So, if you had two NaN results from
expressions, you would not be surprised if the equals method returned
false, as well.
 
J

Joseph Daniel Zukiger

Thomas G. Marshall said:
Stefan Schulz coughed up:

Yes IMO. And

sqrt(-10) ==should== sqrt(-20)

But it seems that I'm likely to be the minority here...

So subclass Double.
 
J

Jacob

Razvan said:
I have noticed that the division by zero is handled differently for
integer and float types.

There is no reason they should be handled the same. Mathematically
the two types are as different as apples and oranges. Integers
model countable sets, while floats models continious phenomenon.

Integers are exact representations and dividing by 0 is not defined
=> Exception.

Floats are inexact representations where dividing by (integer) 0 is
impossible. You can divide by 0.0 which represent *some* floating
point number close to 0.0 but as it is inexact not necesserily 0.0.
=> Infinity
 
J

Joseph Daniel Zukiger

Chris Uppal said:
I say yes, i.e. I agree with Thomas.

The NaN result is saying "this calculation has no defined result", or -- if you
prefer to invoke the complex plane -- "this calculation has two values neither
of which can be approximated as floating point".

You really think you want to be able to say that one undefined result
is equal to another?

You can, of course, subclass Double, and provide your own definition
for a myEquals( Double value ) method using isNaN().
I prefer the first
formulation, not least because we are /not/ working in the complex plane[*].

Sure, but projection out of the complex plane seems to be the more
common (and more useful) semantic.
([*] Remember that the complex plane is not the only mathematical abstraction
that can be considered to embed the real line, and in which sqrt() is defined
for all real values)

And, of course, sqrt() is not the only function which returns NaN.
So the NaN result is a meta-level assertion shoe-horned into IEEE FP
representation.

Are you perhaps thinking that the range for floating point
calculations is merely an abbreviation of the set of Reals?
It would obviously be better -- in general -- to throw an
exception (perhaps a resumable one), but IEEE doesn't have language-specific
concepts like that (AFAIK), so all it can do is represent the meta-linguistic
assertion as a special reserved bit pattern.

Special set of bit patterns, no less.

However, you can do that, as well, with subclassing, IIRC.
There are only a handfull of such meta-lingistic concepts needed to cover the
failure modes of fp calculations. I presume that IEEE have done their
homework, and have covered all the bases, and so that all the meaningfull
assertions of the form "this calculation has no result because..." have been
given NaN values or similar.

Yes and no. What is that class? StrictMath?
Now, I don't see any semantic utility in distinguishing between "sqrt(-1) has
no defined result" and "sqrt(-18) has no defined value" -- in fact I think they
are the /same/ assertion

In what context do you want to be able to say

Double d = sqrt( -1 );
Double e = sqrt( -18 );
boolean b = d.equals( e );

and have b turn out to be true? If it's some context "Fuzzy", subclass
Double into a FuzzyDouble and don't argue with the spec on little
things like this.
(especially since IEEE NaN does not preserve the
expression that could not be computed

Well, if that's what you want, it would be a lot of work, but you
could make an OperandTrackingDouble subclass.
), i.e. I think that "this calculation has
no defined result" /should/ be treated as equal to "this calculation has no
defined result" -- indeed I'd say that it's /obvious/ that they should be
equal.

You work in a different context from me.
That isn't to say that I'd want to make all the different kinds of NaN equal.

There's a point to that, you know.
And it may be that that is the motivation behind making none of them equal, not
even to themselves.
yeaaaahz

Since Java has no clear concept of the different kinds of
NaN as first-class primitive values (e.g there are no float/double literals for
them).

??

Double is declared in java.lang, is it not?
Alternatively, it may be -- as a pragmatic matter -- that generations of
experience in "real" FP work by numerical programmers have found that the
semantically impure device of treating all NaNs as unequal results in simpler,
clearer, or faster expression of important caclulations, and that Java is just
following that. It sounds plausible to me, but I don't know (I'm /not/ a
numerical programmer -- I'm pleased to say ;-)

I might wonder if that is not obvious. Both the not being a numerical
programmer and the being pleased about it, I mean.

JouDanZuki
 
J

Joseph Daniel Zukiger

Thomas G. Marshall said:
Thomas G. Marshall coughed up:

Ah, wait. Perhaps I should make this comment "we know that the two
mechanisms produce the same result". Hmmm....

Good. You're thinking now. Keep thinking.

To me, the latter is clear and I can expect it to behave in a certain
way. The former looks like a lot of perl expressions. I can expect
what I want, but I'm going to have to test boundary cases and dig in
manuals before I'm going to have a lot of confidence in the result.

Fuzziness is useful if you know the specific kind of fuzziness and the
context. But perl is a really high level language. java.lang is a
rather low level package of classes, and you want the low level to be
stable.

If you want the fuzzier semantic, subclass.

JouDanZuki, hoping he's done with his recreational kiitzing for the
day.
 
T

Thomas G. Marshall

Joseph Daniel Zukiger coughed up:
"Thomas G. Marshall"


Good. You're thinking now. Keep thinking.


To me, the latter is clear and I can expect it to behave in a certain
way. The former looks like a lot of perl expressions. I can expect
what I want, but I'm going to have to test boundary cases and dig in
manuals before I'm going to have a lot of confidence in the result.

Fuzziness is useful if you know the specific kind of fuzziness and the
context. But perl is a really high level language. java.lang is a
rather low level package of classes, and you want the low level to be
stable.

If you want the fuzzier semantic, subclass.

subclass what?
 
T

Thomas G. Marshall

Joseph Daniel Zukiger coughed up:
You really think you want to be able to say that one undefined result
is equal to another?

You can, of course, subclass Double, and provide your own definition
for a myEquals( Double value ) method using isNaN().

Go try it and report back to us the compilation error you get. Double is
final.
 
J

Joseph Daniel Zukiger

I read your comment 5 times. I do not understand what you mean.
Both integers and floats have a finite number of bits.

Do you usually operate in the decimal or binary numeric base?

Conversion from decimal to binary base is just one example of where
precision is not maintained.

Maybe you're looking for java.math.BigDecimal?
 
B

Boudewijn Dijkstra

Razvan said:
"Boudewijn Dijkstra" <[email protected]> wrote in message

....with floating point numbers...

.... Whereas integers are always whole numbers.
I read your comment 5 times. I do not understand what you mean.
Both integers and floats have a finite number of bits.

OK, I wrote a little bit too compact.
 
E

Eric Sosman

Joseph said:
Bit patterns and pointers. So, if you had two NaN results from
expressions, you would not be surprised if the equals method returned
false, as well.

Actually, Double.equals() treats *all* NaNs as equal,
even if they have different bit patterns. The method is
defined in terms of Double.doubleToLongBits(), which yields
the "canonical" form 0x7ff8000000000000L for every NaN, no
matter what its actual bit pattern is.

There's another method, Double.doubleToRawLongBits(),
if you actually need to discriminate the bit patterns of
different NaNs -- but Double.equals() doesn't use it.
 
M

Michael Saunby

Jacob said:
There is no reason they should be handled the same. Mathematically
the two types are as different as apples and oranges. Integers
model countable sets, while floats models continious phenomenon.

Integers are exact representations and dividing by 0 is not defined
=> Exception.

Floats are inexact representations where dividing by (integer) 0 is
impossible. You can divide by 0.0 which represent *some* floating
point number close to 0.0 but as it is inexact not necesserily 0.0.
=> Infinity

Perhaps also worth noting that you can divide by infinity and get zero.
Unless of course you divide infinity by infinity and then you get NaN.

e.g.

1.0/0.0 => Infinity
1.0/(1.0/0.0) => 0
(1.0/0.0)/(1.0/0.0) => NaN


Not all languages/compilers will allow you to do this using constants, i.e.
the compiler may know that x/0.0 is division by zero, but it won't know
that y=0.0 ; x/y is division by zero, at least I've yet to encounter one
that does.

Michael Saunby
 
T

Thomas G. Marshall

Michael Saunby coughed up:

....[stomp]...
Perhaps also worth noting that you can divide by infinity and get
zero. Unless of course you divide infinity by infinity and then you
get NaN.

e.g.

1.0/0.0 => Infinity
1.0/(1.0/0.0) => 0

Did not even /dream/ of this. Wow.

(1.0/0.0)/(1.0/0.0) => NaN


Not all languages/compilers will allow you to do this using
constants, i.e. the compiler may know that x/0.0 is division by zero,
but it won't know that y=0.0 ; x/y is division by zero, at least
I've yet to encounter one that does.

It would need to verify everywhere that y isn't modified by another thread
between those two statements "accidentally".

In C that would probably be impossible in nearly all situations. In java,
it would require verifying that y was not accessed by anyone, anywhere, and
also not by reflection. "Eeeek" if it weren't private, and/or final.
 

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,763
Messages
2,569,563
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top