Hi,
I am currently using 10.5 version of wemethods and we have a key value called Budget which is of type float(number) and when we try to use pub.jsonStringtoDocument and this value is getting converted to exponential form.
The target system is now not able to recognize as number and this is failing .Any customer code /alternative to hold the value as same as input given…Suggestions please
The output generated by pub.json:jsonStringToDocument is valid per the JSON specification which allows a number to have an exponent part ( E ) . The target system should be able to perceive 7.523866339E8 as a valid number.
Passing { “budgetData”:7.523866339E8 } to the service pub.json:jsonStringToDocument doesn’t throw any errors.
Alternatively you could instruct the pub.json:jsonStringToDocument to interpret the real number value as a string and retain the exact digits by specifying the inputs decodeRealAsDouble as false and decodeRealAsString as true , the negatives of this approach is that the output would have the value as a string - { “budgetData”:“75238663.39” }
Agreed that the target system should be able to handle this, but there are many threads on the web about this very thing – because folks are using parsers that do not support scientific notation. That means they aren’t really “complete JSON parsers” but it appears this occurs enough that people need to accommodate them.
Adding to the frustration is there is no apparent reason for conversions to suddenly use scientific notation. Such as in this case, what’s the point of doing so? Agreed that semantically they are the same. Syntactically, they are not and that can cause problems.
Float/double/scientific notation – great for what they do. But IME, 99.9% of integrations should not be using them.
After doing jsontoString I was again converting that ObjecttoString
The target system is SAP and it was not accepting that but your solution of setting pub.json:jsonStringToDocument to interpret the real number value as a string and retain the exact digits by specifying the inputs
decodeRealAsDouble as false
decodeRealAsString as true
Worked …
For the forum admins: there is a response in this thread I posted that is pending moderator approval. Not sure why – possibly because it is a bit long? In any case, let me know if there is anything I need to do.
Yes, from a usage perspective it is frustrating. This is possibly because of the underlying APIs which return a floating-point number greater than 9999999 automatically in a scientific notation. For a public service such as this one, there should be an option to retain the actual value and as a number too…
I strongly encourage the practice of NEVER converting strings with decimal values to float/double types. Float/double have a fundamental behavior that can really mess up monetary calculations. The challenge is that the behaviors only show up in some instances and can be hard to track down. The basic issue: the decimal fraction 0.1 is a repeating fraction in binary. It cannot be accurately represented. The usual things people attempt is truncating and rounding after performing a calculation. But depending upon the calculation the "damage’ may have already been (silently) done with inaccurate results.
There are a couple of threads on these forums covering ways to avoid using float/double. One downside is that pub.json:jsonStringToDocument does not provide sufficient control to prevent all conversions to native types. If a numeric value in a JSON element is an integer, instead of a decimal, it will be converted to int/long by default. This doesn’t cause accuracy issues but I wish there was an option to keep it as string. JSON syntax distinguishes between “number” (contains decimal) and “integer” (no decimal) but practically they usually need to be treated the same – a field may contain either “type” and still be valid. I wish jsonStringToDocument had a single setting to keep everything as string (JSON is fully a string representation with “hints” about numeric values). [EDIT] 10.15 and later addresses this. Thanks @John_Carter4 for the reminder!
An additional challenge is pub.json:documentToJSONString doesn’t provide control to create JSON elements as number/integer (no quotes around the value) without converting the values in the document from strings to native types or to wrapper classes. I wish it accepted a string list parameter naming the fields to be treated as number/integer (no quotes) to simplify things. Until then, we use pub.math:toNumber with convertAs set to java.math.BigDecimal or Integer/Long/BigInteger as needed (never Float/Double).
There is almost no reason to convert data elements to native types (float/double/long) in Integration Server. Even the pub.math services accept strings not float/double. BUT those services should be avoided because they convert strings to float/double, potentially introducing accuracy errors. We created equivalent services using BigDecimal within. This caveat applies to any calculations in any language – this is not unique to Java. If accuracy is needed (for money calcs, when isn’t it?) avoid float/double everywhere.
Let me emphasize the importance of what @reamon wrote about the accuracy issues with float (not that someone with his reputation needs my support).
Unless you want to risk wrong results on sometimes seemingly simple calculations, you MUST NOT USE float. I had a rather embarrassing experience in early 2002 (not knowing better at the time) with this and can only warn people.
As of 10.15 we introduced a new service pub.json:jsonToDocument to replace pub.json:jsonStringToDocument, which no longer attempts to strongly type numbers and instead treat them as Strings (unless explicitly defined via the input or associated document type).
This should simplify this type of problem as it ensure no conversion is done and in many cases the value only needs to delivered from one point to another and hence conversion is redundant.
regards,
John.