-2

I have have taken 10 digit float value and tried to convert it to string to print in a readable format. Here is the program to check

public static void main(String[] args) {
    String s1 = "2139095039";
    String s2 = "2.13909504E9";
    Float f1 = Float.valueOf(s1);
    Float f2 = Float.valueOf(s2);
    System.out.println("Are f1 and f2 are same:::" + (f1.equals(f2)));// TRUE
    System.out.println("Are s1 and s2 are same:::" + (s1.equals(s2)));// FALSE
    System.out.println("Are f1 and f2 string format type same:::"
            + (String.format("%.0f", f1)).equals(String.format("%.0f", f2)));// TRUE
    System.out.println("S1 Float to String convertion:: " + String.format("%.0f", f1));// 2139095040
    System.out.println("S2 Float to String convertion:: " + String.format("%.0f", f2));// 2139095040
}

My question here is when S1 and S2 values are same why after conversion to string type its printig 2139095040 instead of 2139095039?

In other words how can i print human readable format of scientific notation of 2.13909504E9?

  • 3
    If precision in decimal values is important, [don't use floats/doubles](https://www.geeksforgeeks.org/rounding-off-errors-java/). – Tim Hunter Oct 06 '20 at 15:16
  • You can use System.out.printf() or NumberFormat to format the number as you want without tranforming it to a string. – NomadMaker Oct 06 '20 at 16:25
  • As an example i printed here actually I need string type object and i don't want to use any other type apart from Float datatype – Ramesh Bathini Oct 06 '20 at 17:26

1 Answers1

0

For roughly the same reason that 0.333333333333333333333 * 3 is not 1.0. Rounding error.

More specifically.

  1. Computer floating point types are base-2
  2. It is a mathematical fact that the mapping between (finite precision) base-2 floating point and decimal notation (base 10) is not exact for all values. (Just like you can't write 1/3 exactly in decimal notation ... unless you have an infinite piece of paper.)

Observations:

  1. You can reduce rounding errors by using double rather than float.
  2. You can reduce rounding errors even further by using BigDecimal.
  3. You can hide rounding errors on output by displaying numbers with less precision, and rounding to the nearest ...
  4. In some cases you cannot eliminate rounding errors entirely.

Note that there is a field of mathematics devoted to the mathematics of numerical computation: Numerical Analysis. If you really want to understand this stuff, how to deal with the effects of errors on computation, that's the field to study.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • I would also add that in lower-level programming languages without such constructs as `BigDecimal` or `BigFloat`, precision is best achieved by storing all values as integer values and dividing at the end. This isn't a problem for OP as they are using Java, but this is useful for anyone working "down at the metal". – guninvalid Oct 06 '20 at 15:45
  • Or use a pre-existing "bignum" library ... in a languages like C, etc. – Stephen C Oct 06 '20 at 15:48
  • Thanks for Details @StephenC. Here i have to use float as a datatype due to some design issues at my end. My concern here is that why floating number printing 2139095040 instead of 2139095039 ? – Ramesh Bathini Oct 06 '20 at 17:05
  • Have to use Float type due to some restrictions at my end. Is parseFloat having any issues while converting bigger float values? – Ramesh Bathini Oct 06 '20 at 17:11
  • The problem is more fundamental than that. `2139095040` is the decimal representation for the `float` value that is nearest to both `2139095039` and `2139095040`. The `parseFloat` method is actually doing the right thing. It is behaving as specified. If you want more precision you **have to** change the data type. – Stephen C Oct 06 '20 at 22:55
  • Thank you @StephenC for the detailed explanation. I do not want to change the datatype due to some restrictions in my application. Here when end user enters a value in the screen parseFloat datatype converting it to some other value hence users seeing some discrepancy with it. for example 2147483647 also converting it into 2147483650. Do we have any other way to make this cocurate other than changing the datatype? – Ramesh Bathini Oct 07 '20 at 04:57
  • I have already answered that question. See the last sentence of my last comment. – Stephen C Oct 07 '20 at 05:28
  • 1
    Or ... I suppose you could ask someone to change reality and the laws of mathematics for you. Apparently you can do that in the USA :-) – Stephen C Oct 07 '20 at 05:30