Я управляю некоторыми большими (128 ~ 256 бит) целыми числами с помощью gmp. Настал момент, когда я хотел бы умножить их на двойное число, близкое к 1 (0,1 ‹ двойное ‹ 10), при этом результат все равно будет приближенным целым числом. Хорошим примером операции, которую мне нужно сделать, является следующее:
int i = 1000000000000000000 * 1.23456789
Я искал в документации gmp, но не нашел для этого функции, поэтому в итоге я написал этот код, который, кажется, работает хорошо:
mpz_mult_d(mpz_class & r, const mpz_class & i, double d, int prec=10) {
if (prec > 15) prec=15; //avoids overflows
uint_fast64_t m = (uint_fast64_t) floor(d);
r = i * m;
uint_fast64_t pos=1;
for (uint_fast8_t j=0; j<prec; j++) {
const double posd = (double) pos;
m = ((uint_fast64_t) floor(d * posd * 10.)) -
((uint_fast64_t) floor(d * posd)) * 10;
pos*=10;
r += (i * m) /pos;
}
}
Не могли бы вы сказать мне, что вы думаете? Есть ли у вас какие-либо предложения, чтобы сделать его более надежным или быстрым?