[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Глюк числа с плавающей точкой
vagon
Здравствуйте! Есть такой код:

$us = 0.015; // вынимается из базы, тип поля FLOAT, может меняться от 0.0001 до 0.1
$rb = 99; // вынимается из базы, тип поля INT, может меняться от 1 до 100
$r = 0.005; // вынимается из базы, тип поля FLOAT, может меняться от 0.001 до 0.01

$u = $us + $r / 100 * $rb;
$r = $r - $r / 100 * $rb;


После всех этих вычислений, в БД пишутся переменные $u и $r, причем $u пишется в номальном виде, а $r записывается как 1e-05 вместо 0.00005
хотя тип полей в базе одинаковый.

Пишется в базу примерно так:

$sql = "UPDATE `summ` SET `money`=`money`+$r WHERE `id`=1";

Нужно чтобы писалось нормальное число с плавающей точкой, вместо 1e-05

В чем причина, и как решить проблему?



Спустя 19 минут, 6 секунд (31.03.2011 - 15:12) nugle написал(а):
попробуй писать в abs()

правда с минусами не прокатит

И правильно заносит пишет 1 * 10 -5 степени

или intval() попробуй

Спустя 10 минут, 30 секунд (31.03.2011 - 15:22) vagon написал(а):
С минусами и не нужно. Но abs() не помог. intval вернет целое, а мне нужно именно число с плавающей точкой.
Самое интересное, что если в поле изначально стоит 0, то запишется 1E-05 а если поставить что-то типа 0.0001 то приплюсуется нормально.

Спустя 17 минут, 25 секунд (31.03.2011 - 15:40) T1grOK написал(а):
какая вам разница. Число то получается в итоге одно и тоже!

Спустя 3 минуты, 40 секунд (31.03.2011 - 15:43) vagon написал(а):
Разница огромная. Мне с такими степенями весь скрипт придется переделывать. И все из-за одного кусочка кода, который работает не так как любой другой кусок.

Спустя 4 минуты, 5 секунд (31.03.2011 - 15:48) Trianon написал(а):
Цитата
Нужно чтобы писалось нормальное число с плавающей точкой, вместо 1e-05


У Вас всё корректно пишется.
Запись 1e-05 и есть число с плавающей точкой.
В то время как 0.00001 - вполне может оказаться числом с точкой фиксированной.

Если Вы не знаете, что означает тот или иной термин, не пытайтесь им оперировать.

Спустя 3 минуты, 36 секунд (31.03.2011 - 15:51) vagon написал(а):
Хорошо. Я не программист, но я думаю что всем и так понятно что требуется вместо 1e-05 писать 0.00001. Это для меня проблема. Есть решение?

Спустя 22 секунды (31.03.2011 - 15:51) T1grOK написал(а):
Цитата (vagon @ 31.03.2011 - 12:43)
Разница огромная. Мне с такими степенями весь скрипт придется переделывать. И все из-за одного кусочка кода, который работает не так как любой другой кусок.

Зачем же весь скрипт переделывать добавьте формат для флоат поля при выборке и все

Спустя 6 минут, 9 секунд (31.03.2011 - 15:58) vagon написал(а):
Цитата
Зачем же весь скрипт переделывать добавьте формат для флоат поля при выборке и все


Т. е.
SELECT FROM ......................
$r = floatval($row[r]); - так что-ли?
Уже пробовал, не помогает.

Спустя 1 минута, 22 секунды (31.03.2011 - 15:59) Trianon написал(а):
vagon
Цитата
всем и так понятно что

Отнюдь. В самой БД вещественное число пишется ни так 1e-05 , ни так 0.00001. При чем ни формат хранения, ни формат вывода обычно ни у кого проблем не вызывает.

Цитата
требуется вместо 1e-05 писать 0.00001. Это для меня проблема. Есть решение?


Если хотите на выходе иметь 0.00001 - можете преобразовать (в SELECT-запросе) величину к типу DECIMAL(M, N) ( В частности запись 9.99999 соответствует типу DECIMAL(6,1))
Если хотите, чтобы оно так хранилось - можете изменить тип поля на DECIMAL в самой таблице.

Вот только работать с ним окажется медленнее, да и памяти оно будет занимать больше. Оно Вам надо?

Спустя 2 минуты (31.03.2011 - 16:01) T1grOK написал(а):

Спустя 46 минут, 39 секунд (31.03.2011 - 16:48) vagon написал(а):
Цитата
Зачем же весь скрипт переделывать добавьте формат для флоат поля при выборке и все
- ничего не понял из того что написано, по Вашей ссылке.
Последние 2 поста просто взорвали мозг. Все это для продвинутых программистов. Почему вообще такое происходит? Нулей после запятой слишком много? Неужели нет решения проще? Обязательно делать приведение типа в SELECT? Там то точно все нормально. Нельзя ли преобразовать как-то перед записью в базу?

Спустя 21 минута, 57 секунд (31.03.2011 - 17:10) nugle написал(а):
vagon
с abs() попробывали?

Спустя 1 минута, 38 секунд (31.03.2011 - 17:11) vagon написал(а):
Цитата
с abs() попробывали?

Пробовал, ничего не меняется.

Спустя 8 минут, 36 секунд (31.03.2011 - 17:20) Trianon написал(а):
Решения нет, и не будет, поскольку Вы не описали, в чем состоит проблема.
С одной стороны Вы говорите, что в SELECT всё нормально.
С другой, что в базе не точисло, хотя тут же сообщаете, что число ровно то, которое нужно.
Где у Вас не то число?


Спустя 5 минут, 51 секунда (31.03.2011 - 17:26) nugle написал(а):
не получается потому что возвращается строка, но опирировать можно как с числом, не получиться просто записать!работайте с таким числом, ничего не измениться!

Спустя 14 минут, 59 секунд (31.03.2011 - 17:41) vagon написал(а):
Trianon, похоже, Вы действительно настоящий программист, им обычных людей не понять никогда, впрочем как и обычным людям их smile.gif

Попробую еще раз объяснить как смогу, уж не судите строго если снова не получится...

Если я открываю phpMyAdmin, то в любой из ячеек summ вижу такое:
0.0001
1.5
0.9005
60.00015

и так далее... - Все в порядке.

Решил кое-что доработать в очередной раз , и вот что я вижу в одной из ячеек базы данных: 1e-05 - это вместо привычного:

0.0001
1.5
0.9005
60.0000015

Еще раз повторюсь, я не программист, и не знаю как работать с такими значениями как 1e-05.

Спустя 3 минуты, 12 секунд (31.03.2011 - 17:44) nugle написал(а):
vagon
ты попробуй своё число вывести через echo и получиться 1e-05,
эта запись означает 1 в -5 степени!
а что сложно с ними работать? так же умножать вычитать

Спустя 4 минуты, 47 секунд (31.03.2011 - 17:49) alex12060 написал(а):
Вам надо сдавать таблицу на првоерку программисту что-ли?
Оставьте так, как есть. Это то-же самое число, что Вам и нужно, просто записано в сокращенной форме. Научитесь представлять одно с другим, и, тогда гемора не будет.

С этими числами можно вести такие-же операции, как и с другими.

Спустя 5 минут, 14 секунд (31.03.2011 - 17:54) Ulan написал(а):
Цитата (nugle @ 31.03.2011 - 14:44)
эта запись означает 1 в -5 степени!

1 умножить на 10 в -5 степени smile.gif

Спустя 2 минуты, 28 секунд (31.03.2011 - 17:56) vagon написал(а):
Цитата
ты попробуй своё число вывести через echo и получиться 1e-05

Если я вывожу через echo 0.0001 то и выводится 0.0001. Если я вывожу 1e-05 то и выводится 1e-05. В этом и проблема.

Спустя 4 минуты, 49 секунд (31.03.2011 - 18:01) Ulan написал(а):
с точки зрения математики и компьютера числа 0,00001 и 1e-05 равны. точней это две записи одного и того же. но удобнее работать со вторым представлением, т.к. сразу видно порядок числа.

Спустя 7 минут, 6 секунд (31.03.2011 - 18:08) vagon написал(а):
Цитата
Вам надо сдавать таблицу на првоерку программисту что-ли?


на првоерку программисту мне ничего сдавать не нужно. Мне нужно чтобы работало все правильно smile.gif А некоторые ко многим вещам относятся крайне небрежно smile.gif

Цитата
с точки зрения математики и компьютера числа 0,00001 и 1e-05 равны. точней это две записи одного и того же. но удобнее работать со вторым представлением, т.к. сразу видно порядок числа.

Я же писал что не знаю как работать с такими вещами smile.gif Через echo выводится эта нечеловеческая билиберда, и другие файлы скрипта просто не будет работать с такой шляпой. Иначе бы я просто не создавал эту тему.

Спустя 37 секунд (31.03.2011 - 18:09) Invis1ble написал(а):
vagon
Попробуй так:
$float = .000000001;
printf('%.10f', $float);

Можно так еще:
$float = .000000001;
echo number_format($float, 10);

Спустя 1 минута, 42 секунды (31.03.2011 - 18:11) Ulan написал(а):
почему это не будут, будут
Double - вещественное число довольно большой точности (ее должно хватить для подавляющего большинства математических вычислений).

Числа с плавающей точкой (они же числа двойной точности или действительные числа) могут быть определены при помощи любого из следующих синтаксисов:

<?php
$a = 1.234;
$b = 1.2e3;
$c = 7E-10;
?>

Спустя 3 минуты, 19 секунд (31.03.2011 - 18:14) vagon написал(а):
Цитата
почему это не будут, будут

Потому что это проверено, не работают. Все до единого, конечно же не проверял.

Спустя 20 минут, 58 секунд (31.03.2011 - 18:35) Trianon написал(а):
Цитата
Потому что это проверено, не работают. Все до единого, конечно же не проверял.

Если не работают некие файлы, так наверное нужно чинить именно их?

Вы пока что утверждаете, что не в файлах дело, а в phpMyAdmin.
Что в нем видите не то что надо.
Показывайте скрипты, которые не хотят работать.

Альтернативные варианты (без плавающей точки) я вам тоже описал.



Касательно нормальных людей.
Когда я учился в школе, этот материал был засунут куда-то в район 6 класса обычной школьной программы.
Про компьютеры, правда, ничего не говорилось (тогда обычный калькулятор был доступен далеко не каждому), но что 0.0001 можно записать как 1 умножить на десять в минус пятой степени, приходилось знать всем. Равно как и про нормальную форму, мантиссу и порядок.

Спустя 18 минут, 51 секунда (31.03.2011 - 18:54) vagon написал(а):
Invis1ble
Цитата
vagon
Попробуй так:


С выводом не пробовал, это второстепенная задача. Главное записать в базу...
$r тянется SELECT-ом из базы, так:


$r = .$row['r'];
$r = number_format($r, 10);


получается ошибка синтаксиса из-за точки.

Спустя 1 минута, 51 секунда (31.03.2011 - 18:56) Invis1ble написал(а):
так точку не нужно писать, а эти костыли, что я написал целесообразно применять именно к выводу, потому как эти числа все равно будут преобразовываться обратно автоматом при операциях с ними.

Спустя 3 минуты, 2 секунды (31.03.2011 - 18:59) Trianon написал(а):
так может стоило просто ошибку исправить?

$r = number_format((float)($row['r']), 10);

Спустя 45 минут, 15 секунд (31.03.2011 - 19:44) vagon написал(а):
Цитата
Если не работают некие файлы, так наверное нужно чинить именно их?

Возможно, но скрипт работает без проблем около полутора лет, и подобных проблем не возникало. Поэтому весь скрипт мне переделывать бы не хотелось, тем более что это заняло бы слишком много времени которого у меня нет. Хотелось бы просто решить вышеописанную проблему. Если не получится - данную доработку придется "отложить в долгий ящик".
Цитата
Альтернативные варианты (без плавающей точки) я вам тоже описал.

Напишу в третий раз... Я не программист, и альтернативные варианты которые Вы описали просто не понял в силу своей некомпетентности в данном вопросе.
Цитата
Касательно нормальных людей.

Я не говорил о нормальности или ненормальности, я говорил о том, что программисты мыслят по-другому, не так как все прочие обыкновенные люди. И бывает сложно как объяснить что-то им, так и понять их. (Наша с Вами дискуссия - лучшее тому подтверждение. Дайте почитать эту тему нескольким своим знакомым программистам, и нескольким людям далеким от этого дела - , обычные люди назовут Вас - неадекватным роботом, а программисты меня - долбо***м smile.gif) По поводу материала который был засунут куда-то в район 6 класса обычной школьной программы когда Вы учились в школе... Он не поможет решить данную проблему, по той простой причине что даже если бы я помнил досконально весь этот материал, который проходил в школе лет 25 назад, (а как известно, то что не востребовано, со временем забывается), то и в этом случае не смог бы самостоятельно решить данную проблему. Причина написана выше, уже трижды.
Цитата
так может стоило просто ошибку исправить?

- Исправил. В базу пишется то же самое.

Спустя 29 минут, 4 секунды (31.03.2011 - 20:13) Trianon написал(а):
В третий раз.

Если Вы хотите чтобы в базу было записано именно 0.00001 ...
Собственно Вы не должны этого хотеть, поскольку число и представление числа - вещи разные, и система управления базой данных не должна заниматься представлениями, она должна запоминать, хранить, искать и извлекать - не более того. Представлением нужно заниматься прикладной стороне - т.е. скрипам.
Но если Вы настолько упрямы, что естественные правила Вам не указ, то:
Если Вы хотите чтобы в базу было записано именно 0.00001
- Чтобы 0.00001 было записано как 0.00001 именно в базу -
Вам следует поменять тип поля.
Другого способа нет.

Какой тип поля выбрать зависит от того, насколько большие числа, и с какой точностью Вы хотите в этом поле держать.

Спустя 30 минут, 16 секунд (31.03.2011 - 20:43) vagon написал(а):
Уже разобрался... FLOAT хранит до 3 нулей после точки, например 0.0001 запишет именно как 0.0001, если нулей больше то запишет в базу в сокращенном виде, как 1e-05. Вот и все собственно... Если бы мне это объяснили с самого начала, текста было бы гораздо меньше smile.gif
Цитата
Собственно Вы не должны этого хотеть
Что я хочу и что могу - совершенно разные вещи. Я Вас понял, но повторюсь еще раз: я не имею ни возможности ни времени переписывать достаточно большой по объему скрипт по-фэншую, как завещал великий IRBIS, (хотя очень серьезно отношусь к советам автора и стараюсь следовать им). Вероятно, сменю тип поля на VARCHAR например. Скорость работы конечно имеет значение, но ведь и операций этих происходит не миллион в секунду. Спасибо всем за помощь!

Спустя 17 минут, 13 секунд (31.03.2011 - 21:00) Trianon написал(а):
FLOAT хранит до 4 знаков после точки, 

(устало... ) FLOAT не хранит десятичные знаки. ни четыре, ни десять.
FLOAT хранит двоичные разряды общим числом в 23. Этим 23 двоичным разрядам соответствуют примерно шесть десятичных разрядов нормализованного числа, то есть разрядов, стоящих после этой самой единички (вернее , начиная с нее и правее).

Десятичные знаки может хранить строка (CHAR, VARCHAR) и очень условно - специальный тип DECIMAL .

например 0.0001 запишет именно как 0.0001,

а раз не хранит, то и гарантировать никто не будет, что число будет именно таким.
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.