Java BigDecimal.doubleValue between Java 6 and Java 8 - java

Case 1: In Java6 BigDecimal("0.0050000").doubleValue() returns 0.0050, and in Java 8 return value is 0.005
Case 2: In Java6 BigDecimal("0.0250000").doubleValue() returns 0.025, and in Java 8 return value is 0.025
In case 1: Java 6 returns with extra trailing zero.. Any idea?? Also how to make Java 8 return the same output as Java 6

There is difference how System.out.println works in java6 and java 8.
Also we talk about doubles, BigDecimal is not a problem here. We can simplify this example to:
System.out.println(Double.toString(0.0050000));
Because println calls java.io.PrintStream#print(double) and then calls String.valueOf(d) you can check it in JDK.
But java.lang.Double#toString(double) looks different in JDK6 and JDK8:
return FloatingDecimal.toJavaFormatString(d); //JDK 6
return new FloatingDecimal(d).toJavaFormatString();//JDK 8
I've found some JDK issues which has been fixed in java 7 (java 7 has same output like in java 8)
I think this issue maybe a cause:
http://bugs.java.com/view_bug.do?bug_id=6935102
http://bugs.java.com/view_bug.do?bug_id=7039369
http://bugs.java.com/view_bug.do?bug_id=7032154

Related

Different Rounding Results in Java 6 and Java 8 [duplicate]

This question already has answers here:
Why does Math.round(0.49999999999999994) return 1?
(5 answers)
Closed 6 years ago.
I am rewriting an old Java 6 Program written to perform some scientific calculations in Java 8 and stuck up in this situation where I'm getting different results for rounding operation.
Java 6 is rounding an input like 0.499999999999999999994 to 1 but Java 8 is making it 0. I'm not able to understand the problem here.
For Instance:
private void foo() {
System.out.println(Math.round(0.499999999999999999994));
}
The above code behaves differently for different Java versions.
It would be great if someone could shed some light on this issue.
I think you stumbled on a known bug in Java 6 which was later fixed in Java 7. This explains the weird code behaviour in Java 6 and Java 8.
Bug Info:
http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6430675
More information and beautiful explanation by #OliverCharlesworth can be found in this post:
Why does Math.round(0.49999999999999994) return 1
Excerpt from his post:
In Java 6 (and presumably earlier), round(x) is implemented as
floor(x+0.5). This is a specification bug, for precisely this one
pathological case. Java 7 no longer mandates this broken
implementation.
The reason why the output of your example is 0 is a different one. 0.999999999999999999994 is a double. Casting an double to an it drops the decimal places of the double value.
public class Example {
public static void main(String[] args) {
double d1 = 0.9;
Double D1 = Double.valueOf(d1);
int d1AsInt = (int)d1;
System.out.println("d1 as int:\t" + d1AsInt);
System.out.println("d1 as int:\t" + D1.intValue());
}
}
If you rely on precise values you should use BigDecimal and BigInteger.

Investigating a Java bug regarding String.valueOf(float)

In Java is it a possibility that String.valueOf(float) would format a float number differently based on what operating system the code is run on, the version of java and/or the operating systems locale.
For example, with the float number 4.5 would it ever be formatted to "4,5" instead of "4.5"?
String.valueOf(float) calls Float.toString().
Float.toString() calls intern sun.misc.FloatingDecimal.toJavaFormatString(float)
The result string will never contain the sign , bacause of hard-coded '.' (ASCII: 46) inside the BinaryToASCIIBuffer.getChars(chars[])
You can see it if you decompile sun.misc.FloatingDecimal class (in my case java 8 jdk) or see the (similar) implementation in openjdk.

Java string split gives different outputs on Windows and linux

Please see the below code --
String s11 ="!country=India ";
String[] ss =s11.split("((?<=[!&|])|(?=[!&|]))");
System.out.println(ss.length);
for(String s :ss) {
System.out.println(s);
}
On Windows it gives
2
!
country=India
Whereas with Ubuntu it gives
3
!
country=India
Why would that be ?
This behavior is not because of different operating systems, but likely different versions of the JVM are used.
This "behavior change" has caused bugs to be filed incorrectly for Java 8.
The documentation has been updated for JDK 8, and is also discussed at length in this question, where split in Java 8 removes empty strings at the start of the result array. This is why the additional empty string before the ! is not created (hence the length of 2 instead 3).
Notice the difference in documentation for the split() method in Java 7 and in Java 8 for the Pattern class, and the string class (Java 7, Java 8) respectively. See the original question linked for further information on this.
I have also reproduced this issue on Java 7: sun-jdk-1.7.0_10 (ideone) and Java 8 sun-jdk-8u25 (ideone). See the Java versions here. Java 8's split will provide not add the extra empty string into the array, while Java 7's split will.
This it is not because of the system being Linux or Windows, but rather the JVM version. You can double check your JVM's version with java -version

Java7 Double.toString() returns 0.005 / java6 it is 0.0050

I am upgrading from JDK6 to JDK7. The following code demonstrate shows a minor change in Double.toString()
public class StringDemo
{
public static void main(String[] args)
{
System.out.println(Double.toString(.0005));
System.out.println(Double.toString(.005)); //different string
System.out.println(Double.toString(.05));
System.out.println(Double.toString(.5));
}
}
JRE6
5.0E-4
0.0050
0.05
0.5
JRE7
I am looking for any documentation related to above change. The compatibility page does not cover it.
5.0E-4
0.005 //changed.
0.05
0.5
The output was saved in many reference files, and compared by string comparison- I need to fix the comparison, but curious to know more details about this change. Authoritative answer on why this change will get bounty.
This was a bug in Java 1.3 through 1.6 (resolved in 1.7).
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4511638
The bug report http://bugs.sun.com/view_bug.do?bug_id=4428022 contains more details. Fixed in JDK 7 (b75).
Related Reports- Quoted from the link above.
Backport: JDK-2181423 - System.out.println(0.001) outputs 0.0010
Duplicate: JDK-5078240 - Double.toString(double) adds a trailing zero
in certain cases
Duplicate: JDK-6575880 - Float.toString(float) adds trailing
zeros
Relates: JDK-6935102 - Regtest
closed/sun/misc/FloatingDecimal/ToString.java now failing.
Relates: JDK-4154042 - java.lang.FloatingDecimal could be
eliminated
The changes for OpenJDK 7 to fix this issue are available at: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/f85aa3aedf41

String.format equivalent in Java 1.4

Currently i have a method calling String.format() in Java 5 and it's working perfectly
String.format("%02x", octet) //octet is a int type
However due to some issue we need to deploy this code in a JDK 1.4 environment, and String.format doesn't exists in 1.4.
Anyone knows any alternative way to perform this function?
You could use something like this snippet:
String hexString = Integer.toHexString(octet);
if (hexString.length() < 2) {
hexString = "0" + hexString;
}
You need to use Integer.toHexString(int) and pad the text yourself.
I think you should take a look at Retroweaver which lets you deploy Java 1.5 on a 1.4 JVM.
Retrotranslator supports String.format translation to JDK 1.4

Categories