-
- А так? ++(97 знак., 28.09.2011 15:11)
- 444.999 Пока так решил: Dany(115 знак., 28.09.2011 15:24)
- Тогда понятно. Формат float состоит из мантиссы и порядка: ++(543 знак., 28.09.2011 16:03 - 16:08, ссылка, ссылка)
- А чем плох вариант с увеличением незначащего разряда(округление в большую сторону)? Можно и без указателей записать. Dany(87 знак., 28.09.2011 15:37)
- Дано: функция xxx() ОШИБОЧНО выводит результат. Решение: вместо того, чтоб исправить функцию xxx() (или вовсе заменить на библиотечную и работающую правильно) мы будем прибавлять 0.0001. А почему 0.0001, а не 0.000001? А при вводе десятитысячных fk0(37 знак., 28.09.2011 16:20)
- Округлять нужно при выводе до заданного числа разрядов после запятой. Всегда при работе с float. А не изобретать магические константы. - fk0(28.09.2011 16:22)
- Если результат int, используется магическое число 0.5, давно известный способ. Михаил Е.(53 знак., 28.09.2011 19:16)
- или так Ruslan(48 знак., 29.09.2011 07:50)
- Это не магическое число, а округление в большую сторону с заданной точностью. Совершенно верно, будет погрешность при выводе числа с точностью округления, но от выше указанной ф-ции такой точности не требуется. Слепая замена одной ф-ции на другую Dany(96 знак., 28.09.2011 17:04)
- Если результат int, используется магическое число 0.5, давно известный способ. Михаил Е.(53 знак., 28.09.2011 19:16)
- Округлять нужно при выводе до заданного числа разрядов после запятой. Всегда при работе с float. А не изобретать магические константы. - fk0(28.09.2011 16:22)
- Дано: функция xxx() ОШИБОЧНО выводит результат. Решение: вместо того, чтоб исправить функцию xxx() (или вовсе заменить на библиотечную и работающую правильно) мы будем прибавлять 0.0001. А почему 0.0001, а не 0.000001? А при вводе десятитысячных fk0(37 знак., 28.09.2011 16:20)
- Потрясный образец говнокода. Работать не будет чуть более чем в половине случаев, кроме машины автора. Вот эту вашу FloatToASCII заменяем на sprintf и не морочим мозг. Потому, что ваша FloatToASCII попросту НЕКОРРЕКТНО сама округляет при выводе. fk0(35 знак., 28.09.2011 15:29)
- 444.999 Пока так решил: Dany(115 знак., 28.09.2011 15:24)
- Зачем все так хитро, я обычно пишу для заведомо положительных чисел a = (int)(f(b)+0.5), это же и делает round, cоответственно для отрицательных a = (int)(f(b)-0.5) - Иннокентий(28.09.2011 14:33,
)
- Проблема в том, что при приведении типов округление быть не обязано. Может быть и floor(). Тогда 444 и получается. Некоторые компиляторы округляют, некоторые делают floor. Это практика, что там говорит стандарт -- не знаю (а интересно). Если fk0(126 знак., 28.09.2011 13:11)
- Мне осмысленно не нужно вообще округление, вот чего хочется 9.99 * 100 = 999 и 4.45 * 100 = 445. В текущий момент приходится врукопашную отслеживать такие ситуации. Вот и подумалось, что так не должно быть, поэтому и вопрошаю. - Dany(28.09.2011 13:20)
- Может быть, там 444.999[9] получается. И принтфом толком не увидишь (он округлит до нужного числа разрядов, а не хватает самого младшего) -- в watch view или отладчике то же самое. Рекомендую посмотреть в hex-виде и сравнить с 445.0, сразу станет fk0(121 знак., 28.09.2011 13:49)
- Так и есть, Dany(149 знак., 28.09.2011 14:33)
- Может быть, там 444.999[9] получается. И принтфом толком не увидишь (он округлит до нужного числа разрядов, а не хватает самого младшего) -- в watch view или отладчике то же самое. Рекомендую посмотреть в hex-виде и сравнить с 445.0, сразу станет fk0(121 знак., 28.09.2011 13:49)
- Мне осмысленно не нужно вообще округление, вот чего хочется 9.99 * 100 = 999 и 4.45 * 100 = 445. В текущий момент приходится врукопашную отслеживать такие ситуации. Вот и подумалось, что так не должно быть, поэтому и вопрошаю. - Dany(28.09.2011 13:20)
- google://man round --> CONFORMING TO: C99, POSIX.1-2001. - fk0(28.09.2011 13:08)
- Видимо потому, что препроцессор перемножает данные константы в 32-бит float, а не в double. Либо это результат integer promotional, когда 32-бит float переводится в 32-бит int усечением дробной части. В IAR ARM 5.50 (int 32 бит) получается rezident(250 знак., 28.09.2011 12:56)
- Дело точно не в препроцессоре, так как Dany(196 знак., 28.09.2011 13:02)
- Ну да, я ошибся. Препроцессоры обычно только целочисленные вычисления делают. С float они не работают. А sizeof(int) на вашем МК какое значение дает? - rezident(28.09.2011 13:33)
- Вообще-то, препроцессоры ничего не делают. Все делается Bill(44 знак., 28.09.2011 16:19)
- MCU PIC24F, sizeof(int) = 2 - Dany(28.09.2011 13:38)
- Попробуйте еще такой вариант, это обычно срабатывает. rezident(50 знак., 28.09.2011 13:44)
- Это ручное округление в большую сторону. Вот ситуация где вредно округлять в большую сторону, ожидаемое значение 999 Dany(130 знак., 28.09.2011 14:01)
- Чушь! 9.995 * 100.0 = 999.5 И простое округление, а не в
большую сторону, должно дать 1000. С какого это должно получиться 999? Вы таки хотите floor(), т.е. без округления? Ну тогда зачем же жаловаться, что 4.45*100.0 = 444.999[9] и, в fk0(753 знак., 28.09.2011 14:39)- Начальная реализация, с которой все началось Dany(2596 знак., 28.09.2011 15:00)
- Пока эта ф-ция применялась для отображения параметров - проблем не было и не было разницы в округлении. А для ввода float округление вредно, вы вводите 4.45, потом происходит atof->проверка граничных значений->FloatToASCII->отображение для Dany(38 знак., 28.09.2011 15:09)
- А для ввода scanf или strotod ничего и не округляют. atof использовать нельзя, если нужна валидация ввода. - fk0(28.09.2011 15:32)
- Исключительно качественное подтверждение моим словам о том, что нефиг заменять библиотечный sprintf на свои и глючные велосипеды с квадратными колёсами. sprintf(buf, "%0.2f", flVal) решает проблему изначально. За вас давно подумали, на все fk0(70 знак., 28.09.2011 15:26)
- Пока эта ф-ция применялась для отображения параметров - проблем не было и не было разницы в округлении. А для ввода float округление вредно, вы вводите 4.45, потом происходит atof->проверка граничных значений->FloatToASCII->отображение для Dany(38 знак., 28.09.2011 15:09)
- Начальная реализация, с которой все началось Dany(2596 знак., 28.09.2011 15:00)
- Чушь! 9.995 * 100.0 = 999.5 И простое округление, а не в
- Это то же самое, что round(), если при приведении типа делается floor(). Проблема в том, что KEIL x51 в такой ситуации сделает round() при приведении и можно получить ошибку на +0.5. Возможно KEIL не прав. Вопрос, где говорится, как именно должен fk0(25 знак., 28.09.2011 13:53)
- Да-да-да, при округлении самый главный вопрос звучит так: "мы продаем или покупаем"? :))) - rezident(28.09.2011 14:34 - 15:24, ссылка)
- Это ручное округление в большую сторону. Вот ситуация где вредно округлять в большую сторону, ожидаемое значение 999 Dany(130 знак., 28.09.2011 14:01)
- Попробуйте еще такой вариант, это обычно срабатывает. rezident(50 знак., 28.09.2011 13:44)
- после инта дубль поставь - LordN(28.09.2011 13:07)
- Такое уже пробовал - Dany(28.09.2011 13:30, ссылка)
- Ну да, я ошибся. Препроцессоры обычно только целочисленные вычисления делают. С float они не работают. А sizeof(int) на вашем МК какое значение дает? - rezident(28.09.2011 13:33)
- Дело точно не в препроцессоре, так как Dany(196 знак., 28.09.2011 13:02)
- В свойствах проекта какое представление float? 24 бит или 32 бит? Если ту же операцию проделать с double? - ++(28.09.2011 12:19 - 12:28)
- Ваш вариант Dany(123 знак., 28.09.2011 12:50)
- By default, a double type is the same size as a float type (32-bit representation) Dany(168 знак., 28.09.2011 12:39)
- а так LordN(60 знак., 28.09.2011 13:54)
- Тоже самое - Dany(28.09.2011 14:31)
- а так LordN(60 знак., 28.09.2011 13:54)
- Спасибо, работает. Подскажите, где посмотреть(в каком header) описание round. - Dany(28.09.2011 12:29)
- А так? ++(97 знак., 28.09.2011 15:11)