вычитание float из float = ересь

Ответить
SirYorik
Сержант
Сообщения: 124
Зарегистрирован: 04.10.2015{, 10:01}
Репутация: 0
Откуда: Томск

вычитание float из float = ересь

#1

Сообщение SirYorik » 23.02.2016{, 09:50}

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

это баг, или куда? копаюсь так и сяк уже больше 2х часов.
9419023.jpg
компилится в:

Код: Выделить всё

float _gtv6 = 0;
float _gtv13 = 1;
float _gtv15 = 0;
...
UB_103065410_ubi_128251383 = (_gtv6)-(_gtv13);
UB_103065410_Instance2 = _func_UB_103065410(UB_103065410_Instance2, UB_103065410_ubi_128251383);
_gtv15 = UB_103065410_Instance2.ubo_91927667;
...
if (1){Serial.println(((( _floatToStringWitRaz(_gtv6,10))) + (String(" - ")) + (( _floatToStringWitRaz(_gtv13,10))) + (String(" = ")) + (( _floatToStringWitRaz(_gtv15,10)))));}
_func - это я пытался играться с округлением, без него тоже самое, округление только в некоторые числа вместо цифрового шума в середину после запятой вставляет 5 нулей, типа: 0.8600000381 Изображение

портянка принятая с ком порта, куда девается минус?  Изображение :


СпойлерПоказать
0.0000000000 - 1.0000000000 = -1.0000000000
0.0000000000 - 1.0000000000 = -1.0000000000
0.3300000190 - 1.0000000000 = 0.6600000381
0.4300000190 - 1.0000000000 = 0.5699999809
0.5299999713 - 1.0000000000 = 0.4699999809
0.6100000381 - 1.0000000000 = 0.3899999809
0.6800000190 - 1.0000000000 = 0.3199999809
0.6600000381 - 1.0000000000 = 0.3300000190
0.7200000286 - 1.0000000000 = 0.2700000047
0.7699999809 - 1.0000000000 = 0.2299999952
0.8199999809 - 1.0000000000 = 0.1800000095
0.8600000381 - 1.0000000000 = 0.1299999952
0.9000000000 - 1.0000000000 = 0.1000000000
0.9399999618 - 1.0000000000 = 0.0599999952
0.9700000762 - 1.0000000000 = 0.0199999990
1.0000000000 - 1.0000000000 = 0.0000000000
1.0199999809 - 1.0000000000 = 0.0099999990
1.0399999618 - 1.0000000000 = 0.0299999980
1.0700000524 - 1.0000000000 = 0.0700000000
1.0800000381 - 1.0000000000 = 0.0799999952
1.1000000238 - 1.0000000000 = 0.1000000000
....
1.3400000333 - 1.0000000000 = 0.3400000095
1.3400000333 - 1.0000000000 = 0.3400000095
1.3500000238 - 1.0000000000 = 0.3500000000
....
1.0199999809 - 1.0000000000 = 0.0099999990
0.9199999809 - 1.0000000000 = 0.0700000000
0.8300000190 - 1.0000000000 = 0.1700000047
0.7400000095 - 1.0000000000 = 0.2599999904
0.6700000286 - 1.0000000000 = 0.3300000190
.....
0.0500000000 - 1.0000000000 = 0.9500000000
0.0500000000 - 1.0000000000 = 0.9500000000
0.0000000000 - 1.0000000000 = -1.0000000000
0.0000000000 - 1.0000000000 = -1.0000000000
по сумме происходящего маразм и шок
Последний раз редактировалось SirYorik 23.02.2016{, 09:51}, всего редактировалось 1 раз.

Аватара пользователя
rw6cm
Полковник
Сообщения: 2283
Зарегистрирован: 06.09.2015{, 20:25}
Репутация: 334
Имя: Владимир

вычитание float из float = ересь

#2

Сообщение rw6cm » 23.02.2016{, 10:05}

SirYorik писал(а):по сумме происходящего маразм и шок
Считать на ардуине Float с 6ти значным числом вобще маразм :)))
В флпрог стараюсь за тысячные не выходить )
Win10-64, FLProg (portable)

Аватара пользователя
support
Супермодератор
Сообщения: 1900
Зарегистрирован: 03.01.2018{, 11:45}
Репутация: 789
Откуда: Астрахань
Имя: Сергей
Контактная информация:

