java.lang.ArithmeticException: Division is undefined - java

I have a simple operation going on in my program:
exposureNoDecimals =
BigDecimal.valueOf(curEffSpreadPremium).multiply(BigDecimal.valueOf(100)).divide(wsRate, 0,
java.math.RoundingMode.HALF_UP).longValue();
exposureNoDecimals - long
curEffSpreadPremium - long
wsRate - BigDecimal
However I am getting
"java.lang.ArithmeticException: Division is undefined"
at java.math.BigDecimal.longScaledDivide(BigDecimal.java:3105)
at java.math.BigDecimal.divide(BigDecimal.java:2409)
at java.math.BigDecimal.divide(BigDecimal.java:2396)
at java.math.BigDecimal.divide(BigDecimal.java:2361)
The problem is the issue is recreatable on production and not on my machine (cant debug, or cant see the inputs)
What can be the issue here? Any suggestions/ideas?

Take a look at the source code for BigDecimal (e.g. here).
An ArithmeticException is only thrown with the message "Division undefined" when you attempt to divide zero by zero.
I'm not going to suggest a fix, because the >>correct<< fix will depend on what this calculation is supposed to be doing, and why the divisor / dividend happen to be zero. Putting in some zero checks might be a solution, but it could also be a "band-aid solution" that hides the problem rather than fixing it. It could come back to bite you later on.
The problem is the issue is recreatable on production and not on my machine (cant debug, or cant see the inputs)
As noted in various comments, there are different versions of BigDecimal depending on the Java version and (apparently) vendor. One of the differences between (some) versions is that the exception messages differ.
If you really want to track this down this reproducibility issue, you are going to have to look at the source code for BigDecimal in production and on your machine. (Unfortunately, a stacktrace involving Java SE classes is often difficult to diagnose without precise Java vendor and version number information. It is not helpful in this case ... for that reason.)

According to the source code of BigDecimal, java.lang.ArithmeticException: Division undefined (without the is) is only thrown when you divide zero by zero.
Looks like in your case curEffSpreadPremium and wsRate both are zero.
So you need to guard the line with zero-checks.

Related

Integrality Gap in MAXIMIZATION in CPLEX+Java | Bug?

I try to solve a large MIP in which the . If it does not solve optimally, it shall return the integrality gap (that is, difference between best integer solution and best solution of the linear relaxation).
Using getMIPRelativeGap of the Java+CPLEX interface, I sometimes got values in the range of 1.0E11-1.0E13 which does not make sense, as an integrality gap should be a percentage between 0 and 1. I tracked those cases down and found out that I get those results, if the best integer solution has a value of 0 (my inner problem is a profitable tour problem, thus, if the best route is not visiting any vertice). The integrality gap should be (bestobjective-bestinteger)/bestobjective (https://www.ibm.com/support/knowledgecenter/SSSA5P_12.6.0/ilog.odms.cplex.help/refdotnetcplex/html/M_ILOG_CPLEX_Cplex_MIPInfoCallback_GetMIPRelativeGap.htm), yet, it seems to be (bestobjective-bestinteger)/bestinteger.
I also tested a couple of other values (if the integer objective is positive), and were able to confirm this in examples.
Can someone else reproduce this behavior? Does this behavior make sense to you?
Thanks :)
Indeed, the documentation for CPXgetmiprelgap in the Callable Library (C API) says the following:
For a minimization problem, this value is computed by
(bestinteger - bestobjective) / (1e-10 + |bestinteger|)
where bestinteger is the value returned by CPXXgetobjval/CPXgetobjval
and bestobjective is the value returned by
CPXXgetbestobjval/CPXgetbestobjval. For a maximization problem,
the value is computed by:
(bestobjective - bestinteger) / (1e-10 + |bestinteger|)
So, it looks like the documentation for the Java API is buggy. The Java API just calls CPXgetmiprelgap under the hood, so it should be the same. Thanks for reporting this. I'll make sure that this gets passed on to the folks who can fix it.

Check for improper angle bracket usage (not in tags) in inline Javadoc in IntelliJ IDEA

Pretty simple question: I often forget that using the less than and greater than symbols in Javadoc doesn't work without using the either a literal block or </>, since they're treated as formatting tags. This subsequently causes my Jitpack build to fail. I use IntelliJ IDEA as my main Java IDE, which appears to give no warning when I use angle brackets in JavaDoc; Is there a way to check against improper usage of these symbols?
According to Serge Baranov from JetBrain's support team:
It's a known limitation, please vote for https://youtrack.jetbrains.com/v2/issue/IDEA-165488.
The issue's description reads as expected:
Idea's 'HTML problems in Javadoc (DocLint)' does not report any
problems in the following javadoc:
/**
* a < b > c
*/
void test();
However, javadoc generation will fail in this case:
Test.java:5: error: malformed HTML
* a < b > c
^
Test.java:5: error: bad use of '>'
* a < b > c
^
Usually this problem is noticed only at the javadoc generation phase
of Maven build process and that's rather inconvenient.
Also, it would be great to have an intention to escape such symbols in
javadoc as &gt / &lt.
However, as of this posting, the bug has no special priority, spent time, or verification (though it has been triaged.) Developer/SO user Roman Shevchenko appears to be assigned to the issue. I wouldn't expect a fix any time particularly soon, given this isn't exactly a huge issue.

getAvailableBlocksLong() * getBlockSizeLong() VS getAvailableBytes()

