Come da titolo mi serve calcolare l'espressione [a*2^n/b], dove a, b e n sono interi tali che 0<a<b< 2^32 e 32<=n<64, mentre le parentesi quadre indicano l'operazione di troncamento.
Volendo rimanere nell'ambito degli interi, ma senza scomodare classi/librerie sui big_int, avrei pensato a qualcosa del genere:
#include <stdio.h>
#include <inttypes.h>
uint64_t a_mul_2_to_n_div_b(const uint32_t a, const uint32_t b, uint8_t n)
{
n -= 32;
uint64_t a_ = (uint64_t)a << 32;
return (a_ / b << n) + (a_ % b << n) / b;
}
int main()
{
uint32_t a = 16845074;
uint32_t b = 2762592030;
uint8_t n = 40;
uint64_t d = a_mul_2_to_n_div_b(a, b, n);
printf("%"PRIu64"\n", d);
}
E' corretto?
Volendo invece utilizzare float/double suppongo si possa fare qualcosa del genere:
#include <stdio.h>
#include <inttypes.h>
int main()
{
uint32_t a = 16845074;
uint32_t b = 2762592030;
uint8_t n = 40;
uint64_t d = a * (double)((uint64_t)1 << n) / b;
printf("%"PRIu64"\n", d);
}
Ma ottengo un risultato sbagliato, e quindi, non avendo mai affrontato l'analisi numerica relativa ai numeri in virgola mobile, non so quanto un approccio del genere convenga (anche in termini di costo computazionale rispetto al precedente codice con gli interi).
In definitiva qual è secondo voi il modo più efficiente di calcolare quell'espressione?