ViKo 1 7 сентября, 2017 Опубликовано 7 сентября, 2017 · Жалоба Есть 16-битовый знаковый результат с АЦП, нужно написать его в виде строки с целой и дробной частями и точкой в заданной позиции. Например, 336 нужно изобразить в виде +3.36. С выравниванием по правому краю. Рабочий пример показываю ниже. Использую буфер на 8 символов. Конец строки тоже входит в буфер, и поэтому число -0.32109 не помещается, будет выводиться в виде -.32109 (может, и не стоило так ограничиваться, но это позже всплыло). Пример не очень нравится, просто на скорую руку слепил. Если кому интересно поупражняться в программировании, покажите, как можно. /*!************************************************************************* @brief 16-bit integer convert to ASCII with comma and signum @param num - число для преобразования @param str - строка из 8 символов: знак, цифры, точка, конец строки @param pointpos - позиция точки в строке (1..6, количество мест перед ней) @param showplus - записывать символ '+' @note при pointpos = 0, > 6 - точка не ставится */ void Half2TextPoint_conv(int16_t num, char *str, uint32_t pointpos, bool showplus) { char *strleft = str; // левая граница строки (только для знака) *(uint32_t *)(str ) = ' ' | ' ' << 8 | ' ' << 16 | ' ' << 24; *(uint32_t *)(str + 4) = ' ' | ' ' << 8 | ' ' << 16 | '\0'<< 24; bool fract = true; // дробная часть рассчитана или не нужна if (pointpos >= 1 && pointpos <= 6) { *(str + pointpos) = '.'; fract = false; // дробная часть нужна, пока не получена } char sign = ' '; if (showplus) sign = '+'; if (num < 0) { sign = '-'; num = -num; } str += 6; do { if (*str == '.') { str--; fract = true; } *str = num % 10 + '0'; str--; } while ((num /= 10) || !fract); // пока нужна дробная часть if (str < strleft) str++; // проскочили из-за запятой в поз. 1 и числа < 1 *str = sign; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 77 7 сентября, 2017 Опубликовано 7 сентября, 2017 · Жалоба void Half2TextPoint_conv (int16_t data, char * str, int pointpos, bool showplus){ static const int16_t pow10_table[] = {10000, 1000, 100, 10, 1}; bool add0 = false; if (data < 0) {*str++ = '-'; data =-data;} else if (showplus) *str++ = '+'; for (int i = 0; i < 5; i++){ if (i == 5-pointpos) { if (!add0) *str++ = '0'; *str++ = '.'; add0 = true; } int16_t pow10 = pow10_table[i]; int digit = 0; while (data >= pow10) { data -= pow10; digit++; } if (digit) {*str++ = ('0' + digit); add0 = true;} else if (add0) *str++ = '0'; } *str = 0; } pointpos показывает количество знаков после запятой. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 7 сентября, 2017 Опубликовано 7 сентября, 2017 · Жалоба Я предполагал попробовать преобразовывать в два этапа - сначала преобразовать число, потом добавить знак, вставить точку и нуль перед ней и после нее, если надо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bw429 0 8 сентября, 2017 Опубликовано 8 сентября, 2017 · Жалоба А printf может всегда выводить знак, даже если "+"? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 8 сентября, 2017 Опубликовано 8 сентября, 2017 · Жалоба А printf точку в середину числа не вставит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bw429 0 8 сентября, 2017 Опубликовано 8 сентября, 2017 · Жалоба Можно выводить частное от деления на 10000, потом точку, потом остаток. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 27 8 сентября, 2017 Опубликовано 8 сентября, 2017 · Жалоба А printf может всегда выводить знак, даже если "+"? Да. %-012.2f Точно не понмю, но печатал всегда со знаком. Вопрос в "ведущих" нулях. Надо курить реализацию форматов printf на конкретном компиляторе, а также зависит от подулюченных библиотек. Для IAR/MSP430 - отличается CLIB / DLIB . . . . Если вопрос только в установке формата (места точки и размерах целой-дробной частей) то в (s)printf есть параметр *, через который можно в нее (приннтф) передавать эти значения. Т.о. вместо написания отдельной ф-ии, возможно, достаточно будет реализовать макрос-обертку с установкой требуемого формата #define MyPrint(target, var, point_left_, point_right) \ sprintf( target, "%*.*f", point_left, point_right, &var) \ В работе я эту конструкцию не проверял, небыло необходимости. Получится или нет - надо курить док на printf. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 1 октября, 2017 Опубликовано 1 октября, 2017 (изменено) · Жалоба После долгих мытарств решил делать так static inline int IntToStr(int x, char str[], int d) { int i = 0; do { str[i++] = (x % 10) + '0'; } while ((x /= 10) > 0); // If number of digits required is more, then // add 0s at the beginning while (i < d) str[i++] = '0'; Reverse(str, i); str[i] = '\0'; return i; } void FtoA(float n, char *res, int afterpoint) { int ap = afterpoint; //signed? if(n < 0) { n *= -1; *res = '-'; res++; } // Extract integer part int ipart = (int)n; // Extract floating part float fpart = n - (float)ipart; // convert integer part to string int i = IntToStr(ipart, res, 0); // check for display option after point if (afterpoint != 0) { res[i] = '.'; // add dot // Get the value of fraction part up to given no. // of points after dot. The third parameter is needed // to handle cases like 233.007 //fpart = fpart * pow(10, afterpoint); while (ap) { fpart *= 10; ap--; } IntToStr((int)fpart, res + i + 1, afterpoint); } } хотя это немного не то что требуется. ну пусть висит. Изменено 1 октября, 2017 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
skripach 6 5 октября, 2017 Опубликовано 5 октября, 2017 · Жалоба А printf может всегда выводить знак, даже если "+"? Может Да. %-012.2f %+012.2f void Half2TextPoint_conv(int16_t num, char *str, uint32_t pointpos, bool showplus) { char mod[]="%00.0f"; if(showplus) mod[1] = '+'; if(pointpos>6) pointpos = 0; mod[4] = pointpos+0x30; sprintf(str, mod, ((float)num/pow(10,pointpos))); } :santa2: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться