Kod: Markera allt
V = (A*x + B*(M-x));
Jag tror man blir tvungen att lära sig hur kompilatorn vill ha det, eller skriva inline-assembler om det är viktigt exakt hur detta görs.
Kod: Markera allt
V = (A*x + B*(M-x));
Kod: Markera allt
uint8_t a;
uint16_t b;
a * b;
Kod: Markera allt
uint8_t a;
uint16_t b;
((uint16_t)a) * b;
Kod: Markera allt
V = (A*x + B*(M-x));
Jag vet inte om jag hänger med på vad du menar här, på vilket sätt skulle t.ex.superx skrev:Om man castar alla 8-bitarsvariablerna till 16-bitar finns möjligheten att kompilatorn gör detta först, och implementerar multiplikationerna som 16x16 bitar, vilket inte är det man vill.
Det där såg verkligen lovande ut. En multiplikation mindre, gånger 48 interpoleringar, det lär märkas på exekveringstiden.Swech skrev:Man kan ju skriva om...
W = (A*x + B*(M-x));
V = W / M;
(A*x + B(M-x)) / M
(A*x + B*M - B*x)/M
((A-B)*x + B*M)/M
B + (A-B)*X /M
Swech
Ah, du tänker så, men det kommer inte hända (om inte kompilatorn är hjärndöd ochsuperx skrev:Resultatet är detsamma, men den undre varianten kräver 4 multiplikationer istället för 1 om man har en 8-bitars-multiplikator.
Nä, det är det ingen som påstått. Tror det här stickspåret började med att jag påstod att C är dåligt på att beskriva den här typen av beräkningar. Min erfarenhet är tyvärr att kompilatorerna är rätt korkade med sånt här. Läs här t.ex.Men det är klart att du har en poäng i det du säger, C är inte target-oberoende,
det har ingen någonsin påstått, och vill man ha fullkomlig kontroll vad som händer
är det knacka asm som gäller.
Kod: Markera allt
long map(long x, long in_min, long in_max, long out_min, long out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
Jag tycker det är lite tvärtom, standarden hjälper till att ordna reda i vad som bör ske.superx skrev: Ibland tror jag kompilatorerna blir lite bakbundna av standarden också, så att de tvingas att göra en cast vid fel tillfälle för att uppfylla någon klausul i standarddokumentet.
Kod: Markera allt
uint32_t u32 = 0;
int32_t s32 = -1;
uint8_t u8 = 0;
int8_t s8 = -1;
(int64_t)(s32 - u32) => 0x00000000ffffffff
(int64_t)(s8 - u8) => 0xffffffffffffffff
Kod: Markera allt
uint16_t interp1(const uint8_t x, const uint8_t A, const uint8_t B, const uint8_t M)
{
uint8_t AB = A-B;
uint16_t V = B + (AB)*x/M;
return V;
}
Kod: Markera allt
uint16_t interp2(const uint8_t x, const uint8_t A, const uint8_t B, const uint8_t M)
{
uint16_t V = B + (A-B)*x/M;
return V;
}