Reputation: 384
Jackson seems to be coercing all floats into doubles in any data structure that I am trying to serialize into JSON. Is there any way to avoid this behavior?
Float f = 50.1f;
System.out.println(f); // 50.1
System.out.println(f.doubleValue()); // 50.099998474121094
System.out.println(new ObjectMapper().valueToTree(f)); // 50.099998474121094 -- how to prevent this?
Using jackson-all-1.9.11.jar.
Upvotes: 4
Views: 6348
Reputation: 2155
In Jackson 2.17.2 this is not a problem, but as a problem still might appear in unexpected places:
float f = 4.24f;
double d = 4.24;
System.out.println (omp.valueToTree(f));
System.out.println (omp.valueToTree(d));
And the result, so far looks ok:
4.24
4.24
Yet, it might require some additional formatting.
Some problems still might occur. But these problems come from Java, not from the Jackson itself.
Supposing having following class
public class Amount {
private float amount;
public void setAmount(float amount){this.amount = amount;}
public float getAmount(){return amount;}
}
As with Jackson it might occur like this
@Test
void testAmount() throws JsonProcessingException {
Amount amt = new ObjectMapper().readValue("{\"amount\":4.24}", Amount.class);
assertEquals(4.24, amt.getAmount()); //<-- test fails here
}
Fixing this by using correct datatype, using 4.24f
instead of 4.24
works:
@Test
void testAmount() throws JsonProcessingException {
Amount amt = new ObjectMapper().readValue("{\"amount\":4.24}", Amount.class);
assertEquals(4.24f, amt.getAmount()); //<-- this is Ok
}
And the problem is not in Jackson but it is a normal behavior for Java itself
@Test
void doubleTest()
{
float f = 4.24f;
double d = 4.24;
assertEqualsDescribe(4.24, f, "expected to fail");
assertEqualsDescribe((float)4.24, f, "expected to succeed");
assertEqualsDescribe(4.24f, f, "expected to succeed");
assertEqualsDescribe(4.24f, d, "expected to fail");
assertEqualsDescribe(4.24, d, "expected to succeed");
assertEqualsDescribe((double)4.24f, d, "fails regardless of expectancies");
assertEqualsDescribe(f, d, "expected to fail");
assertEqualsDescribe(f, (float)d, "expected to succeed");
assertEqualsDescribe((double)f, d, "expected to succeed");
}
Here is the helper code for the describe assert:
...
public static final String RESET = "\033[0m"; // Text Reset
public static final String RED = "\033[0;31m"; // RED
public static final String GREEN = "\033[0;32m"; // GREEN
public static final String CYAN = "\033[0;36m"; // CYAN
public static <T1, T2> void assertEqualsDescribe(T1 val1, T2 val2, String message) {
if (val1.equals(val2))
System.out.print ("Success: " + GREEN + val1 + " equals " + val2 + RESET);
else
System.out.print ("Fail: " + RED + val1 + " doesn't equal " + val2 + RESET);
if (message != null) System.out.print ( CYAN + " " + message + RESET);
System.out.println();
}
...
Upvotes: 0
Reputation: 6970
You can use the custom Jackson serializer of your own as described in this link
Java to Jackson JSON serialization: Money fields
Upvotes: 0