La variable flottante Laravel change de valeur lors de l'ajout à la base de données
-
21-12-2019 - |
Question
Théorie
J'ai une liste de coordonnées assez complète (Latitude et Longitude jusqu'à 7 décimales), que je souhaite continuellement ajouter.Afin d'arrêter la duplication des données, pour chaque coordonnée qui tente d'être saisie, je souhaite vérifier la base de données pour voir si la latitude et la longitude existent, sur la même ligne.
Vérifiez si les coordonnées existent
$coordinate = DB::table('coordinates')
->where('lat', '=', $geocode->getLatitude())
->where('lng', '=', $geocode->getLongitude())
->count();
Migration
Schema::create('coordinates', function(Blueprint $table)
{
$table->increments('id');
$table->float('lat', 10, 7);
$table->float('lng', 10, 7);
$table->timestamps();
});
Lorsque l'adresse de l'utilisateur est convertie, j'ai remarqué que lorsque dd()
la variable latitude, cela donne :
float(53.7960957)
à partir du code dd($geocode->getLatitude());
Lorsque j'essaie de l'ajouter ensuite à la base de données, en supprimant le dd()
, la décimale réelle ajoutée à la base de données est 53.7960968
- Un endroit complètement différent quand on parle de coordonnées !
Pourquoi la décimale passe-t-elle de l'écho sur mon écran à l'ajout à la base de données ?
Dois-je le convertir en float avant de l'ajouter ?Comment puis-je résoudre ça?
La solution
Mise à jour:
Je n'ai pas utilisé MySQL depuis un moment, j'ai donc fait quelques recherches supplémentaires.On dirait que decimal
taper a la capacité d’être précis jusqu’à 65 chiffres.Puisque vous n'avez besoin que de 7 chiffres après la virgule et de 3 avant la virgule, vous ne devriez avoir aucun problème à créer un schéma avec decimal(10,7)
.
En supposant que vous utilisez MySQL, vous ne pouvez pas faire grand-chose.Selon La documentation, float
et double
les types sont des représentations approximatives :
Les types FLOAT et DOUBLE représentent des valeurs de données numériques approximatives.MySQL utilise quatre octets pour les valeurs en simple précision et huit octets pour les valeurs en double précision.
Regarde aussi ceci Violon SQL, vous verrez que MySQL 5.5.32 représentera un flottant de 53.7960957
comme 53.796100616455
et un double de 53.7960957
comme 53.7960957
.Vous souhaiterez peut-être mettre à jour votre schéma pour utiliser des doubles à la place, pour un peu plus de précision.
Vous pouvez également spécifier la précision d'un float avec une syntaxe non standard (ce n'est donc pas recommandé, pour des raisons de portabilité vers d'autres standards SQL) en utilisant float(m,d)
où m
est le total des chiffres et d
est le nombre de chiffres après la virgule.Par exemple, si vous souhaitez autoriser les valeurs de latitude/longitude (-180 à 180) avec jusqu'à 7 chiffres de précision après la virgule... vous devriez pouvoir créer votre tableau avec float(10,7)
.Mais, comme tu le verras, ce n'était toujours pas aussi précis que le double.
Autres conseils
comme dit l'auteur...utilisez DOUBLE au lieu de FLOAT ...
vous pouvez également utiliser la notation 1E6 pour que ce soit un entier à enregistrer dans MySQL.
53.7960957 * 1E6 = 537960957
537960957 / 1E6 = 53.7960957
c'est ainsi que j'utilise pour enregistrer les géocoordonnées