Sto implementando un algoritmo in C che deve eseguire rapidamente addizioni e sottrazioni modulari su interi senza segno e gestire correttamente le condizioni di overflow. Ecco cosa ho ora (che funziona):Addestramento e sottrazione modulari sicuri per il troppo pieno in C?
/* a and/or b may be greater than m */
uint32_t modadd_32(uint32_t a, uint32_t b, uint32_t m) {
uint32_t tmp;
if (b <= UINT32_MAX - a)
return (a + b) % m;
if (m <= (UINT32_MAX>>1))
return ((a % m) + (b % m)) % m;
tmp = a + b;
if (tmp > (uint32_t)(m * 2)) // m*2 must be truncated before compare
tmp -= m;
tmp -= m;
return tmp % m;
}
/* a and/or b may be greater than m */
uint32_t modsub_32(uint32_t a, uint32_t b, uint32_t m) {
uint32_t tmp;
if (a >= b)
return (a - b) % m;
tmp = (m - ((b - a) % m)); /* results in m when 0 is needed */
if (tmp == m)
return 0;
return tmp;
}
Qualcuno sa di un algoritmo migliore? Le librerie che ho trovato che fanno l'aritmetica modulare sembrano tutte per numeri di precisione arbitrari di grandi dimensioni che sono decisamente eccessivi.
Modifica: voglio farlo funzionare correttamente su una macchina a 32 bit. Inoltre, le mie funzioni esistenti sono banalmente convertite per funzionare su altre dimensioni di numeri interi senza segno, una proprietà che sarebbe piacevole conservare.
Sfortunatamente, non sono in grado di supporre che a e b siano inferiori a m per questa particolare applicazione. – ryanc
@ryanc: si potrebbe semplicemente aggiungere 'a% = m; b% = m;' all'inizio di ogni funzione. Ciò fornisce comunque algoritmi più semplici. Sono più veloci o più lenti degli algoritmi nell'OP, dipendono dall'hardware e dai valori dei parametri. –