If people are going to play this game, they need to attach the code produced, preferably with instruction and cycle counts...
This bit has the advantage of being extremely obvious. Both multiplies are optimized to inline code:int main() { // multiply an 8bit number by 100, by first // multiplying by 25 (to yield a 16bit number) // and then by 4 (to yield 24 bits.)
uint16_t x = PORTB;
__uint24 x1 = x*25; // always fits in 16bits.
x1 *= 4; // fits in 24 bits...
PORTB = x1;
PORTB = x1>>8; // output all the bits...
PORTB = x1>>16;
}
Produces: 0: 88 b3 in r24, 0x18 ; 24
__uint24 x1 = x*25;
2: 90 e0 ldi r25, 0x00 ; extend to 16 bits.
4: 9c 01 movw r18, r24
6: 22 0f add r18, r18
8: 33 1f adc r19, r19
a: 22 0f add r18, r18
c: 33 1f adc r19, r19
e: 82 0f add r24, r18
10: 93 1f adc r25, r19
12: 9c 01 movw r18, r24
14: 22 0f add r18, r18
16: 33 1f adc r19, r19
18: 22 0f add r18, r18
1a: 33 1f adc r19, r19
1c: 82 0f add r24, r18
1e: 93 1f adc r25, r19
20: a0 e0 ldi r26, 0x00 ; extend to 24 bits.
x1 *= 4;
22: 88 0f add r24, r24
24: 99 1f adc r25, r25
26: aa 1f adc r26, r26
28: 88 0f add r24, r24
2a: 99 1f adc r25, r25
2c: aa 1f adc r26, r26
PORTB = x1;
2e: 88 bb out 0x18, r24 ; 24
That seems pretty good.Note that __uint24 is pretty new.
Annoyingly, there is no uint24_t. Also, gcc will will not inline a __uint24 * 10.