Абырвалг 0 12 ноября, 2010 Опубликовано 12 ноября, 2010 (изменено) · Жалоба CCS 4.1.3. В комментариях результат присвоения. Как такое может быть? int a1 = (int)(60.0/1.2); // = 49 int a2 = (int)(60.0/1.2 + 0.5); // = 50 Изменено 12 ноября, 2010 пользователем Абырвалг Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
fontp 0 12 ноября, 2010 Опубликовано 12 ноября, 2010 · Жалоба CCS 4.1.3. В комментариях результат присвоения. Как такое может быть? int a1 = (int)(60.0/1.2); // = 49 int a2 = (int)(60.0/1.2 + 0.5); // = 50 ошибка представления округляет так, что (60.0/1.2) = 49.999999 очевидно (int)(60.0/1.2 + 0.5) = 50 да и (int)(60.0/1.2 + 0.001) = 50 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Абырвалг 0 12 ноября, 2010 Опубликовано 12 ноября, 2010 · Жалоба Это то понятно. Но это же ненормально? Раньше с таким не сталкивался, неужто такое в норме вещей? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
fontp 0 12 ноября, 2010 Опубликовано 12 ноября, 2010 · Жалоба Это то понятно. Но это же ненормально? Раньше с таким не сталкивался, неужто такое в норме вещей? Бывает. Ошибки округления при вводе числа. Типа 1.2 = 1.200001 примерно Как-то обсуждали, правда для библиотеки программной укороченых float16-float32 blackfin, а здесь намудрили прямо в компиляторе Не страшно, хоть и неожиданно. Если не использовать int а использовать правильное округление floor(x+0.5), то результат будет всегда ожидаемый Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Абырвалг 0 13 ноября, 2010 Опубликовано 13 ноября, 2010 · Жалоба Бывает. Ошибки округления при вводе числа. Типа 1.2 = 1.200001 примерно Как-то обсуждали, правда для библиотеки программной укороченых float16-float32 blackfin, а здесь намудрили прямо в компиляторе Не страшно, хоть и неожиданно. Если не использовать int а использовать правильное округление floor(x+0.5), то результат будет всегда ожидаемый Использовать вызов функции для вычисления константы, да еще такой простой? На это я пойтить не могу. И чем приведение к целому типу хуже? И там +0.5 надо добавить, и тут. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrewn 0 13 ноября, 2010 Опубликовано 13 ноября, 2010 · Жалоба И чем приведение к целому типу хуже? И там +0.5 надо добавить, и тут. Надо всегда помнить, что флор() - плавающий целый. Пред. автор этого не помнит. 1.2 = 1 + 1/5. Одну пятую в двоичном виде не представить в виде конечной дроби, 1.2 -> 1.999.... или 0x3F99999A с округлением. Иначе никак. Соответственно, преобразование в целое будет, как и сосчитал компилятор или процессор - правильно округлив в целое. И, вообще, а + в = а или а + в = в... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Абырвалг 0 14 ноября, 2010 Опубликовано 14 ноября, 2010 · Жалоба Надо всегда помнить, что флор() - плавающий целый. Пред. автор этого не помнит. 1.2 = 1 + 1/5. Одну пятую в двоичном виде не представить в виде конечной дроби, 1.2 -> 1.999.... или 0x3F99999A с округлением. Иначе никак. Соответственно, преобразование в целое будет, как и сосчитал компилятор или процессор - правильно округлив в целое. И, вообще, а + в = а или а + в = в... Флор округляет вниз, 1.2 -> 1. Но 1.2 в целое преобразовывать мне не надо. 60/1.2 надо. Конкретно в этом примере 60 - сисклок в МГц, 1.2 МГц - частота PWM для вывода наружу. 60/1.2 = 50. При обнулении таймера в него загружается 50-1=49. Чтобы не вспоминать после что такое 49, при инициализации таймера в регистр периода записывается (int) (60/1.2-1). Если результат в скобках целый, то и проблем, как мне казалось, быть не должно. Всю жисть так делал и горя не знал. Вроде и в CCS2 такое использовал, хотя божиться не буду а проверять не охота. Если надо округлить нецелую константу, то добавлял +0.5 и то же отбрасывание дробной части через приведение типа: (int) (60/1.2-1+0.5). Такое и с этими приколами ccs4 работать будет. Вообще понятно почему так происходит, но просто не ожидал такого подвоха. В любом калькуляторе при вычислении 60/1.2 вы получите 50, а не 49.(9). В калькуляторах вроде есть лишний разряд, который вычисляется но не отображается, а используется для округления результата. В чем преимущество флор() - не понял. Вроде никакого, кроме лишнего кода. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sigmaN 0 14 ноября, 2010 Опубликовано 14 ноября, 2010 · Жалоба а может 600/12 ? или типа в килогерцах 60000/1200 и камент в исходнике, мол так и так... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Абырвалг 0 14 ноября, 2010 Опубликовано 14 ноября, 2010 · Жалоба или типа в килогерцах 60000/1200 и камент в исходнике, мол так и так... Ага, вариант. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zebra_spb 0 15 декабря, 2010 Опубликовано 15 декабря, 2010 · Жалоба Предлагаю всем набросать циклу, и посмотреть когда она закончится, любыми компиляторами. double i = 0.0 ; do { i = i + 0.1 ; } while( i != 1.0 ); Затем заменить 0.1 на 0.125. Просветляет относительно представления вещественных чисел. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrewn 0 15 декабря, 2010 Опубликовано 15 декабря, 2010 · Жалоба Предлагаю всем набросать циклу [...] Просветляет относительно представления вещественных чисел. В основном, неубедительно. Этот цикл (и сотни и тысячи ему подобных) иллюстрирует следствие, но не анализирует причину. Причины обоснованы в David Goldberg, What Every Computer Scientist Should Know About Floating-Point Arithmetic, ACM Computing Surveys, Vol 23, No 1, March 1991. Этой же и сходными проблемами в разное время занималось много математиков, от П.Л.Чебышева до У.Кахана (вместо до нужно вписать много известных имён)... Оригинальная статья из ACM CS и из NCG @ http://docs.sun.com/ : Goldberg_1991.pdf goldberg.pdf Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tegumay 4 16 декабря, 2010 Опубликовано 16 декабря, 2010 · Жалоба гм, это как всех всегда учили, надеюсь и вас, погрешность представления, всегда была, есть и будет. вычислителей всегда учат учитывать эту ошибку. особенно при переводе к целому. всегда стоял вопрос куда округлять и граница=) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться