• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Jeanne Boyarsky
  • Devaka Cooray
  • Paul Clapham
Sheriffs:
  • Tim Cooke
  • Knute Snortum
  • Bear Bibeault
Saloon Keepers:
  • Ron McLeod
  • Tim Moores
  • Stephan van Hulst
  • Piet Souris
  • Ganesh Patekar
Bartenders:
  • Frits Walraven
  • Carey Brown
  • Tim Holloway

Floating Point Division

 
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
With floating point, if you divide a very small number by a positive integer greater than 1 you might end up with 0.0. This is known as underflow. Is there a way to catch this exception in Java?

Thanks,
Bob

 
Bartender
Posts: 5903
57
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
How do you know that it's 0.0? Do you have an example? Perhaps a 10 line program to demonstrate?
 
Bob Sherry
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Here is code that demostrates the issue:

 
Marshal
Posts: 24594
55
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There is no exception thrown, so no, there is no way to catch an exception in that case.

I see that the web is full of people who don't like that design feature of Java, but perhaps you could expand on why it's a problem for you.
 
Ranch Hand
Posts: 561
1
VI Editor Chrome Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

I see that the web is full of people who don't like that design feature of Java, but perhaps you could expand on why it's a problem for you.


Err, as an embedded engineer with 40 years experience this strikes me as exactly the wrong attitude to take.  In my domain I really want to know when I get underflow so I can deal with it.

In a lot of cases x = 0.0000000001 is a lot different than x = 0.0, especially when you might need to divide by x.

Then again, Java will never work in an embedded environment.  But still....

After this thread maybe we can get back to why we don't have unsigned bytes
 
Bob Sherry
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am working on a program that is computational intensive and in certain cases, I am getting wrong results. I believe it is due to a floating point underflow. I can and should test for the division to be 0.0. I am not doing that.

It seems to me, that in the modern era, programmers want to use try and catch. In this case, I will use an if. It really does not matter.

Bob
 
Carey Brown
Bartender
Posts: 5903
57
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Have no idea what the overhead of this might be in a computationally intensive app.
 
Paul Clapham
Marshal
Posts: 24594
55
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Jim Venolia wrote:

I see that the web is full of people who don't like that design feature of Java, but perhaps you could expand on why it's a problem for you.


Err, as an embedded engineer with 40 years experience this strikes me as exactly the wrong attitude to take.  In my domain I really want to know when I get underflow so I can deal with it.



Well, yeah, the people griping on the web are on your side. But I'm curious about what one would typically do when encountering FP underflow.
 
Marshal
Posts: 64654
225
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
But it is not only the Java® Language Specification that those people are disagreeing with in this context. It is thee whole context of floating‑point arithmetic as defined by IEEE 754.
Carey's solution misses out at least two corner cases, where b is (±)∞ and where either operand is NaN.
 
Carey Brown
Bartender
Posts: 5903
57
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I knew my example was incomplete and I should have mentioned that. I was trying to point out that any conditions that Java and IEEE don't handle you could write your self but with a (significant?) loss of performance. In addition, you'd have to re-write your formulas to make use of the new divide() method.

Regarding infinity and NaN, I specifically didn't include them because I assumed that underflow was the only condition that needed to be trapped and that the normal IEEE behaviors for infinity and NaN were acceptable. You could certainly trap for those as well if you'd like. The case I didn't bother to include that I felt is necessary is where 'a' is negative.

I also threw in the DEBUG constant because Bob may wish to run his app once looking for underflow cases, and then once that data was debugged and/or order of operations optimized, then set DEBUG to false and recompile with the assumption that the compiler would detect that the if() statement could never be true and eliminate the test from the executable code, thus restoring some or all of the original, non-method, divide performance. Also assuming that a JIT (just in time) run time environment would optimize out the call overhead as well.

Most math libraries go to great pains to re-arrange the order of operations to minimize the chance that an overflow or underflow would occur. A good reference book on this is "Numerical Recipes in C". Perhaps Bob's problems could be reduced or eliminated by similar analysis and optimization of the order of operations being performed. Incorporating a divide() method would serve to highlight cases where analysis and optimization could be applied in a more focused manner.
 
Jim Venolia
Ranch Hand
Posts: 561
1
VI Editor Chrome Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Paul Clapham wrote:Well, yeah, the people griping on the web are on your side. But I'm curious about what one would typically do when encountering FP underflow.


Depends on the system.  You could set the underflow to the smallest value possible to prevent divide by 0.

Another option would be to end a calculation.  If you're trying to minimize an error bar then underflow indicates you're done.
 
