|
Не работает правильно, вычисление float в Keil, Деление на 10 |
|
|
|
Feb 14 2017, 05:48
|
Знающий
   
Группа: Свой
Сообщений: 526
Регистрация: 5-08-05
Пользователь №: 7 390

|
попробуйте поделить на 10.0 или умножить на 0.1f
Сообщение отредактировал Herz - Feb 14 2017, 08:33
Причина редактирования: Избыточное цитирование
|
|
|
|
|
Feb 14 2017, 06:40
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (_Алекс @ Feb 14 2017, 07:21)  Понято, что происходит потеря точности. или число 25.1 невозможно представить типом float с принятым у кейла размером мантиссы. Проверьте просто x = 25.1; не слушайте psL, он продемострировал незнание основ языка.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Feb 14 2017, 06:49
|
Профессионал
    
Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848

|
Цитата(_Алекс @ Feb 14 2017, 09:21)  Код округление числа до десятых. . . . . Может есть другой способ округлить число до десятых. Решение через нетоместо, но решение. Используйте sprintf c указанием точности, напр. %12.1f ps ну и исходник (s)printf можно посмотреть.
Сообщение отредактировал k155la3 - Feb 14 2017, 06:52
|
|
|
|
|
Feb 14 2017, 08:10
|
Гуру
     
Группа: Свой
Сообщений: 2 360
Регистрация: 6-03-06
Из: Кишинев
Пользователь №: 15 025

|
Цитата(_Алекс @ Feb 14 2017, 07:21)  При делении 251 на 10, вроде должно быть 25.1, а получается 25.0999995. Кому должно? не должно оно никому. Почитайте представление чисел в float'e, поймете- там величина всегда неточная, она просто в заданном точностью диапазоне. Кстати, по этой же причине грубой ошибкой является попытка проверить float на равенство чему-то. У Вас просто проявилась накопленная во время вычислений (всех вычислений, а не только последнего!) ошибка. Собственно Вы сами уже ответили на свой вопрос: Цитата(_Алекс @ Feb 14 2017, 07:21)  Если float поменять на double, работает. ... Понято, что происходит потеря точности. Вас смутило что " Код в другой среде, работает и с float.". Скорее всего, в этой "другой среде" (уж не Матлаб ли?) оно приводится к длинному представлению и в нем считается, вот и все. Эти ошибки представления не такой очевидный факт. Я лет 15 назад пытался это же объяснить девушке (Программистка, только что окончила Московский Энергетический, очень круто было в наших краях), у нее была ошибка: если она кучу коротких данных (импульсы от счетчиков) преобразовывала в киловатт-часы, то месячная сумма этих коротких величин не сходилась с данными, показанными по барабану счетчика (конец минус начало интервала наблюдения). Причем если взять сумму импульсов за месяц и преобразовать в киловатты, то с барабаном совпадало. Она так и не поняла про точность вычислений, у нее же писи и фокспро, они всегда точно считают. Думала что я над ней так прикалываюсь.  И не бойтесь использовать дабл, ничего страшного в нем нет. Upd: вот первое попавшееся неплохое описание вопроса. Например, интересен пункт "4.2 Неассоциативность арифметических операций", но там много и другого интересного про подводные камни плавающей точки.
|
|
|
|
|
Feb 14 2017, 09:11
|
Знающий
   
Группа: Свой
Сообщений: 526
Регистрация: 5-08-05
Пользователь №: 7 390

|
Цитата(Сергей Борщ @ Feb 14 2017, 09:40)  или число 25.1 невозможно представить типом float с принятым у кейла размером мантиссы. Проверьте просто x = 25.1; не слушайте Борща с его принятым размером мантисы. Keil использует IEEE-754: http://www.keil.com/support/man/docs/armli...58938949149.htmкоторого достаточно для представления 25.1, можно проверить, например, здесь: https://www.h-schmidt.net/FloatConverter/
|
|
|
|
|
Feb 14 2017, 09:17
|
Местный
  
Группа: Свой
Сообщений: 252
Регистрация: 14-09-06
Пользователь №: 20 377

|
Ерунда, похоже, с Keil. double Round (double x){ return x=6.1; }; Функция возвращает 6.099998474121, как такое может, быть. https://www.h-schmidt.net/FloatConverter/, проверил 6.1 это 6.099999904632568 похоже, так и есть
|
|
|
|
|
Feb 14 2017, 09:32
|
Местный
  
Группа: Свой
Сообщений: 252
Регистрация: 14-09-06
Пользователь №: 20 377

|
Цитата(HardEgor @ Feb 14 2017, 13:25)  А откуда числа в комментариях взялись? Это вы вручную посчитали? А теперь попробуйте вывести результат через sprintf с форматом %e Да, вручную. Уже понял, свою ошибку.
|
|
|
|
|
Feb 14 2017, 10:00
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (psL @ Feb 14 2017, 11:11)  Вы бы хоть немного ознакомились с тем, на что ссылаетесь (хотя бы по википедии): QUOTE Возможные конечные значения, которые могут быть представлены в формате, определяются основанием b, количеством цифр в мантиссе (с точностью р) и максимальным значением emax: И лично вам в коллекцию: неявное приведение типов
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Feb 14 2017, 16:06
|
self made
   
Группа: Свой
Сообщений: 855
Регистрация: 7-03-09
Из: Toronto, Canada
Пользователь №: 45 795

|
Цитата(Сергей Борщ @ Feb 14 2017, 01:40)  или число 25.1 невозможно представить типом float с принятым у кейла размером мантиссы. Проверьте просто x = 25.1; число 25.1 невозмжно точно представить ни в каком варианте float, хоть double, хоть long double. Цитата(Ruslan1 @ Feb 14 2017, 03:10)  У Вас просто проявилась накопленная во время вычислений (всех вычислений, а не только последнего!) ошибка. при чем тут накопленная ошибка? после выполнения floor уже все абсолютно точно.
|
|
|
|
|
Feb 14 2017, 16:10
|
Участник

Группа: Участник
Сообщений: 56
Регистрация: 3-11-11
Пользователь №: 68 126

|
В двоичном формате с плавающей запятой точно представимы только целые числа, либо числа дробная часть которых есть сумма (отрицательных) степеней двойки.
Нужно умножать дробную часть на 2 до тех пор пока она не обнулится: 0,703125 x 2 = 1,40625 | 1 0,40625 x 2 = 0,8125 | 0 0,8125 x 2 = 1,625 | 1 0,625 x 2 = 1,25 | 1 0,25 x 2 =0,5 | 0 0,5 x 2 = 1 | 1 Т. о. 0,703125 = 0,101101(2)
0.1 сколько на 2 не умножай, дробная часть никогда не обнулится. Т. е. в двоичном виде точно не представимо
Сообщение отредактировал conan - Feb 14 2017, 16:11
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|