вычитание float из float = ересь

#3

Сообщение support » 23.02.2016{, 10:07}

Ардуино вообще не очень дружит с типом Float. Поэтому я всегда рекомендую всю математику делать с целыми значениями, а если нужно вывести флоат, переводим перед самым выводом например на дисплей или в порт.
Автор программы FLProg.

SirYorik
Сержант
Сообщения: 124
Зарегистрирован: 04.10.2015{, 10:01}
Репутация: 0
Откуда: Томск

вычитание float из float = ересь

#4

Сообщение SirYorik » 23.02.2016{, 10:29}

rw6cm писал(а):В флпрог стараюсь за тысячные не выходить )
да мне и 2х хватило бы, оно этот хлам само откудато натягивает, как отпилить не знаю.
в выводе задрал на 10 знаков чтобы посмотреть чего происходит.
support писал(а):а если нужно вывести флоат, переводим перед самым выводом например на дисплей или в порт.
вывод только для диагностики глюка с математикой.

при этом рядом, прям на одной плате другая пара float переменных нормально вычитается, со значениями <0 всё окей.

пробовал тип double - не помогло.(что логично)
пробовал сложение с отрицательным числом, не помогло.

1.3092288970+-1.1000000238 = 0.2092288732
1.3098659515+-1.1000000238 = 0.2098659276
0.9984392166+-1.1000000238 = 0.1015608310
0.8943552970+-1.1000000238 = 0.2056447267
0.8057197570+-1.1000000238 = 0.2942802429

Изображение

Добавлено (23.02.2016, 10:29)
---------------------------------------------
переточил что бы вычитание было целочисленным

схематично: F*100-->INT-INT-->INT/100.0-->F

0.11728 - 1.10000 = 0.98999
0.11055 - 1.10000 = 0.98999
0.10449 - 1.10000 = -1.00000
0.09904 - 1.10000 = -1.00999
Последний раз редактировалось SirYorik 23.02.2016{, 10:19}, всего редактировалось 1 раз.

Аватара пользователя
rw6cm
Полковник
Сообщения: 2283
Зарегистрирован: 06.09.2015{, 20:25}
Репутация: 334
Имя: Владимир

вычитание float из float = ересь

#5

Сообщение rw6cm » 23.02.2016{, 10:52}

SirYorik писал(а):да мне и 2х хватило бы
Даже с тысячными проблем не замечалось, если конечно не применялось преобразований.
Вложения
1_1-1.flp
(86.99 КБ) 64 скачивания
Последний раз редактировалось rw6cm 23.02.2016{, 10:52}, всего редактировалось 1 раз.
Win10-64, FLProg (portable)

SirYorik
Сержант
Сообщения: 124
Зарегистрирован: 04.10.2015{, 10:01}
Репутация: 0
Откуда: Томск

вычитание float из float = ересь

#6

Сообщение SirYorik » 23.02.2016{, 11:01}

плюнул на неведому-фигню, 4 часа в никуда.

переделал эти переменные в integer и умножил на 1000, всё немедленно стало как надо
1187 - 1100 = 87
1195 - 1100 = 95
1198 - 1100 = 98
970 - 1100 = -130
874 - 1100 = -226
787 - 1100 = -313

ДИЧЬ!

Аватара пользователя
support
Супермодератор
Сообщения: 1900
Зарегистрирован: 03.01.2018{, 11:45}
Репутация: 789
Откуда: Астрахань
Имя: Сергей
Контактная информация:

вычитание float из float = ересь

#7

Сообщение support » 23.02.2016{, 11:16}

SirYorik писал(а):переделал эти переменные в integer и умножил на 1000, всё немедленно стало как надо
 Всё правильно сделали. Даже сами разработчики ардуино так рекомендуют делать. Кстати есть ещё приколы. Например:
Следует иметь ввиду, что числа с плавающей точкой не являются точными, что может приводить к неожиданным результатам при их сравнении.
Например, 6.0 / 3.0 может не равняться 2.0. Поэтому, вместо сравнения
двух чисел следует проверять, является ли абсолютное значение их
разности меньше некоторого небольшого значения.
Автор программы FLProg.

Ответить

Вернуться в «переменные»