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)
Related
I'm using a 3rd party software built in Java that displays numbers. This software is multilanguage and one of the languages that we use is Euskera (eu, eu_ES). Number format is shown wrong in this language (123,456.89 instead of 123.456,89).
Searching more in-depth and decompiling some classes I've seen that number formatting is done with DecimalFormatSymbols and DecimalFormat so I've made a junit test to see if the issue is from this 3rd party software or from java.
Locale locale = new Locale("eu");
DecimalFormatSymbols decimalFormatSymbols = new DecimalFormatSymbols(locale);
String pattern = "#,###.##";
DecimalFormat decimalFormat = new DecimalFormat(pattern, decimalFormatSymbols);
String formatted = decimalFormat.format(1234567.89765);
assertEquals("1.234.567,9", formatted);
After running this test I've seen is Java who is formatting this way.
In one hand I've downloaded the last version of this 3rd party software because is open source and I could make a little workaround that worked. On the other hand, we use a version from 6 years ago that can't be upgraded because os system requirements and this version are in Sourceforge's CVS which I was unable to download.
Is there any way I can change the grouping separator and decimal separator for Euskera in Java level?
Yes, you can but it's a bit of a palaver. Essentially, you can create a custom NumberFormatProvider that does something different for eu_ES and delegates to the original provider for all other locales. You'll have to put it in a JAR with a META-INF/services/xxxx file and include it on the classpath.
See this question: Java override locale setting for specific locale
And more instructions here:
LocaleServiceProvider JavaDoc
Tutorial on the Java Extension Mechanism
I don't know java and can't get JavaCall.jl to work with java.text.DecimalFormat. In MATLAB this is very simple -- just check out this link.
Reading the JavaCall.jl documentation, I tried replicating the provided example with DecimalFormat and got this far:
julia>using JavaCall
julia>JavaCall.init(["-Xmx128M"])
julia>jdf = #jimport java.text.DecimalFormat
After that, I got a bunch of errors. (bear in mind: I absolutely have no clue as to how Java works?)
Please help!
It's not clear from the question whether you're looking to know more about JavaCall.jl or just to use some comma separated formatting.
If the latter, then you can use the Formatting.jl package: https://github.com/JuliaIO/Formatting.jl
julia> using Formatting
julia> sprintf1("%'.02f", 123456789)
"123,456,789.00"
And then you don't need any Java.
This package also has a bunch of other formatting options.
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.
This might be kind of a dumb question, but I'm stuck on it.
I'm trying to set the RoundingMode on a DecimalFormat.
DecimalFormat df = new DecimalFormat("###.##");
df.setRoundingMode(RoundingMode.HALF_UP);
However, the code looks fine to me and it looks the same as many examples I have seen.
The error on setRoundingMode() is:
***The method setRoundingMode(RoundingMode) is undefined for the type DecimalFormat***
It suggests to cast df to an Object, but that doesn't solve anything...
Any suggestions?
EDIT
I am using ver. 1.7
Below I changed the compliance level to 1.6 yet no difference.
Thank you in advance for the help!
Try System.out.println(System.getProperty("java.version")); and be sure that your jre version really is 1.6 or higher
The Chinese currency has the ISO 4217 code CNY. Since free global trading in that currency is restricted though, there's a second 'offshore' currency equivalent, called CNH. Wikipedia has a bit of summary of this all.
CNH isn't in ISO 4217, but I'd like to be able to use it in my app without having to write my own Currency class. Presumably there's some kind of list somewhere inside the JVM install. How do I go about adding additional currency codes?
EDIT: See this question for dealing with this in Java 7
Looks like support for this was added with Java 7.
For earlier versions, you could use an equivalent Currency class of your own devising, or less happily, replace the default java.util.Currency class (or java.util.CurrencyData, which contains the raw data) in your classpath (whitepaper).