Обаче тая стратегия е добра и за конвертиране към десетична стойност. Цената е едно деление което е трудно да се избегне. Дори на х64 умножението по 10 е възможно с последователност от 2 инструкции без умножение.
unsigned utos( char *s, unsigned val ) {
uint64_t xval = ( val * 0x100000000ULL + 999999999 ) / 1000000000;
unsigned i, j, x;
for( j = i = 0; i < 10; i++ ) {
s[j] = ( x = xval >> 32 ) + '0';
if( x ) break;
xval *= 10;
}
while( i++ < 9 ) {
xval = (uint32_t)xval;
xval *= 10;
s[++j] = ( xval >> 32 ) + '0';
}
s[++j] = 0;
return j;
}
Jetson Orin Nano Super Developer Kit
67 TOPS за $250.
Докато се наканя, разпродадоха всичко което имаха. :(
Реба Създадено на 17.12.24 18:59, видяно: 148 пъти. #129664
универсалното делене си е бавно ако не ти е хардуерно. мене наскоро ми излезе като проблем и мисля да мина с таблица със степените на десятката
Едно делене или 128 битово умножение щото е голяма константа. Което е един път за конвертирането на цялата стойност към десетична бройна система. Пак е добре.
Реба Създадено на 04:57, видяно: 116 пъти. #129674
е добре е, на фона на обичайния код за микроконтролери който се вее из интернет. човек, ползват % за да циклят в буфер който е с размер степен на двойката, смятай. аз от друга страна нарочно не си линквам либгцц за да не се изкушавам да деля. в момента карам с printf който има само %x и %s , мисля все пак да добавя и %d
Може да разчитат компилатора да сведе % до & при оптимизацията. Най-вероятно и компилатора не пасе трева като го види това. И аз се изкушавам вместо >> да ползвам / със степен на 2 за по-добра прегледност. Въпреки че още не съм го правил. Трябва да се види компилатора какво генерира.
ПС: Например разчитам че това умножение * 0х100000000ULL ще се сведе до чист << 32 или диретно зареждане в старшата двойна дума.
Реба Последно редактирано на 05:52 от Дон
Реба, видяно: 103 пъти. #129676
то компилатора вероятно го прави, но двете неща не са баш идентични, трябва да е именно & а не %. ако нещо осереш и завъртиш поинтера назад, ще получиш - 1%256 което е - 1, а не 255 и ще почнеш да пишеш и четеш извън буфера. отделно че компилатора трябва да добави още 3-4 инструкции за знака, та да превърне & в %
Щом си стигнал до printf, делението ти е най-малкия проблем за скорост. :)
Реба Създадено на 13:42, видяно: 66 пъти. #129687
не е до скорост, за микроконтролерите гледам всичко да ми е под 100% контрол. либгцц може и да линкна ако видя зор, ама за сега се справям и без него. да не забравяме че от ей такива дреболии е тръгнал рънтайма и е стигнал до днешните безумия и помощ, помощ winsxs ми напълни диска
Аз затова избягвам да използвам printf изобщо ако ме вълнува контрол. Не знам как е имплементирано в libgcc, но си спомням главоболията с libc като линкна всичките i18n идиотщини, които така или иначе никой не използва.
Едно време имаше една ulibc която беше по-читава, но не знам как е за микроконтролери, май беше за Линукс.
Между другото, най-добрия вариант за printf би бил стринга да се парсва когато се компилира и да се заменя със съответните функции за печатане. Би работило идеално в 99.9% от случаите.
Реба Създадено на 19:13, видяно: 27 пъти. #129697
там е работата че не знаеш дали печата, в момента по-често праща по някой сериен порт
Е то е ясно че от микроконтролер най-често ще се праща по сериен порт.
Това не е важно. Идеята е
printf("ala %d bala %04x nica %s\n", x, y, s);
да се направи на
printstr("ala "); printdec(x, 0, 0); printstr(" bala "); printhex(y, 4, 1);
printstr(" nica "); printstr(s); printstr("\n");
Така няма да се налага да парсваш стрингс за форматиране на микроконтролера.