I would like to convert a double (for example price with a value of 1.90) to an integer without losses! I am making a program that processes money, and I have to input them as doubles, and then convert them to integers so that I can proccess them and for example when I have 1.90 euros and i want to convert it to cents it will appear as 189 cents instead of 190! please help me :) thanks in advance
Check the details on how doubles and floats behave in java in the JLS
Well, you could round the value to desired precision. As long as you're within given format's precision (~15 digits for double ~7 for float) you'll get good results.
double fractValue = 1.90; // 1.8999999....
int val = (int)Math.round(fractValue*100);
It's much better idea to use BigDecimal though. You will never lose any precision then.
double x = 1.89; //Or whatever
String[] y = String.valueOf(x).split("[.]"); // Returns array having 1 and 89
String z = y[0] + y[1]; //String which is = 189
if(y[1].length()==1)
z +="0"; // Add a 0 in end if required
int finalInt = Integer.parseInt(z); //Convert String to Integer
finalInt should be what you want.
Related
I would like to initialize a double directly by using the hexadecimal-notation. I know this works for int and Long as shown in the following example (resulting values always right):
int i = 0x10000000; // 268435456
Long li = 0x1000000000000000L; // 1152921504606846976
On the other hand, if I try do the same with doubles, it works but only in range of 4 Bytes (view comments in the code example). For the second, not valid notation the Netbeans IDE keeps telling me that is is an integer value and, thus, too large:
double d1 = 0x10000000; // 2.68435456E8
double d2 = 0x1000000000000000; // not valid
float-values work as well as they are in the range of 4 Bytes:
float f1 = 0x10000000; // 2.68435456E8
Is there a way to directly write/initialize a double with hexadecimal-notation?
Is the only reason for being able to write a Long with hex-notation that there is no "L" in this notation (in contrast to "f" for float or the not valid "." for marking doubles)?
Why is there a limitation to 4 Bytes? And why does it apply to double and not to Long?
Thank you for your advise and suggestions.
Java supports floating-point hexadecimal literals since 1.5
double d = 0x1f.1p1;
If you just want to initialize your double with an integer value in the long range, use:
double d2 = 0x1000000000000000L;
You can also supply integer hexadecimal values outside the long range using BigInteger:
double d3 = new BigInteger("123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0", 16).doubleValue();
If you need to supply hexadecimal fractions, as suggested in the previous answer, use a hexadecimal floating point literal:
double d = 0x1F.1p1;
This is my code :
double width = 50/110000;
System.out.println("width ori is "+width );
And the output is: 0.00000000000
What's wrong ? the expected output has to be 4.5454545454545455E-4
Any body can explain to me why?
Because you're dividing two integers, so it will only take the integer part (integer division).
Dividing integers in a computer program requires special care. Some
programming languages, treat integer division (i.e by giving the integer quotient as the answer). So the answer is an integer.
Examples :
In real life In Java
4/3 = 1.33333 4/3 = 1
25/12 = 2.083333 25/12 = 2
9/2 = 4.5 9/2 = 4
50/110000 = 0.000454545 50/110000 = 0
You can cast one of the number (or both but it's actually useless) to double to avoid that :
double width = (double)50/110000;
double width = 50d/110000;
double width = 50.0/110000;
Result of int/int returns you an integer.
So the decimal part got truncated resulting you with an integer
You need to cast:
double width = (double)50/110000;
As #Josh M has pointed, You can also try :
double width = 50d / 110000d;
Explanation to what's happening:
In Java, the default type of numbers is int, so when you write 50/110000, they're both considered int, although you defined the result to be double.
When int division occurs, the result will be 0, because they are both ints, then the double will hold this value, which will be represented as double, so you're getting 0.000000.
Possible solutions:
Coding these numbers with d: 50d/110000d.
Casting one side explicitly (the other will be implicitly cast): (double)50/110000.
50.0/110000.
See Chapter 5. Conversions and Promotions, it'll really help you.
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
I have to write a program with the following requirements:
I have a variable of type float, say float a = 3333.333f;
I have a variable of type int, say int b = 9999;
When I perform a*b in calculator, the result will be 33329996.667
After rounding up the decimals to 2 places, I want to print the value as 33329996.67 in java. I tried with long, double, float, big decimal, But couldnt succeed.
Can anyone please help me solving this?
float only has 7 digits of precision, so its not a good choice for a result with more than 7 digits. double has up to 16 digits of accuracy and is a better choice.
double a = 3333.333;
int b = 9999;
System.out.printf("%.2f", a * b);
prints
33329996.67
To determine the number of digits after the comma you have to apply a little trick:
First shift the comma to the right for the amount of digits you want to have, then cut the whole number e.g. with Math.ceil(float f) and then shift the comma back to the left.
That will illustrate that:
float f = 33329996.667;
float f2 = Math.ceil((f * 100)) / 100;
f2 now has the value 33329996.67.
Hope this helps.
EDIT: For formatting have a look here
I need to convert a string with value 12.10 to a float value without losing the zero. How can I achieve this in Java.
if you aren't worried about memory then
String str = "12.00";
BigDecimal bd= new BigDecimal(str);
System.out.println(bd);//12.00
a) It makes no sense to store trailing zeroes in a float.
b) 12.1 will not map precisely to a floating point value (although this may not be immediately apparent)
From Bloch, J., Effective Java, 2nd ed, Item 48:
The float and double types are
particularly ill-suited for monetary
calculations because it is impossible
to represent 0.1 (or any other
negative power of ten) as a float or
double exactly.
For example, suppose you have $1.03
and you spend 42c. How much money do
you have left?
System.out.println(1.03 - .42);
prints out 0.6100000000000001.
The right way to solve this problem is
to use BigDecimal, int or long
for monetary calculations.
Example:
BigDecimal price = new BigDecimal("12.10");
Use a java.text.DecimalFormat:
DecimalFormat fmt = new DecimalFormat("0.00");
double floatval = fmt.parse("12.10").doubleValue();
String sval = fmt.format(floatval);