Odpovídáte na názor k článku Specifika instrukční sady mikroprocesorů Intel 8086/8088 (2). Názory mohou přidávat pouze registrovaní uživatelé. Nově přidané názory se na webu objeví až po schválení redakcí.
Jj, vypocty na 8bitech byly peklo. V drevnich dobach jsme se ucili zaklady DSP (zde P = processing) na pripravcich s 8051...
Pred 20 lety jsem presel na ARMy a tam treba na slabych Cortexech s jednocyklovou nasobickou, ale casove drahym delenim konci rychla konverze utoa treba takto:
uint8_t * bin2dec(uint32_t u, uint8_t * dest) { uint8_t * d = dest; uint64_t r; if (u < 100UL) { /* 1 & 2 digits */ ECHO2DECDIGCOND(d, u) goto lm0; } else if (u < 1000000UL) { if (u < 10000UL) { /* 3 & 4 digits */ /* (100..9999) * (2^32 / 100) -> 2^32 / 100 = 42,949,672.96 -> 42,949,673 */ r = (uint64_t)u * 42949673UL; u = (uint32_t)(r >> 32U); ECHO2DECDIGCOND(d, u) d += 2UL; goto lm2; } else { /* 5 & 6 digits */ /* 10000..999999 * (2^32 / 10000) -> 2^32 / 10000 = 429,496.7296 -> 429,497 */ r = (uint64_t)u * 429497UL; u = (uint32_t)(r >> 32U); ECHO2DECDIGCOND(d, u) d += 4UL; goto lm4; } } else { if (u < 100000000UL) { /* 7 & 8 digits */ /* 1000000..99999999 * (2^32 / 1000000) -> 2^32 / 1000000 = 4,294.967296 -> 4,294 */ /* The multiplication precision is not sufficient */ /* 1000000..99999999 * (2^(32 + 16) / 1000000) -> 2^(32 + 16) / 1000000 = 281,474,976.710656 -> 281,474,977 */ r = ((uint64_t)u * 281474977UL) >> 16U; u = (uint32_t)(r >> 32U); ECHO2DECDIGCOND(d, u) d += 6UL; goto lm6; } else if (u <= 1160773632UL) { // 9 & 9+1/2 digits /* 100000000..4294967295 * (2^32 / 100000000) -> 2^32 / 100000000 = 42.94967296 -> 43 */ /* The multiplication precision is not sufficient */ /* 100000000..1160872980 * (2^(32 + 25) / 100000000) -> 2^(32 + 25) / 100000000 = 1,441,151,880.75855872 -> 1,441,151,882 ! */ // -> it works up to 1160872980 only! // For immediate comparison -> 1,160,773,632 <-> 0x45300000 11-bit value r = ((uint64_t)u * 1441151882UL) >> 25U; u = (uint32_t)(r >> 32U); ECHO2DECDIGCOND(d, u) goto lm8; } else { /* 10 digits */ /* 100000000..4294967295 * (2^32 / 100000000) -> 2^32 / 100000000 = 42.94967296 -> 43 */ /* The multiplication precision is not sufficient */ /* 100000000..4294967295 * (2^(32 + 25) / 100000000) -> 2^(32 + 25) / 100000000 = 1,441,151,880.75855872 -> 1,441,151,881 */ r = (uint64_t)u * 1441151881UL; u = (uint32_t)(r >> 57U); ECHO2DECDIGCOND(d, u) /* Fix back to 32-bit fraction */ r >>= 25U; goto lm8; } } lm8: r = (r & 0xFFFFFFFFUL) * 100UL; u = (uint32_t)(r >> 32U); ECHO2DECDIG(d - 8UL, u) d += 8UL; lm6: r = (r & 0xFFFFFFFFUL) * 100UL; u = (uint32_t)(r >> 32U); ECHO2DECDIG(d - 6UL, u) lm4: r = (r & 0xFFFFFFFFUL) * 100UL; u = (uint32_t)(r >> 32U); ECHO2DECDIG(d - 4UL, u) lm2: r = (r & 0xFFFFFFFFUL) * 100UL; u = (uint32_t)(r >> 32U); ECHO2DECDIG(d - 2UL, u) lm0: *d = 0U; return d; }
To ECHO... makro neni nic jineho nez sahnuti do 200bajtove tabulky dvojic znaku. Cilem bylo zvolit takove multiplikativni konstanty, aby byly potreba 32bitove posuny, tj. zadne, takze to uint64_t je vicemene takova berlicka pro C.