-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GSON is always converting a long number to scientific notation format. #968
Comments
I think, it's only happen when GSON don't know that it's a long type. Look at simple example of comparison with Jackson
And take a look at another thread of StackOverflow |
especially timestamp~ waiting for solutions. |
The origin of the problem is because in ObjectTypeAdapter class (at line 78), when it detects the value is a Number returns a Double by default (even if it is an int) and by "fixing" this section of code, other tests will fail because is meant to work that way (returning always a double). I would recommend you either to give the variable the appropriate format after retrieving the value through GSON if you don't want the scientific notation or changing the type of variable that will store the value. If you want to treat the value with a different format maybe DecimalFormat class might help you with that. An important point is to notice as @Parmakli says, this only happens when GSON doesn't know exactly what type of number you want so if it is possible you could try to be more precise when treating the type of value to avoid this problem. |
I believe that the problem is due to a lack of an ability to explicitly specify a desired format to be used for long numbers. |
I think the root problem in Gson is that when ObjectTypeAdapter encounters a NUMBER it calls If this is correct, Gson would need to replace uses of (from here) |
At the very least, when supplying your own |
waiting for solutions. |
You could either convert Double to Long by hand, or use |
This is actually more severe than described until now. I have cases where I have a long number, e.g. 5992738213938843957 which GSON returns as 5.9927382139388436E18, which a Double.toLong() returns as 5992738213938843648! This is because decimal places in Double are not exact like BigDecimal. So I do not have a way to get the long value out with GSON at all currently. See also https://stackoverflow.com/questions/17695242 and https://stackoverflow.com/questions/15507997 So it seems the only option is to switch to Jackson here. |
See gson glitch: google/gson#1290 google/gson#968
* WIP * Revert "WIP" This reverts commit 98b34c4. * WIP * Revert "WIP" This reverts commit 3b9fc96. * Add de/serializer for MinDiskFree * Move MinDiskFree out of Folder * Move MinDiskFree out of Folder (2) * Revert "Move MinDiskFree out of Folder (2)" This reverts commit 65f87db. * Revert "Move MinDiskFree out of Folder" This reverts commit b71350b. * Revert "Add de/serializer for MinDiskFree" This reverts commit 5827426. * RestApi: Add MinDiskFreeSerializer, MinDiskFreeDeserializer * Revert "RestApi: Add MinDiskFreeSerializer, MinDiskFreeDeserializer" This reverts commit 3922f24. * Test * Revert "Test" This reverts commit 3550095. * FolderActivity/DeviceActivity: Fix restApi unavailable in onCreate() * Model/Folder#MinDiskFree: Initialize members (fixes #277) * ConfigXml#getFolders: Add MinDiskFree (fixes #277) * ConfigXml: Write back minDiskFree (fixes #277) * Ignore notices about updating gradle dependencies * ConfigXml: Make number parsing more safe * FolderActivity#initFolder: Add new Folder.MinDiskFree * Handle minDiskFree.value as String instead of float * Revert "Handle minDiskFree.value as String instead of float" This reverts commit 0552cfc. * WIP * Revert "WIP" This reverts commit 0a3df91. * RestApi: Avoid creating duplicate Gson() instances * Model/Folder: Use Integer instead of Float See gson glitch: google/gson#1290 google/gson#968 * Try MinDiskFree.value as Long instead of Integer * Revert "Try MinDiskFree.value as Long instead of Integer" This reverts commit d358862. * Revert "Model/Folder: Use Integer instead of Float" This reverts commit ca3931b. * Update model/Options: MinHomeDiskFree (fixes #277)
Any idea how to fix it? |
It's been five years, any hope of having a way to choose scientific notation vs. non-scientific notation? |
OK looks like I found the way to do it by using BigDecimal. I have incoming data as a float, then convert to BigDecimal and then to the JsonObject and then toString. public class JsonPrecisionTest {
public static void main(String[] args) {
System.out.println(createPayload(176.66f));
System.out.println(createPayload(17326.237f));
}
public static String createPayload(float price) {
BigDecimal bdPrice = new BigDecimal(price, new MathContext(countDigits(price)));
JsonObject json = new JsonObject();
json.addProperty("price", bdPrice);
return json.toString();
}
public static int countDigits(Float number) {
String str = number.toString();
int len = str.length();
if (str.contains(".")) {
len --;
}
return len;
}
} and the output looks like this {"price":176.66}
{"price":17326.236} |
A solution(?) for getting the long version of the number: |
Fixed by #1290. |
The issue is described at StackOverflow.
GSON always converts long numbers ending with zero to a scientific format (e.g. 1.4803202E9) and there is no direct way of preserving the number format with zeros.
The text was updated successfully, but these errors were encountered: