> why isn't it 1890
Some numbers that can be represented exactly in base-10 cannot be represented exactly in base-2.
For example, one-tenth in base-10 is 0.1
In base-2, you cannot represent this number exactly. It is a repeating fraction, just like one-third is in base-10.
0.1 = 1/2
0.01 = 1/4
etc.
Try to get those negative powers of 2 to add up to exactly one-tenth. You can't do it.
There are uncountably infinitely many numbers in the range covered by double, but only a finite number of bits with which to represent them. Many of them (uncountably infinitely many) cannot be represented exactly, so an approximation will be used.
> and how can I get 1890?
Use java.text.DecimalFormat to format the output, or use java.math.BigDecimal.
> thank you but can you give me an example of how i can
> do arthmetic on decimal numbers in java with out this
> problem?
Read the API docs for the classes I mentioned, or google for examples with those classes. Give it a shot, and if you can't get it to work like you want, post your code with details about whatever problems you're having.
The input and output numerals are based on the base or radix 10 (decimal system).
1 * 10`1 + 8*10`0 + 9*10`-1 = 18.9
But the computer uses for the numerals the binary system base on the base 2.
1*2`4 + 0*2`3 + 0*2`2 +1*2`1 + 0*2`0 + 1*2`-1+1*2`-2+1*2`-3+0*2`-3+......
The problem are the transformations from the decimal to the binary system and reverse. In both cases a limited number of bytes is used. Therefore you get the differences.
Using BigDecimal delivers precise results, because they use a BCD (binary coded decimals) representation.
public static void main(String[] args) {
double factor1 = 18.9;
double factor2 = 100;
double result = factor1 * factor2;
System.out.println(" 18.9 * 100 = " + result);
BigDecimal bdFactor1 = new BigDecimal("18.9");
BigDecimal bdFactor2 = new BigDecimal("100");
System.out.println(" 18.9 * 100 = " + bdFactor1.multiply(bdFactor2));
}
Result:
18.9 * 100 = 1889.9999999999998
18.9 * 100 = 1890.0
I am doing:
BigDecimal bdfirst = new BigDecimal(first);
BigDecimal bdsecond= new BigDecimal(second);
BigDecimal bdtrunc = bdfirst.multiply(bdsecond);
System.out.println(first+" * "+second+" = "+bdtrunc.toString());
my result is:
747.5 * 0.09 = 67.27499999999999751032486727808645810000598430633544921875
the answer should be 67.275 - why am I getting this imprecise value still?
Because you are creating your BigDecimals from the imprecise doubles. TryBigDecimal bdfirst = new BigDecimal("747.5");
BigDecimal bdsecond= new BigDecimal("0.09");
BigDecimal bdtrunc = bdfirst.multiply(bdsecond);
System.out.println(bdfirst+" * "+bdsecond+" = "+bdtrunc.toString());
ok here is the problem
System.out.println(bdfirst.toString()+" * "+bdsecond.toString()+" = "+bdfirst.multiply(bdsecond));
747.5 * 0.0899999999999999966693309261245303787291049957275390625 = 67.27499999999999751032486727808645810000598430633544921875
So when i create my big decimal objects and pass the constuctor the double as argument, the real number is stored imprecisely mucking up my calculation. Is the solution to convert my doubles to strings before creating the bigdecimal? i can't possibly store all these values as strings - it would require a overhaul of my whole application. any tips?
> last question i promise
>
> if I take my double and do a new double().toString()
> will this be effective for all cases or should i just
> retrieve my values as strings directly from the DB
I don't see what you can hope to achieve with this. It probably won't work because once you place a value in a double the damge is done.
Use double and DecimalFormat.
> if I take my double and do a new double().toString()
> will this be effective for all cases or should i just
> retrieve my values as strings directly from the DB
Don't use:
double someValue = 5;
String string = new Double(someValue).toString();
Use this instead:
double someValue = 5;
String string = Double.toString(someValue);
Or use a DecimalFormat, as necessary. I don't know much about retrieving the values from the database. But, using the second version above eliminates the unnecessary construction of a Double.
I'm sorry
just to be clear
If i use a double, then convert it to string to be used with BigDecimal, will I run into this problem or should I only be working with Strings? From what I can tell so far, Double.toString() seems to be giving me accurate numbers so is it correct for me to assume that my real number stored in a double will always be returned to me correctly unless i perform arithmetic on it?