[EDIT] I did make a stupid mistake on my testing. I asked a question here without knowing it.
The answer is, both are the same. But I leave my post here for others.
What is the difference between
getAvailableBlocksLong() * getBlockSizeLong() and getAvailableBytes()?
I tested myself and got a really strange result on Genymotion.
The values from getAvailableBlocksLong() * getBlockSizeLong() and getAvailableBytes() are different!
I literally don't get what is happening here.
Does it have something to do only with Genymotion?
Should I just use getAvailableBytes() in most cases?
The former gets the number of available memory blocks and multiplies it by the memory block size, the latter just straight up returns the available momery in bytes. Same thing

Unexpected results from Metaphone algorithm

I am using phonetic matching for different words in Java. i used Soundex but its too crude. i switched to Metaphone and realized it was better. However, when i rigorously tested it. i found weird behaviour. i was to ask whether thats the way metaphone works or am i using it in wrong way. In following example its works fine:-
Metaphone meta = new Metaphone();
if (meta.isMetaphoneEqual("cricket","criket")) System.out.prinlnt("Match 1");
if (meta.isMetaphoneEqual("cricket","criketgame")) System.out.prinlnt("Match 2");
This would Print
Match 1
Mathc 2
Now "cricket" does sound like "criket" but how come "cricket" and "criketgame" are the same. If some one would explain this. it would be of great help.
Your usage is slightly incorrect. A quick investigation of the encoded strings and default maximum code length shows that it is 4, which truncates the end of the longer "criketgame":
System.out.println(meta.getMaxCodeLen());
System.out.println(meta.encode("cricket"));
System.out.println(meta.encode("criket"));
System.out.println(meta.encode("criketgame"));
Output (note "criketgame" is truncated from "KRKTKM" to "KRKT", which matches "cricket"):
4
KRKT
KRKT
KRKT
Solution: Set the maximum code length to something appropriate for your application and the expected input. For example:
meta.setMaxCodeLen(8);
System.out.println(meta.encode("cricket"));
System.out.println(meta.encode("criket"));
System.out.println(meta.encode("criketgame"));
Now outputs:
KRKT
KRKT
KRKTKM
And now your original test gives the expected results:
Metaphone meta = new Metaphone();
meta.setMaxCodeLen(8);
System.out.println(meta.isMetaphoneEqual("cricket","criket"));
System.out.println(meta.isMetaphoneEqual("cricket","criketgame"));
Printing:
true
false
As an aside, you may also want to experiment with DoubleMetaphone, which is an improved version of the algorithm.
By the way, note the caveat from the documentation regarding thread-safety:
The instance field maxCodeLen is mutable but is not volatile, and accesses are not synchronized. If an instance of the class is shared between threads, the caller needs to ensure that suitable synchronization is used to ensure safe publication of the value between threads, and must not invoke setMaxCodeLen(int) after initial setup.

Rounding Half Up with Decimal Format in Android

I want to set the Rounding Mode to HALF_UP on my DecimalFormat, but eclipse is telling me that setRoundingMode() is not available on the DecimalFormat class. My project properties (and the overall Eclipse properties) are using the 1.6 compiler. The developer.android.com site says that I can use either Java 5 or 6 so I'm not sure what the problem is.
import java.math.RoundingMode;
import java.text.DecimalFormat;
completedValueFormatter = NumberFormat.getNumberInstance();
DecimalFormat completedDecimalFormat = (DecimalFormat)completedValueFormatter;
completedDecimalFormat.setRoundingMode(RoundingMode.HALF_UP);
I've also tried using the android tools to generate an ant-based project, tried this code in the project and also got the same compile error. So it doesn't appear to be related to Eclipse. It seems related to the Android API.
Any suggestions?
This doesn't truly answer why I can't use the Java 6 .setRoundingMode(RoundingMode) method in DecimalFormat, but it is at least a work-around.
int numDigitsToShow = this.completedValueFormatter.getMaximumFractionDigits();
BigDecimal bigDecimal = new BigDecimal(valueToBeRounded);
BigDecimal roundedBigDecimal = bigDecimal.setScale(numDigitsToShow, RoundingMode.HALF_UP);
return this.completedValueFormatter.format(roundedBigDecimal.doubleValue());
I create a BigDecimal with the value I need to round, then I get a BigDecimal of that value with the scale set to the number of digits I need to round my values to. Then I pass that rounded value off to my original NumberFormat for conversion to String.
If anyone has a better solution, I'm all ears!
Here is what I suspect the problem is, (assuming I am reading the docs properly) and its a doozy:
According to the java.text.DecimalFormat API documentation, you are not actually getting the Runtime Implimentation of the Java 1.6 RE, but are getting an android "Enhanced Version" that clearly doesn't include the setRoundingMode, which frankly bites.
"This is an enhanced version of DecimalFormat that is based on the standard version in the RI. New or changed functionality is labeled NEW."
A weakness in Java for many many many years has been the DecimalFormat class defaulted to HALF_ROUND_UP and had no way to change that, until JVM 1.6. Pity to see Android is keeping this need to kludge alive.
So looks like we are stuck Kludging BigDecimal scale Settings to format output all over any app that needs it, instead of simply being able to rely on a formatter call alone to get the job done. Not the end of the world, but very disappointing Google.
Of course that same doc says that setRondingMode() works, so perhaps this is a all out BUG??
I guess this would be the best option
http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Math.html#ceil(double)

Categories

Resources