Win a copy of OCP Java SE 8 Programmer II Exam Study Guide this week in the OCP forum!
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
Sheriffs:
Saloon Keepers:
Bartenders:

# problem in java math function

Greenhorn
Posts: 22
hi...

when i divide any integer say (126812) when i divide this int with 3600 i get 35.22555555555556 now i again multiply it to 3600 but i don't get exact 126812 in return i get some double in points like 126812.00000001 but i need exact value in return caz i m using that value as key in key value pair for a map. please help me how can i get the exact value..and i have hell lots of values like dis

Bartender
Posts: 1210
25
Hi Mukesh,

Some floating point operations require more precision than is available in the system. The result is approximated to fit the available precision. When that result is reused in the inverse operation, you won't get back the original value because of this approximation. This happens in our own calculations too: For example,
7/3 = 2.3333333333 (recurring).
If you multiply this result with 3, you won't get 7, you'll get 6.9999999999 (recurring) which is not quite 7.

One solution would be use Math.round() to get the integer (or long) closest to the double, and use that as the key.

But have you thought through the approach of making a multiplication result as a key? Normally, keys should be unique. But other multiplications may also result in the same key inadvertently replacing a value.

Cheers
Karthik

Greenhorn
Posts: 1
Try using BigDecimal.

Bartender
Posts: 1561

mukesh pandey wrote:hi...

when i divide any integer say (126812) when i divide this int with 3600 i get 35.22555555555556 now i again multiply it to 3600 but i don't get exact 126812 in return i get some double in points like 126812.00000001 but i need exact value in return caz i m using that value as key in key value pair for a map. please help me how can i get the exact value..and i have **** lots of values like dis

Please read up on the inaccuracies that are inherent within any floating point type of number:
floating point

The solution: never use a floating point number as a key.

mukesh pandey
Greenhorn
Posts: 22
hi I agree that i should not use floating kind of number as map but its my requirement, what I am doing is i am mapping a location with the latitude and longitude. latitude and longitude can be float, so here lat and long are key and the location of that area is value. that y i need to use this kind of number as key to key value map

mukesh pandey
Greenhorn
Posts: 22
and one more thing round function can't be used here caz the definition of round function is =(int)Math.float(a +.5) so what it does is it always gives the next higher value as its adding .5 by its own. while i need a nearest value

Ranch Hand
Posts: 32
Round adds .5 and then truncates. 8.1 + 0.5 = 8.6 -> 8, but 8.6 + 0.5 = 9.1 -> 9 so round rounds to the closest integer.

Actually x.5 is half way between x and x.1, so it is equally close to x and x+1. Every floating point implementation that I have ever seen has x.5 round to x+1. That way, exactly half of the bit patterns for the y part of x.y round to x and half round to x+1.

This description only applies to floating point numbers that actually have the integer and fractional parts. For example, 12345678901234567890.6 has no information about the .6 when in float format.

Karthik Shiraly
Bartender
Posts: 1210
25
Hi Mukesh,

Since the values in question are latitude/longitude values, I feel you can take an approach like this: Lat/lng values have a set precision (for example, a precision upto 6th decimal place represents around 10 centimeters). Now it's unlikely you'll have more than 1 location within 10 cm. So multiple your floating values by 10^6, round to int/long and use them as keys (maybe combine them into a simple class). Use both rounded values to create a fairly unique hashCode for each combination. As Artem said, you can in fact also use BigDecimal with 6 point precision, instead of rounding to int/long.
For lookups, take the values returned by the mapping platform, use only upto 6 decimal points (using BigDecimal) and then do the lookup. As long as all BigDecimals are used with same precision, you can get exact matches without requiring some kind of tolerance calculation.

Cheers
Karthik

 It is sorta covered in the JavaRanch Style Guide.