Is there any way to convert a Long data type to Double or double?
For example, I need to convert 15552451L to a double data type.
You could simply do :
double d = (double)15552451L;
Or you could get double from Long object as :
Long l = new Long(15552451L);
double d = l.doubleValue();
Simple casting?
double d = (double)15552451L;
As already mentioned, you can simply cast long to double. But be careful with long to double conversion because long to double is a narrowing conversion in java.
Conversion from type double to type long requires a nontrivial translation from a 64-bit floating-point value to the 64-bit integer representation. Depending on the actual run-time value, information may be lost.
e.g. following program will print 1 not 0
long number = 499999999000000001L;
double converted = (double) number;
System.out.println( number - (long) converted);
Are you looking for the binary conversion?
double result = Double.longBitsToDouble(15552451L);
This will give you the double with the same bit pattern as the provided long.
Binary or hexadecimal literals will come in handy, here. Here are some examples.
double nan = Double.longBitsToDouble(0xfff0000000000001L);
double positiveInfinity = Double.longBitsToDouble(0x7ff0000000000000L);
double negativeInfinity = Double.longBitsToDouble(0xfff0000000000000L);
(See Double.longBitsToDouble(long))
You also can get the long back with
long bits = Double.doubleToRawLongBits(Double.NaN);
(See Double.doubleToRawLongBits(double))
Long i = 1000000;
String s = i + "";
Double d = Double.parseDouble(s);
Float f = Float.parseFloat(s);
This way we can convert Long type to Double or Float or Int without any problem because it's easy to convert string value to Double or Float or Int.
What do you mean by a long date type?
You can cast a long to a double:
double d = (double) 15552451L;
You can try something like this:
long x = somevalue;
double y = Double.longBitsToDouble(x);
I think it is good for you.
BigDecimal.valueOf([LONG_VALUE]).doubleValue()
How about this code?
:D
Related
I have int value 40959999. How to convert it to float without rounding into 409599,99?
result of float f = 40959999/100.00f will be 409600.0
Use double instead of float
double d = 40959999/100.00f;
Double and Float have inherent imprecision that is impossible to avoid (more info on the why here). Using a double you may not have your number rounded in this scenario but not in all. If you work with something that should never be rounded (like prices), you should be using BigDecimal instead.
Implement your int value like shown. Rather than using float use BigDecimal instead.
BigInteger b1 = BigInteger.valueOf(40959999);
int scale = 2;
BigDecimal d1 = new BigDecimal(b1, scale);
System.out.println(d1);
run:
409599.99
Lets say that I have variable tmp which is a double, and I want to convert tmp to an int, but still have the variable called tmp. How would I do this?
Thanks
You can't have the same variable as both an int and a double.
You can have this though:
double d = 0.1d;
int i = (int) d;
d = (double) i;
System.out.println(d);
Basically you first cast your double to an integer, losing the fraction. Afterwards you cast it to a double again and assign it to your d variable. You don't have to explicitly do the casting from int to double because it is a widening conversion, but it makes it more clear what happens.
The end result is that your d variable now has a value that can be precisely interpreted by an integer but on the other hand you also, well, basically threw away your fraction. Your variable did not change its type, however.
You can write this less verbosely like this:
double d = (int) 0.1d;
I have below code:
Double a = new Double((123456798/1000000)); //123456798 this value comes from client side as a `int`
DecimalFormat df = new DecimalFormat("###.###");
log.info("a :"+a+" df "+df.format(a.doubleValue()));
output:
a :123.0 df 123
//i want output like this, a :123.xxx fd 123.xxx
please help
UPDATE:
123456798 this value comes from client side as a int so i cant do it as 123456798.0 (or something)
123456798 and 1000000 are int literals, so dividing them will use integer arithmetic, and yield 123.
Instead, you could use floating point literals in order to use floating point arithmetic:
Double a = new Double((123456798.0/1000000.0));
DecimalFormat df = new DecimalFormat("###.###");
log.info("a :"+a+" df "+df.format(a.doubleValue()));
Any one value in the division should be float or double.
Double a = new Double((123456798.0/1000000));
or
Double a = new Double((123456798/1000000.0));
if you are getting these values in variables, then multiply it with 1.0
like
Double a = new Double((variable*1.0/1000000));
Put it like that
Double a = new Double((123456798.0/1000000.0)); // <- note ".0"
the reason of the misbehavior is the integer division:
123456798/1000000
is the integer value, while
123456798.0/1000000.0
is the floating point one (double)
Double a = new Double((123456798/1000000));
You are doing integer division here. Make one of the constants a double, so that floating-point division is done. Also, why are you using Double? It's better to use the primitive type double.
double a = 123456798.0 / 1000000;
Or simply, since they are constants:
double a = 123.456789;
You perform an integer division, thats why a is incorrect:
Double a = new Double(123456798.0/1000000);
I want to multiply a high precision integer (long or BigInteger) by a small double (think about something > 0 and < 1) and get the arithmetically rounded integer (long or BigInteger) of the exact arithmetic value of the operation as result.
Converting the double to integer does not work, because its fractional value gets lost.
Converting the integer to double, then multiply and converting the result back to integer will not work either, because double is not precise enough.
Of course you could argue, that because the double operand is not precise enough in the first place, it might not matter that the result is not precise with the same order of magnitude, but in this case, it does.
Bonus question:
Using BigDecimal works, but seems to be very inefficient. Converting long to double and then multiplying and converting back seems to run 500 times faster (albeit losing precision) than converting to BigDecimal. Is there a more efficient possibility? Is it possible to gain performance when multiplying several different long each with the same double?
You want to use BigDecimal in order to preserve precision.
BigInteger myBI = new BigInteger("99999999999999999");
Double d = 0.123;
BigDecimal bd = new BigDecimal(myBI);
BigDecimal result = bd.multiply(BigDecimal.valueOf(d));
Using BigDecimal indeed works. You still have to be carefull about using the exact value the double represents and rounding arithmetically.
BigInteger myBI = new BigInteger("1000000000000000000000000000000000000000000000000000000");
double d = 0.1;
BigDecimal bd = new BigDecimal(myBI);
BigInteger doubleWithStringValue = bd.multiply(BigDecimal.valueOf(d)).toBigInteger();
BigDecimal bdresult = bd.multiply(new BigDecimal(d));
BigInteger unrounded = bdresult.toBigInteger();
BigInteger correct = bdresult.add(new BigDecimal("0.5")).toBigInteger(); // this way of rounding assumes positive numbers
BigInteger lostprecision = new BigDecimal(myBI.doubleValue() * d).toBigInteger();
System.out.println("DoubleString: " + doubleWithStringValue);
System.out.println("Unrounded: " + unrounded);
System.out.println("Correct: " + correct);
System.out.println("Lost precision: " + lostprecision);
Output:
DoubleString: 100000000000000000000000000000000000000000000000000000
Unrounded: 100000000000000005551115123125782702118158340454101562
Correct: 100000000000000005551115123125782702118158340454101563
Lost precision: 100000000000000020589742799994816764107083808679919616
The best solution I can see is you use the Math.round function. with code like this.
long l; //your long value
double d;//your fraction
long answer;
answer = Math.round((double)(l * d));
This will give you the answer without a lost prevention error.
The other option would be to truncate it.
same declares as above code.
String s;
s = "" + (l*d);
StringTokenizer token = new StringTokenizer(s);
s = token.nextToken();
answer = Long(s);
Double has a precission of 52 bit. How about:
multiplying your double by (1<<52)
convert double to BigInteger (no loss as full precision is on left of decimal point)
multiply with other BigIngeger
partially correct binary exponent of result (BigInteger>>51)
If odd, do your rounding by adding 1 or BigInteger.Sign (depending on your preferences of rounding)
Finally shift result one more bit (BigInteger>>1)
BigInteger myBI = BigInteger("99999999999999999");
Double d = 0.123;
BigInteger bigDouble = (BigInteger)(d * ((ulong)1 << 52));
BigInteger result = (myBI * bigDouble) >> 51;
if (!result.IsEven)
result += result.Sign;
result = result >> 1;
I need to write a small Java program that deals with calculations involving money. Therefore it needs to have accuracy. (Eg: No float/double variables, only long).
Unfortunately, the original value I need to use is imported through a method which can only read variables as "double".
Now, I tried casting it to a long using a method similar to:
double importedValue = x;
double importedValueConverted = (long) x;
However, when I try dividing importedValueConverted by another "long" variable I get:
required: long
found: double
error: possible loss of precision
Why is that?
double importedValue = x;
double importedValueConverted = (long) x;
Note that both of these variables are declared as 'double'. This results in your error (paraphrasing): (the operation you're doing requires a) long (but when it tried it found a) double.
You want:
double importedValue = x;
long importedValueConverted = (long) x;
Forget all the casting business. If you are working with financial calculations, you can directly use BigDecimal to wrap the doubles returned by your so called method and use an appropriate rounding mechanism provided by BigDecimal that suits your needs.
Update:
This post raised an additional question which I don't think was ever answered-- why use int, or better yet, long or BigDecimal for currency calculations. This is answered here:
Why not to use double or float to represent currency (or where any exact calculations are needed)?
Because floats and doubles cannot accurately represent most base 10
real numbers.
And even when using BigDecimal, one must use the String constructor and not the float one.
This all said, your best bet is to:
Convert all values to cents and store as a long (multiply each dollar amount by 100)
Do the operations in cents
Convert back to dollars by dividing by 100 at the end
This will retain the accuracy desired. Obviously this solution has USD in mind, any conversions to foreign currencies would need appropriate consideration.
Rather than casting, consider rounding to the nearest long value:
double d = 1234.56;
long x = Math.round(d);
Tho really I ask why you'd want to go from a double to a long, as this is going to lose you the precision of the decimal values.
If you want to keep some precision (up to 3 digits, say), and you can absolutely only work with long to do so, you can multiply both doubles by 1,000, then scale all later operations by the same factor, and then scale them all back at the end, like so:
double starting = 1234.5678;
double worker = starting * 1000;
long roundedWorker = Math.round(worker);
// do other computations here...
// due to earlier scaling, adding 1000 is equivalent to adding 1 to the original
long longResult = roundedWorker + 1000;
double threeDigitPreciseResult = longResult / 1000d;
System.out.println("Adding 1 to original number as a long: " + threeDigitPreciseResult);
Update
After getting a better explanation of the problem, it sounds like what you're looking for is the functionality provided by DecimalFormat. Below is a method roundToTwoDecimals() which uses it, along with a test case demonstrating it:
import java.text.DecimalFormat;
import org.junit.Test;
public class ExampleTest {
#Test
public void test() {
double num1 = 29334.32942032432;
double num2 = 438.95940;
double result = num1 / num2;
System.out.println("Before rounding: " + result);
double rounded = roundToTwoDecimals(result);
System.out.println("After rounding: " + rounded);
}
public double roundToTwoDecimals(double d) {
DecimalFormat twoDForm = new DecimalFormat("#.##");
return Double.valueOf(twoDForm.format(d));
}
}
Which prints out:
Before rounding: 66.82697629968585
After rounding: 66.83
You're casting x to a long than trying to assign it to a double.
That doesn't make sense.
If you want a long, you should use a long.
long longValue = (long) 4.64;
If you wanna cast double to long you do below.
double importedValue = 8.0;
long importedValueConverted = (long) 8.0;
System.out.println(importedValueConverted/(long)8);
OUTPUT: 1
double importedValue = x;
double importedValueConverted = (long) x;
you were trying to cast a double to long and reassign the casted value to a double. you should assign it to long.
Why not look at BigDecimal. It works well when I have used it. Be careful using the Double ctor though as Double is not that precise (eg it cannot accurately store 0.1). It may be more useful to use the String ctor for BigDecimal