ToR_TDA 0 6 мая, 2020 Опубликовано 6 мая, 2020 · Жалоба Здравствуйте форумчане! Такой вопрос у меня как правильно преобразовать целочисленное знаковое число в строку без преобразования во float. Имеем переменную int16_t current; Она соответствует физическому значению измеряемого тока следующим образом: 32767 = 3,2767A -32768 = -3,2768A Есть необходимость преобразовать это в форматированную строку вида: I= 3,277A I=-3,277A Использую функцию sprintf, но она хорошо работает только для положительных чисел и чисел менее -10000 (менее -1.000A) sprintf(Str_Buffer, "I= %1d.%03d A", current/10/1000, current/10%1000); При значении например -0.623A этот код отдаст строку "0.-623", а не "-0.623" Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 14 6 мая, 2020 Опубликовано 6 мая, 2020 · Жалоба Знак отдельно печатайте: char sign = i < 0 ? '-' : ' '; if (i < 0) i = -i; sprintf(buf, "I= %1c%1d.%03d A", sign, current/10000, (current/10)%1000); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rkit 1 6 мая, 2020 Опубликовано 6 мая, 2020 · Жалоба Проще взять и написать самому с нуля функцию, формирующую нужную строку. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 6 мая, 2020 Опубликовано 6 мая, 2020 · Жалоба Вместо последовательности /...% лучше использовать функцию div(). Еще можно просто добавить десятичную точку в нужную позицию строки, сформированной printf. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 7 мая, 2020 Опубликовано 7 мая, 2020 · Жалоба Цитата Использую функцию sprintf, но она хорошо работает только для положительных чисел и чисел менее -10000 (менее -1.000A) Функция не при чём, просто Вы не умеете ею пользоваться. Всё легко и просто: s16 current; int i = current; char c = '+'; if (i < 0) { c = '-'; i = -i; } uint j = (uint)i / 10000u; sprintf(..., "I= %c%u.%04u A", c, j, (uint)i - j * 10000u); //возможно для AVR-компилятора int/uint лучше заменить на short/ushort - не знаю, не пользуюсь 5 часов назад, AHTOXA сказал: Знак отдельно печатайте: char sign = i < 0 ? '-' : ' '; if (i < 0) i = -i; sprintf(buf, "I= %1c%1d.%03d A", sign, current/10000, (current/10)%1000); То, что Вы не знаете математики, нам уже давно известно, но всё таки - такое количество ляпов в 3-х строчках! - это должно быть слишком даже для Вас.... PS: А вообще: Ваш пример - пожалуй неплохой способ сделать как можно более тормозной код Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 14 7 мая, 2020 Опубликовано 7 мая, 2020 · Жалоба 5 часов назад, jcxz сказал: То, что Вы не знаете математики, нам уже давно известно, но всё таки - такое количество ляпов в 3-х строчках! - это должно быть слишком даже для Вас.... Что, Славик, соскучился? :-) Ну давай, обосновывай свои наезды. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ToR_TDA 0 7 мая, 2020 Опубликовано 7 мая, 2020 · Жалоба 10 hours ago, AHTOXA said: Знак отдельно печатайте: О, огромная благодарность все так просто, я был слеп когда смотрел на форматы sprintf 10 hours ago, aaarrr said: Вместо последовательности /...% лучше использовать функцию div(). Спасибо! Переписал это так: int16_t current; char sign; div_t fracDigit; if (current >= 0) sign = ' '; else sign = '-'; fracDigit = div(current/10, 1000); sprintf(Str_Buffer, "I= %1c%1d.%03d A", sign, fracDigit.quot, fracDigit.rem); 5 hours ago, jcxz said: Функция не при чём, просто Вы не умеете ею пользоваться. Именно поэтому я и написал в раздел "В помощь начинающему" на форуме. Спасибо, идея аналогична первому ответу и в данной задаче сверх-оптимизация не требуется. 10 hours ago, rkit said: Проще взять и написать самому с нуля функцию, формирующую нужную строку. Возможно кому-то и проще. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 7 мая, 2020 Опубликовано 7 мая, 2020 · Жалоба 4 минуты назад, ToR_TDA сказал: Именно поэтому я и написал в раздел "В помощь начинающему" на форуме. Спасибо, идея аналогична первому ответу и в данной задаче сверх-оптимизация не требуется. Дело не в оптимизации - это мелочи. В "первом ответе" куча ляпов и багов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ToR_TDA 0 7 мая, 2020 Опубликовано 7 мая, 2020 · Жалоба 1 minute ago, jcxz said: Дело не в оптимизации - это мелочи. В "первом ответе" куча ляпов и багов. Но идея то правильная Я не из тех кто выбивает от людей на форуме готовый исполняемый код, мне нужна была лишь подсказка. И теперь все работает как нужно, еще раз спасибо всем за ответы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 7 мая, 2020 Опубликовано 7 мая, 2020 · Жалоба 10 минут назад, ToR_TDA сказал: Но идея то правильная Я не из тех кто выбивает от людей на форуме готовый исполняемый код, мне нужна была лишь подсказка. И теперь все работает как нужно, еще раз спасибо всем за ответы. Вы уверены что он действительно "работающий"? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ToR_TDA 0 7 мая, 2020 Опубликовано 7 мая, 2020 · Жалоба 8 minutes ago, jcxz said: Вы уверены что он действительно "работающий"? Да, я проверил все в железе на всем диапазоне несколько раз. Форматирование работает корректно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 14 7 мая, 2020 Опубликовано 7 мая, 2020 · Жалоба 1 минуту назад, ToR_TDA сказал: Форматирование работает корректно Славик вам намекает, что int16_t несимметричный - отрицательному значению -32768 нет соответствующего положительного. Это надо учесть при смене знака числа - либо преобразовать его в int32_t, либо менять знак уже после деления на 10/1000. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ToR_TDA 0 7 мая, 2020 Опубликовано 7 мая, 2020 · Жалоба 14 minutes ago, AHTOXA said: Это надо учесть при смене знака числа Если честно то не очень понял. Есть некоторое АЦП которое отдает мне данные так: 12 hours ago, ToR_TDA said: 32767 = 3,2767A -32768 = -3,2768A При этом коду 0x0000 соответствует ток 0А. В какой момент происходит неправильная смена знака? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 7 мая, 2020 Опубликовано 7 мая, 2020 · Жалоба 21 минуту назад, AHTOXA сказал: Славик вам намекает, что int16_t несимметричный До Андрюши похоже дошло.... Ну лучше поздно чем никогда. 25 минут назад, ToR_TDA сказал: Да, я проверил все в железе на всем диапазоне несколько раз. Форматирование работает корректно. Хозяин - барин. Ваш проект - вам виднее. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ToR_TDA 0 7 мая, 2020 Опубликовано 7 мая, 2020 · Жалоба 2 minutes ago, jcxz said: Хозяин - барин. Ваш проект - вам виднее. Не не не, если уж сказали то договаривайте, вот код который работает сейчас: int16_t current; char sign; div_t fracDigit; if (current >= 0) sign = ' '; else sign = '-'; fracDigit = div(current/10, 1000); sprintf(Str_Buffer, "I= %1c%1d.%03d A", sign, fracDigit.quot, fracDigit.rem); В какой момент происходит проблема? И почему я не вижу ее по показаниям? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться