Jackson JSON conversion rounds values outside of integer range (2^32) [duplicate] - java

I need to parse a json that contains a long number (that was produces in a java servlet). The problem is the long number gets rounded.
When this code is executed:
var s = '{"x":6855337641038665531}';
var obj = JSON.parse(s);
alert (obj.x);
the output is:
6855337641038666000
see an example here: http://jsfiddle.net/huqUh/
why is that, and how can I solve it?

As others have stated, this is because the number is too big. However, you can work around this limitation by sending the number as a string like so:
var s = '{"x":"6855337641038665531"}';
Then instead of using JSON.parse(), you can use a library such as javascript-bignum to work with the number.

It's too big of a number. JavaScript uses double-precision floats for numbers, and they have about 15 digits of precision (in base 10). The highest integer that JavaScript can reliably save is something like 251.
The solution is to use reasonable numbers. There is no real way to handle such large numbers.

The largest number JavaScript can handle without loss of precision is 9007199254740992.

I faced this issue some time ago, I was able to solve using this lib: https://github.com/josdejong/lossless-json
You can check this example:
let text = '{"normal":2.3,"long":123456789012345678901,"big":2.3e+500}';
// JSON.parse will lose some digits and a whole number:
console.log(JSON.stringify(JSON.parse(text)));
// '{"normal":2.3,"long":123456789012345680000,"big":null}' WHOOPS!!!
// LosslessJSON.parse will preserve big numbers:
console.log(LosslessJSON.stringify(LosslessJSON.parse(text)));
// '{"normal":2.3,"long":123456789012345678901,"big":2.3e+500}'

Related

How to calculate any power of a base 2 number in Java by not using BigInteger?

How can I calculate in Java any power of a number in a base 2 (2^n, where n can be any number), without using the BigInteger class?
Let's say I got the binary number 100000000000000000000100000000001 stored in a given array, and I want to print its value in a decimal number (just to print it, let's say we store it in a String type).
I'm not sure I understand your problem completely, but if n is the binary number converted to a decimal number, then you are playing with way too large numbers.
Consider the binary number as decimal. Your example would be the decimal number 4294969345. Just try to consider what 2^4294969345 would be. As an example 2^429 would be 1.38633485×10^129. There's no way you can execute this.
I agree with the others, please share your code, and maybe you can get a better answer.
EDIT: If it's just a conversion from the big binary number to a decimalnumber, you can use Long.parseLong(binaryNumber, 2), where binaryNumber is your binary number as a String.
The values needs to be saved somewhere to be "just printed", whether a data structure or a primitive, in your case it's way too large for an integer ( > 2^31), you can use long instead (Long.parseLong(binary, 2)) but eventually if it keeps getting bigger, you will need another way, either using BigInteger or your own brains.

Big Numbers handling in groovy + Jmeter + java

I have a question about big numbers in groovy, I write at script that call to DB and put budget value in variable called toub_start_budget, the value stored is 2570000000.
since I want to do arithmetic operation I created another variable called toub_budget and put in it the value of the first variable as float.
The problem is that the new variable not saved the data as float but as a number as 2.56999987E9.
and the arithmetic that I do are wrong, for example divide by 1000000, will bring 2569.9 and not the accurate results 2570 (accuracy is important).
can someone please advise how to handle big numbers, with arithmetic?
regards
Do not use float, it is by definition inaccurate. If you need to do accurate calculations and arbitrary big numbers, use BigDecimal. If you use Groovy, then just do the calculation, Groovy will automatically use BigDecimal when appropriate as you can see by executing (2570000000 / 1000).getClass() and (2570000000 / 1001).getClass()

Using Java BigDecimal for a 15 precision digit (scale of 2)

I found a partial answer here, but I knew this already. So I decided to post a new question.
I am trying to convert a HTTP request parameter string to a 15 precision Java BigDecimal number (with scaling of 2). For example,
String x = request.getParameter("seqNo"); /* e.g. 12345678910111213141516.17181920 whatever */
// I want to convert x so that it has a precision of 15 and scale of 2 i.e. 111213141516.17.
I don't care about rounding. It's a form of reference number, so irrelevant of rounding. I know that scaling can be set by using overloaded setScale(int) method that will return a scaled(Truncated?) BigDecimal. But how to make sure that the precision is set properly?
How about using substring instead? It's not really a number anyway.
int pos = x.indexOf('.');
String y = x.substring(pos - 12, pos + 3);
If you are really crazy enough to try processing this as numbers (collissions and differences in rounding are going to break your neck sooner or later!), you could do this.
double v = Double.parseDouble(y); // REALLY REALLY REALLY NOT RECOMMENDED.
But this is a very very bad idea. Don't squeeze something into a number column that is not a number. Next week, you'll get numbers with two dots, and it will break in every possible way.
If you do not need to do mathematical computations, treating such a field as VARCHAR or TEXT is perfectly acceptable. Because that is what it is: a sequence of characters. Not a number.
In fact, I would strongly advise to store the whole number, as VARCHAR. It is a unique identifier, not a mathematical number to do computations with.

How to round a float number in Java if its a whole? [duplicate]

This question already has answers here:
How to round a number to n decimal places in Java
(39 answers)
Closed 8 years ago.
How do I round a float number if it returns a whole value? And, how do I round if it's like:
5/2 = 2.5
and NOT like this:
5/2 = 2.50000000
A double does not allow you to specify the number of decimal places it has; you may be able to set as many as you wish to 0, but they are still there. (Note that, mathematically, the two values you show for 5/2 are the same.) What you can do is control how many get displayed; since you haven't specified how you are attempting to display this value, I can't help in how to modify it to limit the number of decimal places to show.
Whenever needed, you can make some modifications on your double, such as using the setRoundingMode method of DecimalFormat class, along with the RoundingMode enum.
As mentioned before though, 2.5 is the same with 2.500000 in a double, you do not have to change its digits.
I guess you are trying to print your double and you get a number of unwanted digits in the output. In that case, I suggest though that you convert your double into a formatted string and use it as such:
System.out.println(String.format("%.2f", myDouble));
You are a bit confused I think...
2.5 and 2.50000000 are the exact same thing!
They are just written differently.
I don't really understand what you are trying to achieve but you can round floats like this:
float result = Math.round(someFloat);
If you always want to round up or down regardless of what the number is use:
float result = (float)Math.ceil(someFloat);
or
float result = (float)Math.floor(someFloat);

Java Math.pow issue

I am working on a program which needs to cube a number. Long story short, I need to compare the number to a string, so I need to get rid of the decimal place a double gives when I convert to string. To do this, I used Math.round and saved it as a long. This works fine for relatively normal numbers, but the numbers can go up to 999,999.
I used 275393 (a given test number, so I'm assuming it must be correct for the problem I'm working on) and neither a calculator nor the computer seemed to get the correct answer. The correct answer is supposed to contain 123457 somewhere in the results, but the calculator has 12346 (which I think is just rounding, as it stops listing numbers after this) and the computer has 123456 (the computer stops listing numbers after this point). Is rounding it giving it the problem (it shouldn't because I'm pretty sure it only rounds to the tenths place, but who knows)? Or is it something else?
Math.pow() takes two doubles and returns a double. There is not enough precision in a double to represent 2753933 = 20886164356123457 (exact).
The solution is to use BigInteger.pow().
A double has limited precision. Instead, use BigInteger or BigDecimal for your calculation.
I need to compare the number to a string, so I need to get rid of the decimal place a double gives when I convert to string.
Do it the other way around. Convert the String to a number, then compare it to the double (with a small tolerance to account for inaccurate binary representations of float point numbers).

Categories