jenya7 0 31 августа, 2020 Опубликовано 31 августа, 2020 · Жалоба fval = 1.299; sprintf(buff, "%2.3f", fval); USART_SendString(SYS_USART, buff); В IAR честно печатает 1.299 В GCC округляет - 1.300. Где там настроить чтоб не округлял? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rkit 1 31 августа, 2020 Опубликовано 31 августа, 2020 · Жалоба Если ты хочешь точности до цифры - не используй числа с плавающей точкой. Они не для этого. С любыми компиляторами и любыми настройками будут возникать такие ситуации. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 31 августа, 2020 Опубликовано 31 августа, 2020 · Жалоба 1 hour ago, rkit said: Если ты хочешь точности до цифры - не используй числа с плавающей точкой. Они не для этого. С любыми компиляторами и любыми настройками будут возникать такие ситуации. с числом все в порядке. мне его надо отобразить на дисплее, для этого перевожу в строку, при переводе sprintf его округляет. например такое решение правильно отображает число в любом компиляторе Spoiler #define MAX_PRECISION (10) static const double rounders[MAX_PRECISION + 1] = { 0.5, // 0 0.05, // 1 0.005, // 2 0.0005, // 3 0.00005, // 4 0.000005, // 5 0.0000005, // 6 0.00000005, // 7 0.000000005, // 8 0.0000000005, // 9 0.00000000005 // 10 }; char * ftoa(double f, char * buf, int precision) { char * ptr = buf; char * p = ptr; char * p1; char c; long intPart; // check precision bounds if (precision > MAX_PRECISION) precision = MAX_PRECISION; // sign stuff if (f < 0) { f = -f; *ptr++ = '-'; } if (precision < 0) // negative precision == automatic precision guess { if (f < 1.0) precision = 6; else if (f < 10.0) precision = 5; else if (f < 100.0) precision = 4; else if (f < 1000.0) precision = 3; else if (f < 10000.0) precision = 2; else if (f < 100000.0) precision = 1; else precision = 0; } // round value according the precision if (precision) f += rounders[precision]; // integer part... intPart = (int)f; f -= intPart; if (!intPart) *ptr++ = '0'; else { // save start pointer p = ptr; // convert (reverse order) while (intPart) { *p++ = '0' + intPart % 10; intPart /= 10; } // save end pos p1 = p; // reverse result while (p > ptr) { c = *--p; *p = *ptr; *ptr++ = c; } // restore end pos ptr = p1; } // decimal part if (precision) { // place decimal point *ptr++ = '.'; // convert while (precision--) { f *= 10.0; c = (char)f; *ptr++ = '0' + c; f -= c; } } // terminating zero *ptr = 0; return buf; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 31 августа, 2020 Опубликовано 31 августа, 2020 · Жалоба 1 hour ago, jenya7 said: де там настроить чтоб не округлял? fval у вас какого типа? Ибо 1.299 это double, а 1.299f это флоат. Полезная ссылка про формат IEEE-754. Вряд ли что-то можно настроить. Библиотека каждого компилятора может немного по-другому обрабатывать числа. Это вполне допустимо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 31 августа, 2020 Опубликовано 31 августа, 2020 · Жалоба 1 hour ago, haker_fox said: fval у вас какого типа? Ибо 1.299 это double, а 1.299f это флоат. Полезная ссылка про формат IEEE-754. Вряд ли что-то можно настроить. Библиотека каждого компилятора может немного по-другому обрабатывать числа. Это вполне допустимо. fval у меня float. нет я понимаю когда округление происходит при математических операциях, но тут вроде как функция должна преобразовать число в строку. с какого перепуга она решает округлять входной аргумент. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 42 31 августа, 2020 Опубликовано 31 августа, 2020 · Жалоба 19 minutes ago, jenya7 said: fval у меня float. нет я понимаю когда округление происходит при математических операциях, но тут вроде как функция должна преобразовать число в строку. с какого перепуга она решает округлять входной аргумент. Это вы fval объявили как float, а пытаетесь ему присвоить double, вот компилятор и производит преобразование типов при присваивании. Чтобы этого избежать, к вашему значению 1.2999 надо добавить буковку f. Вот так fval = 1.2999f; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 31 августа, 2020 Опубликовано 31 августа, 2020 (изменено) · Жалоба 1 hour ago, dimka76 said: Это вы fval объявили как float, а пытаетесь ему присвоить double, вот компилятор и производит преобразование типов при присваивании. Чтобы этого избежать, к вашему значению 1.2999 надо добавить буковку f. Вот так fval = 1.2999f; ааа. понял. спасибо. правда тут я для примера поставил константное значение, реально это результат вычислений или fval = another_val. в таком случае нужен имплисит каст (float) несмотря на то что аргументы объявлены как float? понял. нужно делать каст. Изменено 31 августа, 2020 пользователем jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 31 августа, 2020 Опубликовано 31 августа, 2020 · Жалоба 1 hour ago, jenya7 said: аргументы объявлены как float? Какие аргументы? Я уже выше вам написал, что 1.89 // это double 1.89f // это float 7.88f // это float 10.520 // это double float abcd = 1.552f; // здесь компилятор присвоит константу типа флоат переменной типа флоат float efgh = 7.410; // здесь константа типа double будет присвоена переменной типа флоат, т.е. сначала будет вызвана процедура (программная) конвертации, // а затем произойдёт присвоение Рекомендую вам заглядывать в листинги. Там сразу увидите что к чему. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 31 августа, 2020 Опубликовано 31 августа, 2020 · Жалоба 1 hour ago, haker_fox said: Какие аргументы? Я уже выше вам написал, что 1.89 // это double 1.89f // это float 7.88f // это float 10.520 // это double float abcd = 1.552f; // здесь компилятор присвоит константу типа флоат переменной типа флоат float efgh = 7.410; // здесь константа типа double будет присвоена переменной типа флоат, т.е. сначала будет вызвана процедура (программная) конвертации, // а затем произойдёт присвоение Рекомендую вам заглядывать в листинги. Там сразу увидите что к чему. понял. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться