2015-02-26 3 views
0

Мне нравится хранить широты и долготы очень точно в моей базе данных MySql с помощью InnoDB. Тем не менее, float не предлагал достаточно внутренних десятичных знаков, поэтому я переключился на двойной. Чувствуя себя немного, но MySql принял двойной размер до 30, поэтому я использовал double (30,27), потому что нужны только 3 регулярных места, а остальные должны быть за запятой.MySql и float или double обведите мой номер, когда я обновляю его на запрос с php

Хорошо, что в MySql, который работал до сих пор, и с другой стороны, я получаю поплавки над json_decode, и когда я повторяю их, у них есть до 18 или 19 мест после запятой. Так что даже здесь все, как ожидалось.

Но когда я создаю запрос на обновление для заполнения пустых двойных полей (double 30/27), он просто заполняет все цифры нулем, освобождая первые 9 цифр. Или иногда начинается начало правила с 7 цифр с линией 9s.

Например, когда я обновляю 47.2608691999999877 в MySQL - независимо от того, если в сценарий или за PhpMyAdmin, после или выписки кнопки сохранения +47,260869199999990000000000000 появляются в таблице, где 47,260869199999987700000000000 должны появиться или

+11,396251100000000633, как обновление в таблицу дает мне 11.396251100000000000000000000

Похоже, что он игнорирует возможные места, начиная с 7. или иногда заполняет его 9, но в большинстве случаев есть только нули.

Может ли кто-нибудь дать мне совет для решения этой проблемы, пожалуйста?
Помните, что я также получаю проблему с PHPMyAdmin, но из PHP. Теперь я не уверен, что это проблема MySQL или PHP.

Спасибо

Так, например я MySql я могу хранить это легко по, например PHPMyAdmin:

+0

Если вам нужна точность - используйте 'DECIMAL'. –

ответ

1

Обратите внимание, как DOUBLE (30, 27) имеет смысл для 16-17 значащих цифр, а затем пошло наперекосяк?

FLOAT имеет 24 бита точности. Этого достаточно для 7 значащих цифр. В частности, для широты и долготы это достаточно точно, чтобы попасть в пределах 1,7 метра (5,6 фута). Для большинства приложений lat/lng этого достаточно.Таким образом, на самом деле не имеет значения, что при вставке (преобразовании из десятичной в двоичную) и другой ошибке при чтении (конвертация обратно в десятичную) возникает ошибка округления.

DOUBLE имеет 53 бит точности, около 16 значащих цифр - 3,5 нанометта с севера на юг или восток-запад!

DOUBLE (30, 27) - В случае ВСТАВКИ, он говорит (1) круглым до 27 знаков после запятой, (2) округляет до 53 бит точности. Когда вы читаете, он отменяет шаги, приводя к странным беспорядкам, которые у вас есть.

Я никогда не видел действительной потребности в использовании (M, N) на FLOAT или DOUBLE. Не делай этого.

Для DECIMAL (M, N) вы храните точно, что соответствует N знакам после запятой. Для целей lat/lng рассмотрите DECIMAL (6,4) для широты и (7,4) по долготе - 16 метров (52 фута). Или, для большей точности, (8,6) и (9,6) - 16 см (6 дюймов). Обратите внимание, что FLOAT занимает 4 байта (всегда), DOUBLE: 8, DECIMAL (6,4): 3, (7,4): 4, (8,6): 4, (9,6) : 5. Если у вас есть миллиарды записей lat/lng, байты хранения складываются.

+0

В связи с тем, что на самом деле невозможно представить все возможные значения lat/long с правильной точностью 16 цифр, я бы сказал, что правильным ответом является переход к целочисленным данным type (поэтому десятичные числа, так как это фиксированное десятичное место), если математика будет предпринята, то разные показатели по числам могут иметь значительную потерю точности, и в дополнение ко всему этому из-за динамического набора PHP это может вызвать проблемы в неожиданных местах. Тем более, что мы выставляем цифры для показа. –

+0

PHP использует 32-битные целые числа. Степени * 10000 могут храниться в MEDIUMINT (3 байта) и давать вам разрешение 2,7 метра (8,8 фута). INT предоставит вам менее 10 значащих цифр. Я не могу представить, почему вы считаете необходимым хранить «16 цифр точности», и я не могу представить, какая система даст вам такую ​​точность. –

+0

Целочисленные числа PHP зависят от платформы, поэтому в любой разумной операционной системе 64-разрядная ОС означает 64-разрядные целые числа со знаком (хотя в документации на php5.5 указано, что окна всегда считаются 32-разрядными.), Что и для этого уровня в латах/длинных координатах , Я могу представить, что это разрешение является частью спецификации ASTERIX. –

-1

Я не стал бы доверять любые числа с плавающей точкой для Шир/хранения, вы почти гарантированно иметь ошибки округления. Числа с плавающей запятой просто не так точны.

Рассматривали ли вы фиксированной точкой целое число (47,2608691999999877 становится 472608691999999877 путем умножения и деления на 10000000000000000 при необходимости для отображения/возвращения из входного сигнала (или даже просто просто выполняет операцию строки для отображения.)

Числа такого масштаба должно соответствовать довольно комфортно в диапазоне от 64 разрядных целого числа (черт, вы даже можете получить 17 знака после запятой и по-прежнему будете в порядке.: P)

+0

См. Мой ответ на вопрос, почему я это понизил. –

+0

@RickJamesI просто прочитал ваш ответ, рядом, но без сигары (но эффективно вы сбиваете с толку значение с точностью). Я бы свернул его вручную и использовал целые числа или синтаксический анализ вместо численного разбора или даже сохранил как строки (просто чтобы убедиться что преобразование с плавающей запятой dosnt испортит его.) –

0

Ваш сценарий и PHPMyAdmin писали на PHP, который использует точность для дисплея поплавка числа, но числа дескрипторов mysql и php как можно точнее.

Попробуйте изменить настройку .ini точности: http://php.net/manual/ru/ini.core.php#ini.precision