La variable flotante Laravel cambia el valor al agregar a la base de datos
-
21-12-2019 - |
Pregunta
Teoría
Tengo una lista de coordenadas bastante completa (latitud y longitud con 7 decimales), que quiero agregar continuamente.Para detener la duplicación de datos, para cada coordenada que se intenta ingresar, quiero verificar la base de datos para ver si la latitud y la longitud existen, en la misma fila.
Comprueba si existen coordenadas.
$coordinate = DB::table('coordinates')
->where('lat', '=', $geocode->getLatitude())
->where('lng', '=', $geocode->getLongitude())
->count();
Migración
Schema::create('coordinates', function(Blueprint $table)
{
$table->increments('id');
$table->float('lat', 10, 7);
$table->float('lng', 10, 7);
$table->timestamps();
});
Cuando se convierte la dirección del usuario, he notado que cuando dd()
la variable de latitud, sale como:
float(53.7960957)
del código dd($geocode->getLatitude());
Cuando intento agregarlo después a la base de datos, eliminando el dd()
, el decimal real que se agrega a la base de datos es 53.7960968
- ¡Una ubicación completamente diferente cuando hablamos de coordenadas!
¿Por qué el decimal cambia de hacer eco en mi pantalla a agregarse a la base de datos?
¿Necesito convertirlo en flotante antes de agregarlo?¿Cómo puedo resolver esto?
Solución
Actualizar:
No he usado MySQL por un tiempo, así que investigué un poco más.Parece el decimal
tipo tiene la capacidad de ser preciso hasta 65 dígitos.Dado que solo necesita 7 dígitos después del decimal y 3 antes del decimal, no debería tener problemas para crear un esquema con decimal(10,7)
.
Suponiendo que esté utilizando MySQL, no hay mucho que pueda hacer.De acuerdo a la documentación, float
y double
Los tipos son representaciones aproximadas:
Los tipos FLOAT y DOUBLE representan valores de datos numéricos aproximados.MySQL utiliza cuatro bytes para valores de precisión simple y ocho bytes para valores de precisión doble.
Mira también esto Violín SQL, verás que MySQL 5.5.32 representará un flotante de 53.7960957
como 53.796100616455
y un doble de 53.7960957
como 53.7960957
.Es posible que desee actualizar su esquema para utilizar dobles en su lugar, para obtener un poco más de precisión.
También puede especificar la precisión de un flotante con sintaxis no estándar (por lo que no se recomienda para portabilidad a otros estándares SQL) usando float(m,d)
dónde m
son los dígitos totales y d
es el número de dígitos después del decimal.Por ejemplo, si desea permitir valores de latitud/longitud (-180 a 180) con hasta 7 dígitos de precisión después del decimal... debería poder crear su tabla con float(10,7)
.Pero, como verás, esto todavía no era tan preciso como lo era el doble.
Otros consejos
como dice el escritor...utilice DOBLE en lugar de FLOTADOR...
También podría usar la notación 1E6, por lo que sería un número entero para guardar en MySQL.
53.7960957 * 1E6 = 537960957
537960957 / 1E6 = 53.7960957
esta es la forma que estoy usando para guardar coordenadas geográficas