I need to store GPS coordinates in a database. I've heard that floats are less accurate than decimals. Is that true? If so, what reason is there to ever use floats?
4 Answers
Since Earth equatorial circumference is around 40000 km and longitude spans 360 degrees, it follows that near the equator 1 degrees is equivalent to about 110 km.
Thus:
- 0 digit precision: ±110 km
- 1 digit precision: ±11 km
- 2 digit precision: ±1.1 km
- 3 digit precision: ±110 m
- 4 digit precision: ±11 m
- 5 digit precision: ±1.1 m
- 6 digit precision: ±11 cm
- 7 digit precision: ±1.1 cm
However, the closer you move to the Poles, the smaller the lengths of the parallels becomes.
For example near Paris, which has a latitude of 48 degrees, 1 degree is equivalent to cos(48) * 110 = 74 km
.
Thus:
- 0 digit precision: ±74 km
- 1 digit precision: ±7.4 km
- 2 digit precision: ±0.74 km
- 3 digit precision: ±74 m
- 4 digit precision: ±7.4 m
- 5 digit precision: ±0.74 m
- 6 digit precision: ±7.4 cm
- 7 digit precision: ±0.74 cm
So, field of type DECIMAL(10,7)
would be enough to satisfy you rather precise.

- 45,245
- 23
- 243
- 245

- 3,994
- 3
- 35
- 51
If you want more accurate GPS coordinates, then yes decimals are the way to go. You can create them with a migration like:
create_table "models" do |t|
t.decimal "latitude", :precision => 15, :scale => 10, :default => 0.0
t.decimal "longitude", :precision => 15, :scale => 10, :default => 0.0
end
The reason people use floats is that they are usually precise enough for most use cases and use less space to store.

- 50,956
- 18
- 113
- 146
-
@jac Please see: `http://www.ruby-forum.com/topic/208222` and why decimal doesn't solve your problem. – Anil Jun 15 '12 at 04:44
-
@Anil not sure I follow. I use this in my application instead of floats for higher precision GPS coordinates and it works exactly as I expect it to. – Peter Brown Jun 15 '12 at 15:59
If you want 100% accuracy with your decimals, then multiply by 10**n(where n is your desired precision), and store as integer.
Float objects represent inexact real numbers using the native architecture's double-precision floating point representation.
See:
http://www.ruby-doc.org/core-1.9.3/Float.html

- 3,899
- 1
- 20
- 28
As you can see in Paul's answer, it depends on your use-case.
A float provides a precision of roughly 6 decimal digits.
±11 cm is quite acceptable for, say, an address. and if you're displaying addresses it's unlikely that you are going to do any arithmetical operations that will compound rounding errors.

- 309
- 4
- 12