From: Frank Cisco on
How do you get an accurate addition of a float and an int?

int i = 5454697;
float f = 0.7388774F;

float result = new Integer(i).floatValue()+f;

result=5454697.5 ??

Surely it should be 5454697.7388774? If I use double it's fine, but I need
to use float



From: rossum on
On Tue, 15 Sep 2009 17:17:40 +0100, "Frank Cisco"
<tdyjkdftyujdtjyj(a)dtyjdtyjdtyjdty.com> wrote:

>How do you get an accurate addition of a float and an int?
>
>int i = 5454697;
>float f = 0.7388774F;
>
>float result = new Integer(i).floatValue()+f;
>
>result=5454697.5 ??
>
>Surely it should be 5454697.7388774? If I use double it's fine, but I need
>to use float
Floats are only accurate to about 7 or 8 significant figures. Your
sum has exceeded the limits on the accuracy of floats.

Doubles have an accuracy of about 15 or 16 significant figures so your
sum works with double variables.

rossum

From: Thomas Pornin on
According to Frank Cisco <tdyjkdftyujdtjyj(a)dtyjdtyjdtyjdty.com>:
> How do you get an accurate addition of a float and an int?

By not using the 'float' type. Accuracy of a 'float' is limited.

See: http://en.wikipedia.org/wiki/IEEE_754-1985
A 'float' value is an IEEE 'single-precision' value. For the
values you use:

> int i = 5454697;
> float f = 0.7388774F;
>
> float result = new Integer(i).floatValue()+f;
>
> result=5454697.5 ??

Around 5454697, the only values which can be represented in a 'float'
are 5454696.5, 5454697, 5454697.5, 5454698,... hence Java is accurately
returning you the closest possible value: 5454697.5 is, among the
values which may fit in a 'float', the one which is closest to the
mathematical result of the operation you asked for.

By the way, 'new Integer(i).floatValue()' is a quite convoluted way
to convert an 'int' to a 'float'. '(float)i' would work equally well.


> If I use double it's fine, but I need to use float

If the need for 'float' is absolutely unavoidable (I do not believe it)
then your problem is absolutely without solution.


--Thomas Pornin
From: Patricia Shanahan on
Frank Cisco wrote:
> How do you get an accurate addition of a float and an int?
>
> int i = 5454697;
> float f = 0.7388774F;
>
> float result = new Integer(i).floatValue()+f;
>
> result=5454697.5 ??
>
> Surely it should be 5454697.7388774? If I use double it's fine, but I
> need to use float

5454697.7388774 is not exactly representable in either double or float,
but double can get much closer. The double approximation happens to be
close enough to 5454697.7388774 that its toString() is "5454697.7388774".

Incidentally, "new Integer(i).floatValue()" is unnecessary. i+f would
convert i to float and do the addition.

Float only has 24 significant bits, the equivalent of slightly over 7
significant decimal digits, so you should expect rounding error to
appear around the seventh or eighth decimal digit when adding numbers of
similar magnitude.

If you need exact arithmetic on decimal fractions, you should use
neither double nor float, but BigDecimal. If some rounding error is
acceptable, but you need to get reasonable precision without doing a lot
of numerical analysis, use double.

I strongly recommend against float unless you have a really good
understanding of numerical analysis, and the benefits of float in your
application justify significant extra work, because being sure of
getting usable results from its limited precision is difficult. A
non-trivial calculation with float can have results that are all,
or mainly, rounding error.

Even if your inputs and outputs are in float, you will get better
precision by converting to double for the calculations and converting
back again at the end.

Patricia
From: Frank Cisco on
cheers all! why on earth is float used at all then if it's so inaccurate?