Как разбить число точками

Подскажите как разбить число точками.
Есть число long к примеру 29500000, нужно для вывода на дисплей сделать его таким 29.500.000, а так же число может состоять не из 8ми знаков а из 7ми к примеру 3000000 а нужно вывести на экран 3.000.000

Делается символьный буфер, число последовательно делится на 10, остаток от деления кладётся (символ цифры) в буфер, через каждые три символа вставляется точка.
Как число закончится, выводится на экран в обратном порядке.

Зачем три раза делить на 10, когда можно один раз разделить на 1000?

1 лайк

на 10 делить столько раз, сколько циферок в числе. Вообще вариантов в интернете множество, и мой не единственный.

Делить на 1000, пока результат деления не даст 0

1 лайк

древний код нашел свой

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 байт.

2 лайка

что-то ты перемудрил, как мне кажется…
Вот твоя функция втрое короче и без логарифмов:

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++;
    }
}

А она не задом-наперёд выводит ???

а, точно :slight_smile:
Ну ща поправим…

готово…

Отредактировано, код см в #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
1 лайк

ТС придется про указатели гуглить … , а судя по другим темам у него с этим мушкела …

Код @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, то цифры бьются один в один …

1 лайк

хорошо потусили :slight_smile:
:+1:

Надо ещё через vector попробовать …

не, я все эти производные типы из STDlib стараюсь не использовать… это не для МК, на мой взгляд

Есть косяк для нулевого значения !

if (value == 0) {Serial.print('0'); return;}
первой строчкой добавить… и все

Что в твой код. что в мой