Подскажите как разбить число точками.
Есть число long к примеру 29500000, нужно для вывода на дисплей сделать его таким 29.500.000, а так же число может состоять не из 8ми знаков а из 7ми к примеру 3000000 а нужно вывести на экран 3.000.000
Делается символьный буфер, число последовательно делится на 10, остаток от деления кладётся (символ цифры) в буфер, через каждые три символа вставляется точка.
Как число закончится, выводится на экран в обратном порядке.
Зачем три раза делить на 10, когда можно один раз разделить на 1000?
на 10 делить столько раз, сколько циферок в числе. Вообще вариантов в интернете множество, и мой не единственный.
Делить на 1000, пока результат деления не даст 0
древний код нашел свой
void logPrintInt(unsigned long currentInt) {
while (logTXbusy());
logStartTX();
unsigned char locBuf[16]; // строковый буфер где мы будем сохранять текст
unsigned long tmInt = currentInt; // сохраняем число во временную переменную
unsigned char i = 0; // позиция строкового буфера
do {locBuf[i++] = tmInt % 10 + '0';} // кладем остаток от деления на 10 временного числа в строковый буфер - идет с маладшего разряда
while ((tmInt /= 10) > 0); // до тех пор, пока деленное на 10 временная переменная больше нуля
locBuf[i] = '\0'; // заканчиваем строку нулем
for(unsigned char j=i; j>0; --j) { // бежим циклом по строке в обратном порядке
_logTXbuf[i-j] = locBuf[j-1]; // и кидаем байты в отправляемый буфер
}
unsigned short locLen = strlen((const char *)locBuf);
HAL_UART_Transmit_DMA(&huart3, (unsigned char *) _logTXbuf, locLen);
}
осталось добавить точки
void print_group(long value, byte num = 3, char divider = '.');
void setup() {
Serial.begin(115200);
print_group(1234567890);
Serial.println();
print_group(1234567890, 2);
Serial.println();
print_group(1234567890, 4, ',');
}
void loop() {
}
void print_group(long value, byte num, char divider) {
byte l = byte(log10(abs(value))) / num * num;
long m = 10;
for (byte i = 1; i < l; i++, m *= 10);
int n = value / m;
Serial.print(n);
if (l > 0) Serial.print(divider);
value = abs(value % m);
while (l != 0) {
l--;
m /= 10;
n = value / m;
Serial.print(n);
if ((l > 0) && (l % num) == 0) Serial.print(divider);
value = value % m;
}
}
1.234.567.890
12.34.56.78.90
12,3456,7890
Строки 18-19 это типа long m = pow(10, l);
, но что то pow
считает на своей волне …
Скетч использует 2238 байт (6%) памяти устройства. Всего доступно 32256 байт.
Глобальные переменные используют 188 байт (9%) динамической памяти, оставляя 1860 байт для локальных переменных. Максимум: 2048 байт.
что-то ты перемудрил, как мне кажется…
Вот твоя функция втрое короче и без логарифмов:
void print_group(long value, byte num, char divider) {
byte l = 0;
while (value != 0) {
Serial.print(value % 10);
if ((l > 0) && (l % num) == 0) Serial.print(divider);
value = value /10;
l++;
}
}
А она не задом-наперёд выводит ???
а, точно
Ну ща поправим…
готово…
Отредактировано, код см в #12
И про знак числа не забываем …
Знак пусть сам делает
По итогам тестов исправил пару ошибок, код такой:
void print_group(long value, byte num, char divider) {
byte l = 0;
char buf[24];
char* ptr = buf + 23;
*ptr-- = '\0';
while (value != 0) {
if ((l > 0) && ((l % num) == 0)) *ptr-- = divider;
*ptr-- = '0' + (value % 10);
value = value /10;
l++;
}
ptr++;
Serial.print(ptr);
}
Sketch uses 51952 bytes (4%) of program storage space. Maximum is 1048576 bytes.
Global variables use 6852 bytes (2%) of dynamic memory, leaving 288060 bytes for local variables.
Maximum is 294912 bytes.
в мониторе
1.234.567.890
12.34.56.78.90
12,3456,7890
ТС придется про указатели гуглить … , а судя по другим темам у него с этим мушкела …
Код @b707
Скетч использует 2106 байт (6%) памяти устройства. Всего доступно 32256 байт.
Глобальные переменные используют 188 байт (9%) динамической памяти, оставляя 1860 байт для локальных переменных. Максимум: 2048 байт.
У меня для Нано компилируется так:
Sketch uses 1852 bytes (6%) of program storage space. Maximum is 30720 bytes.
Global variables use 188 bytes (9%) of dynamic memory
где-то у тебя еще 250 байт сверху накидывается…
Полный код
void print_group(long value, byte num = 3, char divider = '.');
void setup() {
Serial.begin(115200);
print_group(1234567890);
Serial.println();
print_group(1234567890, 2);
Serial.println();
print_group(1234567890, 4, ',');
}
void loop() {
}
void print_group(long value, byte num, char divider) {
byte l = 0;
char buf[24];
char* ptr = buf + 23;
*ptr-- = '\0';
while (value != 0) {
if ((l > 0) && ((l % num) == 0)) *ptr-- = divider;
*ptr-- = '0' + (value % 10);
value = value /10;
l++;
}
ptr++;
Serial.print(ptr);
}
Ардуино ИДЕ 1.8.19
Fedora35 x64
У меня 328PB чип выставлен … и MiniCore …
Если выставить arduino uno, то цифры бьются один в один …
хорошо потусили
Надо ещё через vector
попробовать …
не, я все эти производные типы из STDlib стараюсь не использовать… это не для МК, на мой взгляд
Есть косяк для нулевого значения !
if (value == 0) {Serial.print('0'); return;}
первой строчкой добавить… и все
Что в твой код. что в мой