Converting large scientific number to long - java

I've spend a long time now, trying to convert the number 1.2846202978398e+19 in java, without any luck. Currently what I'm trying to do (long)Double.parseDouble(hashes), however this gives 9223372036854775807, which is obviously incorrect. The actual number should look something like this 12855103593745000000.
Using int val = new BigDecimal(stringValue).intValue(); returns -134589568 as it's unable to hold the result. Switching the code to long val = new BigDecimal(hashes).longValue(); gives me -5600541095311551616 which is also incorrect.
I'm assuming this is happening due to the size of a double compared to a long.
Any ideas?

Did you try to use String.format :
String result = String.format("%.0f", Double.parseDouble("1.2846202978398e+19"));
System.out.println(result);
Output
12846202978398000000
Edit
Why you don't work with BigDecimal to do the arithmetic operations, for example :
String str = "1.2846202978398e+19";
BigDecimal d = new BigDecimal(str).multiply(BigDecimal.TEN);
// ^^^^^^^^------example of arithmetic operations
System.out.println(String.format("%.0f", d));
System.out.println(String.format("%.0f", Double.parseDouble(str)));
Output
128462029783980000000
12846202978398000000

Your value exceeds the maximum size of long. You can not use long in this situation.
Try
BigDecimal value = new BigDecimal("1.2846202978398e+19");
After that, you can call
value.toBigInteger()
or
value.toBigIntegerExact()
if needed.

What about:
System.out.println(new BigDecimal("1.2846202978398e+19").toBigInteger());

Related

Scala - convert large or scientific numbers to Long

Need to be able to convert 00000924843571390729101 or 2.71000000000000000E+02 to Long
Expect 2.71000000000000000E+02 to become 271
funky results for this: 00000924843571390729101 became 924843571390729088
val signNumber = "00000924843571390729101"
val castnum = signNumber.toDouble.toLong.toString
First conversion below works for 2.71000000000000000E+02, 2nd one works for 00000924843571390729101
val castnum = signNumber.toDouble.toLong.toString
val castnum = signNumber.replaceAll("\\.[0-9]*$", "").toLong.toString
Do not want to keep any decimal places so not using java.math.BigDecimal
Input string may come in as 9028456928343.0000 in which case want 9028456928343 as the Long
The weird result in the first case is due to the fact that you are going through toDouble, limiting the precision due to how doubles are represented.
To reliably convert from these strings to Longs you can try out BigDecimal::longValueExact as follows:
import java.math.BigDecimal
new BigDecimal("00000924843571390729101").longValueExact()
// 924843571390729101: Long
new BigDecimal("9028456928343.0000").longValueExact()
// 9028456928343: Long
new BigDecimal("2.71000000000000000E+02").longValueExact()
// 271: Long
Since you also have strings that come with decimal digits, you have to use a form of number parsing that can recognize those, even if you don't want to keep that information.
This method will throw an ArithmeticInformation if you loose any information, meaning the number doesn't fit in a Long or it has a nonzero fractional part. If you want to be more lenient you can use BigDecimal::longValue
import java.math.BigDecimal
import scala.util.Try
​Try(new BigDecimal("9028456928343.0001").longValueExact())
// Failure(java.lang.ArithmeticException: Rounding necessary): scala.util.Try
Try(new BigDecimal("9028456928343.0001").longValue())
// Success(9028456928343): scala.util.Try
You can play around with this small snippet of code here on Scastie.
val signNumber = Try(numberCleaner(signNumber).replaceAll("\\.[0-9]*$", "").toLong.toString).getOrElse(numberCleaner(signNumber).toDouble.toLong.toString)

Long values are concatenating instead of adding

I have this method:
public NumPal next(){
stringRev = reverseString(stringCur);
numRev = Long.parseLong(stringRev);
numCur = Long.parseLong(stringCur);
numCur = (numCur + numRev);
stringCur = Long.toString(numCur);
NumPal n = new NumPal(stringCur);
return n;
}
When i try to add numCur and numRev it for some reason concatenates them. Are they staying as strings? I believe I'm using Long.ParseLong correctly but im not sure.
Check whether the addition is overflowing long size. long size range is 2^63 to 2^63–1. If you want to addition of big numbers which cannot be accommodated in long, try the method present in this link. https://www.geeksforgeeks.org/sum-two-large-numbers/

Java, math (adding, dividing, multiplying) all together

This is my code and it whines about calc 2 and the result.
BigDecimal costNum1 = new BigDecimal(number3.getText().toString());
BigDecimal costNum2 = new BigDecimal(number1.getText().toString());
BigDecimal costNum3 = new BigDecimal(number2.getText().toString());
BigDecimal calc1 = costNum1.multiply(costNum2);
BigDecimal calc2 = calc1.divide("100");
BigDecimal calc3 = calc2.multiply(costNum3);
result.setText(calc3).toString());
Safe to say I'm quite new in this, I'm almost there but I can't make up what is wrong. It's for my first Android App.
BigDecimal#divide accepts another BigDecimal, not a String.
Try
calc2.divide(new BigDecimal("100"));
Also, you have one too many parentheses in your last line.
Try
result.setText(calc3.toString());
You should always count the number of left parens, and see if it matches the number of right parens. If you use an IDE like eclipse, it should point these problems out to you automatically.

How do I use BigDecimal's setScale to get two digits precision

public class Dummy {
public static void main(String args[]) {
String x = "1.234.567,89 EUR";
String e = " EUR";
List<BigDecimal> totals = new ArrayList<BigDecimal>();
totals.add( new BigDecimal(x.replaceAll(" EUR","").replaceAll("\\.","").replaceAll(",",".")));
System.out.println(totals.get(0).add(new BigDecimal(0.10).setScale(3,0)));
}
}
With current code I get 1234567.991 and setting it to setScale(2,0) I get 1234568.00 what I am looking for is 1234567.99. Any help?
Use
System.out.println(totals.get(0).add(new BigDecimal(0.10)
.setScale(2, BigDecimal.ROUND_HALF_UP)));
Out put
1234567.99
I think there must be an inbuilt Java function for this. But otherwise, you can do it with simple mathematics.
You can multiply the number with 100. And then use ceiling or floor function of Java. And then divide it with 100. You got your desired result.
Do not use
new BigDecimal(0.10)
which is both inprecise and does not give a precision/scale of 2.
But use
new BigDecimal("0.10")
This preserves the scale.
This will give desired output.
If you want to go with double at that time we can use DecimalFormat but in bigdecimal setScale is used.
BigDecimal.valueOf(1234567.991).setScale(2, BigDecimal.ROUND_HALF_UP)
.doubleValue();
OUTPUT
1234567.99

Removing the .0 from a double

I am trying to display numbers in a string dynamically, so if the number has decimal's display them but if not don"t show the .0
example: display 5.5 as 5.5 and 5.0 as 5
This is what I have so far: (answer is a double)
double temp = answer;
long temp2 = (long) temp;
if (temp == temp2) {
output = String.valueOf(temp2);
System.out.println(output);
this work's fine up to about 1e18 then will error out because of the maximum size of a Long.
So how would I achieve this on bigger numbers like 5.43e86
Use DecimalFormat
double answer = 5.0;
DecimalFormat df = new DecimalFormat("###.#");
System.out.println(df.format(answer));
The DecimalFormat suggestions are the easiest way to handle this. If they aren't sufficient, here's another idea.
If you're starting to hit the maximum values that can be represented by primitives in Java, then you may need to move to BigInteger and BigDecimal.
Try playing around with the BigDecimal.toBigInteger() method coupled with the toString() methods on BigDecimal and BigInteger.
It's not good solution
if you use new DecimalFormat("0.#") you are missing data, for example
PI = 3.14, but after parse you ae geting 3.1
Another solution to use eval%1 ? (int)d : d
this time couse max integer limit , again missing data
my solution is working, but it's not good idea
res = removeLastChars(eval,".0");
private String removeLastChars(double eval, String text){
String res = String.valueOf(eval);
int length = text.length();
if (res.length() > length){
res = res.substring((res.length() - length), res.length()).equals(text)
? res.substring(0, (res.length() - length)) : res;
}
return res;
}
Look at
http://download.oracle.com/javase/6/docs/api/java/text/DecimalFormat.html
you would want just DecimalFormat("0.0")

Categories