Форум программистов, компьютерный форум, киберфорум
PHP
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.81/21: Рейтинг темы: голосов - 21, средняя оценка - 4.81
0 / 0 / 1
Регистрация: 01.04.2015
Сообщений: 65

Вычитание двух чисел с плавающей точкой откуда остаток

15.01.2018, 16:49. Показов 4578. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток!
От клиента приходит число например 0.02 ($qty);
В DB есть 2 записи 0.005 ($incoming_old->qty) и 0.0015 (что в сумме 0.2);
Логика заключается в том что мы подымаем первую запись смотрим у нее число ( = 0.005), выполняем формулу
PHP
1
2
3
4
while ($incoming_old !== null && $qty) {
    $qty = (float)$qty - (float)$incoming_old->qty;
    $incoming_old = Incoming::getOld();
}
Первая итерация проходит норм:
0.0015 = 0.02 - 0.005;
А вот на второй начинается magic:
0.0015 = 0.02 - 0.005;
8.6......E-19 = 0.0015 - 0.0015
Что только не пытался сделать, если ставлю проверку на равенство пишет true;
Если руками посчитать 0.0015 - 0.0015 = 0;
PHP 7.0.22
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
15.01.2018, 16:49
Ответы с готовыми решениями:

Особенности представления чисел с плавающей точкой
$n = 5.148\0.198; print $n; // =26 print floor($n); // =25 PHP бист швайсэ!!! З.Ы. php 5.3.3 - 5.3.10

Сравнение чисел с плавающей точкой выдают неожиданный результат
Я далеко не новичок в php, но куда еще можно было бы пихнуть данную тему я даже и не знаю. В процессе написания одной системы столкнулся...