Ranch Foreman
Posts: 3267
19
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Personally, it's always annoyed me that Java doesn't have safer math operations by default.  Yes, I'm aware of the history of IEEE 754, and we're not going to change Java too fundamentally now.  But I would much prefer that by default, math operations should throw errors for overflow and underflow... and then there could be a way to enable a fast-but-less-safe mode for those who need it.  But frankly, most people don't need it, and I would prefer to make math errors easier to find by default.

But, given Java as it has been developed... note that since Java 1.8, java.util.Math has methods to handle exact operations for ints and longs, very similar to what Carey suggested, e.g.:

There's no divideExact() currently, mostly because the currect addExact(), subtractExact() and multiplyExact() methods only support integers, and thus only need to check for overflow, never underflow, and with integers you can never overflow from division.  I think it would be nice to have floating point equivalents for all these - though "exact" seems a poor term to use in any method name for floating point operations.  Perhaps something like "safe" instead?


An additional complication is that it's not clear whether other conditions like dividing by 0  or other overflow should be converted to an exception, or whether we can just continue to use values like POSITIVE_INFINITY and NAN, as per usual IEEE 754 rules.  Quite possibly that's why they haven't already added such methods.  I would also think it's much rarer to find situations where floating-point underflow occurs, compared to integer overflow.  Ah, well.
 
Campbell Ritchie
Marshal
Posts: 64654
225
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Mike Simmons wrote:Personally, it's always annoyed me that Java doesn't have safer math operations by default. . . .

Maybe your disagreement isn't with Java® at all, but with IEEE754. I know there are features about IEEE754 which aren't necessarily mathematically sound, including the very existence of remainder operators, but we are stuck with it for better or worse.

. . . integers, . . . only need to check for overflow, never underflow . . .

I remember being taught that underflow is a problem specific to floating‑point arithmetic.
You will end up at the point where your floating‑point arithmetic will underflow to 0.0 otherwise you run out of memory space to store such small values. And remember how poor the precision is close to 0.0. We had a chap talk to us at the BCS at Darlington a few years ago about a new format for floating‑point arithmetic. He used the nearly 2⁵² spare values at present used for NaNs to extend the small end of the range, and had a concept of NaNs being orthogonal to other numbers, rather like the way imaginary numbers are sometimes depicted. I have forgotten most of the other deatils, I am afraid. He said it was possible to obviate exceptions caused by strange arithmetic (divide by 0) and his new arithmetic would be so fast his computers would outsell everybody else's . . .

. . . it's not clear whether other conditions like dividing by 0 . . . should be converted to an exception, or whether we can just continue to use values like POSITIVE_INFINITY and NAN . . .

I would agree with the notion that 1.0 ÷ 0.0 = ∞, but maybe we should be throwing exceptions instead of producing NaNs.

But IEEE754 is a compromise produced because different computer manufacturers were using different formats for floating‑point arithmetic and numbers, so at least they were all getting the same things wrong the same way Just like Java® which follows IEEE754 strictily, until you read about the % operator on floating‑point numbers. Again
 
Mike Simmons
Ranch Foreman
Posts: 3267
19
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, I had seen your previous post re: IEEE 754, and that why I had said yes, I'm aware of the history of IEEE 754.  Yes, we know Java is following IEEE 754.  I would say I'm not disagreeing with the rationale that IEE 754 had back in 1985, nor with the reasons Sun had for using it for Java in the early nineties.  But I find it annoying to be stuck with it as a default in 2019.  (Pretty sure I felt this way in 1998 or so as well.) Java is in general pretty good about throwing a stack trace when something bad and unexpected happens, e.g. a null.  But with primitive operations, not so much - errors can get ignored or hidden by default.  This applies to integer overflow most of all, but also to the other issues discussed.
 
Campbell Ritchie
Marshal
Posts: 64654
225
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
One problem about integer overflow is that you have to ignore it when calculating hash codes.
 
Mike Simmons
Ranch Foreman
Posts: 3267
19
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Very true.  Also a lot of cryptography uses such integer arithmetic.  We absolutely need to be able to access this sometimes.  I just don't like it as the default.
 
Paul Clapham
Marshal
Posts: 24594
55
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Carey Brown wrote:Perhaps Bob's problems could be reduced or eliminated by similar analysis and optimization of the order of operations being performed. Incorporating a divide() method would serve to highlight cases where analysis and optimization could be applied in a more focused manner.



From his last post it sounds like he's on the way to doing that. He did mention that underflow might (or might not, presumably) be the source of the problems, so adjusting the code to deal with underflow in some way will likely help him to find whether there's some other source.
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!