Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java - remove float leftovers elegantly

In brief - I am having a hard time with the float left overs
(i.e. 10.00000123 instead of 10)

Here I go :

I need to generate list of floats with constant gap as follows (actually its a map , I need to retreive the object nut nevermind that)

List A: 0.25, 0.5, 0.75, 1, ...
or
List B: 0.01, 0.02, 0.03, 0.04, ...

every time I get a number and I round it to the neerest cell in the list.
lets say I get 0.051 to retreive a cell in list A - I return 0.05.
lets say I get 0.21 to retreive a cell in list B - I return 0.25.

So I started be doing this

float a = Math.round(Value / step) * step;

but than I get a lot of time 0.2500001 (float leftovers ) I need a smart way to round it .

Maybe by taking the number of digits after the dot and doing again

Math.round(Value / 100) * 100;?

Is there a smarter way? I tried doig this

        final float factor = Math.round(1 / step);
        final float value = (float) Math.round(value * factor) / factor;

but I sometimes have a list like this

List A: 10, 15 , 20, 25, 30, ...

and when I get 22 I retreive the cell of 20. the problem is that When I get a gap of 10

Math.round(1 / baseAssetStep) 

returns 0 - and I get NaN

like image 860
Bick Avatar asked Jun 19 '26 11:06

Bick


2 Answers

Use BigDecimal instead of float.


From the Java Tutorials of Primitive Data Types:

float: [...] This data type should never be used for precise values, such as currency. For that, you will need to use the java.math.BigDecimal class instead. Numbers and Strings covers BigDecimal and other useful classes provided by the Java platform.

like image 200
Peter Lang Avatar answered Jun 21 '26 02:06

Peter Lang


Firstly, I would use double or long instead as these have much more digits of accuracy. If you really need to, use BigDecimal, but its pretty rare to find a real world situation where double or long would not do the job.

double d = 10.00000123;
double r = Math.round(d * 10000) / 10000.0;

or using long with fixed point precision.

long l = 100000; // the actual value * 10000

A common use case for fixed point precision is money. Instead of using dollars with double use cents with long or even int instead.

like image 35
Peter Lawrey Avatar answered Jun 21 '26 01:06

Peter Lawrey