Число с плавающей точкой
Не могу определить целое число: Пример: <?php $a = 86.1; if (is_float($a)) {

9
34 / 11 / 6
Регистрация: 09.01.2018
Сообщений: 189
15.01.2018, 17:01
Не экономьте на символах.

echo (0.02-0.015-0.005); // 8.673617379884E-19

Операции с плавающей точкой не надежны из-за особенностей работы процессоров. Самый простой пример можно в браузере вычислить 0.2+0.7= 0.8999999999999999

Просто округлите до нужной точности с помощью round() (хотя у меня было что и округление не помогало, но случилось лишь раз в жизни)
0
Эксперт PHP
4925 / 3920 / 1620
Регистрация: 24.04.2014
Сообщений: 11,441
15.01.2018, 22:13
Цитата Сообщение от ezd Посмотреть сообщение
Операции с плавающей точкой не надежны из-за особенностей работы процессоров
Никакиких особенностей работы процессора приводящих к ошибкам арифметики плавающих чисел нет, проблемма глубже. Все дело в особенности действительных чисел. Возьми любые два несовпадающие числа - между нимибудет бесконечное множество числе. А оперативная память конечна, поэтому и приходится идти на "уступки".
Цитата Сообщение от ezd Посмотреть сообщение
Просто округлите до нужной точности с помощью round()
Не надо округлять. Если есть необходимость сравнить 2 числа с плавающей точкой, то условие будет таким: |a - b| < e, e - желаемая точность
https://habrahabr.ru/post/112953/
0
34 / 11 / 6
Регистрация: 09.01.2018
Сообщений: 189
16.01.2018, 02:33
Цитата Сообщение от Jewbacabra Посмотреть сообщение
Никакиких особенностей работы процессора приводящих к ошибкам арифметики плавающих чисел нет, проблемма глубже. Все дело в особенности действительных чисел. Возьми любые два несовпадающие числа - между нимибудет бесконечное множество числе. А оперативная память конечна, поэтому и приходится идти на "уступки".
???

Цитата Сообщение от Jewbacabra Посмотреть сообщение
Если есть необходимость сравнить 2 числа с плавающей точкой
А у кого из присутствующих есть такая необходимость?
0
Эксперт PHP
4925 / 3920 / 1620
Регистрация: 24.04.2014
Сообщений: 11,441
16.01.2018, 02:55
Цитата Сообщение от ezd Посмотреть сообщение
???
???
Цитата Сообщение от ezd Посмотреть сообщение
А у кого из присутствующих есть такая необходимость?
У TC
0
34 / 11 / 6
Регистрация: 09.01.2018
Сообщений: 189
16.01.2018, 07:03
Цитата Сообщение от Jewbacabra Посмотреть сообщение
Никакиких особенностей работы процессора приводящих к ошибкам арифметики плавающих чисел нет, проблемма глубже. Все дело в особенности действительных чисел. Возьми любые два несовпадающие числа - между нимибудет бесконечное множество числе. А оперативная память конечна, поэтому и приходится идти на "уступки".
При чем тут бесконечность между числами? Вы на листочке предложенные выше числа когда считаете у вас тоже такая ерунда на выходе получается? Конечно нет. Вопрос в процессорах и в том как он работает с числами с плавающей точкой. В вашей же статье описаны примеры, просто явно не указывается, что у процессора по сути нет "запятой", там везде как бы целые и степени числа 2 (в случае плавающей точкой степень отрицательная).

Пример из статьи:

1,01e-3 = 1×2^-3 + 0×2^-4 + 1×2^-5 = 1×0,125 + 0×0,0625 + 1×0,03125 = 0,125 + 0,03125 = 0,15625

То есть оно складывается 1/8 + 0/16 + 1/32.

Если брать десятичную систему то число
0,15625=0*10^0 + 1*10^-1-1 + 5*10^-2 + 6*10^3 + 2*10^-4 + 5*10^-5
или понятней
0,15625=0+1/10+5/100+6/1000+2/10000+5/100000

И если в десятичной системе можно точно записать вот такими степенями 10-ки, то в двоичной системе эти приближения к единице заканчиваются гораздо быстрее х/2+х/4+х/8+х/16... и в итоге получается число приблизительное (сколько влезло). И в результате вычисления остается вот эта приблизительная разница.

Цитата Сообщение от Jewbacabra Посмотреть сообщение
У TC
Судя по коду надо вычислить результат и куда-то его сохранить. Его просто удивило такое странное представление. Если его программа не рассчитана на какие-то сверхточные физические вычисления с кучей знаков после запятой, то может просто округлить да хоть до 8-ого знака, этого более чем в прикладных задачах.

echo round(0.02-0.015-0.005,8); // == 0
1
0 / 0 / 1
Регистрация: 01.04.2015
Сообщений: 65
16.01.2018, 11:36  [ТС]
Благодарю за развернутые разъяснения
0
Эксперт PHP
4925 / 3920 / 1620
Регистрация: 24.04.2014
Сообщений: 11,441
16.01.2018, 21:45
Цитата Сообщение от ezd Посмотреть сообщение
При чем тут бесконечность между числами?
Это причина. А погрешности при вычислении - следствие. Из твоего сообщения следует что существует способ абсолютно точно производить операции с действительными числами, а процессор - это такой неполноценный инструмент не позволяющий этого сделать. Это не так.

Цитата Сообщение от ezd Посмотреть сообщение
Вы на листочке предложенные выше числа когда считаете у вас тоже такая ерунда на выходе получается? Конечно нет.
Посчитай на листочке корень из 2

Цитата Сообщение от ezd Посмотреть сообщение
может просто округлить да хоть до 8-ого знака, этого более чем в прикладных задачах.
Невозможно округлить до 8 знака, это все равно будет то же число с плавающей точкой. Можно лишь получить строковое представление числа, округленное до 8 знака.
0
34 / 11 / 6
Регистрация: 09.01.2018
Сообщений: 189
17.01.2018, 05:11
Цитата Сообщение от Jewbacabra Посмотреть сообщение
Посчитай на листочке корень из 2
Зачем мне корень из 2 на бумаге считать? У нас конкретный пример в задаче! Конкретный! Который на бумаге дает 0!

echo (0.02-0.015-0.005); // 8.673617379884E-19
0
17.01.2018, 09:45

Не по теме:

Цитата Сообщение от ezd Посмотреть сообщение
Зачем мне корень из 2 на бумаге считать? У нас конкретный пример в задаче!
Разница между частным и общим случаем понятна?

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
17.01.2018, 09:45
Помогаю со студенческими работами здесь

Числовое значение с плавающей точкой
У меня выводится сумма одного предмета - 1013 $, а мне надо поставить точку чтобы было так - 101,3 $ помогите допилить код, с математикой...

Регулярное выражение - число с плавающей точкой
Всем привет! Помогите пожалуйста, есть задачка: из строки типа &quot;asdaqw555.77eqwewq&quot; с помощью регулярного выражения на выходе было...

Сложение и вычитание чисел с плавающей точкой
Доброго времени суток. Прошу помочь. Нужно где-то откопать програмку: &quot;Сложение и вычитание чисел с плавающей точкой&quot;. Если у кого...

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

Как найти остаток от деления чисел с плавающей точкой?
Приветствую. Есть код: for(int i=0;i&lt;n;i++) { if(mas%2.0==0.0) { t++; } } Пишет что операция &quot;%&quot;...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
Загрузка PNG-файла с альфа-каналом с помощью библиотеки SDL3_image на Android
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru