1

I have a JSON source from an API at work, where I have to get a balance from the JSON response, so the value is very important. That amount comes in xx.xxxxxxxxxxxxxx (usually two digits followed by a maximum of 14 decimals).

I am working with JAVA. It doesn't matter what I try, the output is always the same. The console says it's a float, I can't cast it to any other formats. And the weirdest thing is that the number shown is wrong. For example, I am getting 803.599310421 in the JSON response, and when I print out the value, it says 803.5989647583. Same number but different decimals.

How do I get this accurately? Because frankly, I don't want to parse it as a string. The only way I could get the same value from the JSON was with substring.

Here's the code I'm using:

    JsonPath jsonobject = httpRequest2.jsonPath();
    float myFloatValue = jsonobject.get("data[0].balance");
    System.out.println(myFloatValue);

Here's a sample of the value in the JSON: 903.40019831 Here's what Sysout prints: 903.4004 or 903.4003987 Completely useless, please help!

tobias_k
  • 81,265
  • 12
  • 120
  • 179
  • Why just not use a float then? – JensW Apr 30 '19 at 07:32
  • I can't show the code because of company policy. I am using JsonPath type, from RestAssured. Tried with JSONObject (org.json.simple) – Ionut Apostu Apr 30 '19 at 07:55
  • Well, have you tried `double myFloatValue = jsonobject.get("data[0].balance");`? With `float myFloatValue = ...` you are immediately downcasting the value to `float`. – tobias_k Apr 30 '19 at 08:06
  • Of course, I tried. java.lang.Float cannot be cast to java.lang.Double – Ionut Apostu Apr 30 '19 at 08:10
  • I don't see this as a duplicate. The problem seems to be with the library. – tobias_k Apr 30 '19 at 08:19
  • I can reproduce the problem with JsonPath, which returns a float even when asking for a double. In fact, when pretty-printing the node itself, it seems like the value is already parsed as a float. Not sure if we are both using the library in the wrong way. Maybe just use Jackson instead? – tobias_k Apr 30 '19 at 08:23
  • What library and version are you using? – Daniele Torino Apr 30 '19 at 08:28
  • The problem is that floaing-point isn't this accurate. The number needs to be transmitted in ASCII decimal, and ices send using `BigInteger` or `BigDecimal`. @tobias_k – user207421 Apr 30 '19 at 08:35
  • Not sure if I'm using this correctly, but try `JsonPath.config = JsonPathConfig.jsonPathConfig().numberReturnType(NumberReturnType.BIG_DECIMAL)` before parsing the JSON. – tobias_k Apr 30 '19 at 08:35
  • @user207421 No, that is not the problem. Double _would_ be accurate enough, but by default, `JsonPath` seems to actually parse, and then return, a `float` and not a `double`. – tobias_k Apr 30 '19 at 08:36
  • No it wouldn't. You are expecting 16 significant decimal digits from a format that can only provide 15.9. In any case the problem is clearly at the other end. – user207421 Apr 30 '19 at 08:50
  • @user207421 Okay, seems like I misread the question as 14 digits instead of 2+14, but still, the _real_ problem is that without proper configuration (see above) `JsonPath` will in any case just return a `float`. The answers to the "duplicate" do not address this problem. – tobias_k Apr 30 '19 at 08:53

1 Answers1

1

enter image description here

float is not high precision. Use BigDecimal. https://docs.oracle.com/javase/8/docs/api/java/math/BigDecimal.html

Community
  • 1
  • 1
yeahseol
  • 377
  • 1
  • 6