• Post Reply Bookmark Topic Watch Topic
  • New Topic

problem in java math function  RSS feed

 
mukesh pandey
Greenhorn
Posts: 22
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
 
Karthik Shiraly
Bartender
Posts: 1210
25
Android C++ Java Linux PHP Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
 
Artem Bihle
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Try using BigDecimal.
 
pete stein
Bartender
Posts: 1561
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
 
Charles Bradley
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Android C++ Java Linux PHP Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!