Nikolay801_ (23.03.2016 10:15, просмотров: 233) ответил SciFi на Во-первых, не понимаю я этот птичий язык. Во-вторых, нахуа? Чем sprintf не угодил? В третьих, ну, бывает, sprintf толстоват - сишный вариант будет в 2 раза толще асмового, что за печаль? Зато без мозголомства. В третьих, если уж совсем припёрло -
этот птичий язык означает следующие. число преобразуется в десятичный формат начиная со старших разрядов. Для этого вычисляется результат деления на 10000. Чтобы не использовать деление преобразуемое число умножается на 2^32, а затем делится 10000. Что эквивалентно умножению на магик нумбер (2^32/10000). те при умножении на этот магик нумбер в результате получается значение в котором с 32 бита и выше находится значение старшего десятичного разряда, а ниже все младшие в остатке. Дальше остальные разряды получаются умножением остатка на 10 и извлекаются по границе слова.
Так как из выше сказанного ясно, что все вычисления производятся с разрядностью больше чем слово у дспика, то это и рождает путаницу с тасовкой данных по регистрам, классика жанра.
Соответствующий код на це.
#define SCL (429497ul)
/*********************************
*
*********************************/
void itoa_(uint16_t val, uint8_t * str){
uint32_t remainder;
uint64_t scaledVal;
scaledVal = (uint64_t)SCL * val;
str[0] = '0' + (scaledVal >> 32);
remainder = scaledVal >> 16;
remainder = (uint16_t )(remainder + 1);
for (int i = 0; i < 4; i++){
remainder *= 10;
str[i + 1] = '0' + (remainder >> 16);
remainder = (uint16_t )remainder;
}
}
На сколько он оптимален я даже задумываться не собираюсь, но у моего моего процессора разрядность 32 есть инструкция умножения возвращающая результат в 64 бита и инструкции для паковки и распаковки битовый полей, так что все возможности сделать компактно и быстро есть, с робкой надеждой что компиллер родит хороший код.
ЗЫ у дспика есть инструкция аппаратного деления, которая одновременно считает остаток. Можно сделать это преобразование тупо, просто и очевидно.
Будь ты проклят, Перри-Утконос!