ex-2/fancier: fix crash in mpq_log_ui on power of 2
This commit is contained in:
parent
5c7f46ce2f
commit
ce91072040
@ -85,6 +85,10 @@ char* mpq_dec_str(mpq_t z, size_t mantissa_size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* printf() like function with special conversion %q, which
|
||||||
|
* prints the deciamal expansion of mpq_t rational numbers.
|
||||||
|
* The second argument is the number of digits shown.
|
||||||
|
*/
|
||||||
void mpq_fprintf(FILE *fp, size_t digits, char* fmt, ...) {
|
void mpq_fprintf(FILE *fp, size_t digits, char* fmt, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
@ -243,6 +247,26 @@ void mpq_log_ui(mpq_t rop, size_t x, size_t digits) {
|
|||||||
fprintf(stderr, "[mpq_log_ui] binary digits: %ld\n", m);
|
fprintf(stderr, "[mpq_log_ui] binary digits: %ld\n", m);
|
||||||
fprintf(stderr, "[mpq_log_ui] a=%g\n", mpq_get_d(a));
|
fprintf(stderr, "[mpq_log_ui] a=%g\n", mpq_get_d(a));
|
||||||
|
|
||||||
|
// calculate log(2)*(m-1)
|
||||||
|
mpq_t log2; mpq_init(log2);
|
||||||
|
mpq_log2(log2, digits);
|
||||||
|
|
||||||
|
mpz_mul_ui(mpq_numref(log2), mpq_numref(log2), m-1);
|
||||||
|
mpq_canonicalize(log2);
|
||||||
|
|
||||||
|
/* When x is a power of two a=1 and y=0.
|
||||||
|
* The series for log(1+y/1-y) is not defined for y=0
|
||||||
|
* so this case must be handled separately.
|
||||||
|
*/
|
||||||
|
if (mpq_cmp_ui(a, 1, 1) == 0) {
|
||||||
|
mpq_set(rop, log2);
|
||||||
|
|
||||||
|
// free memory
|
||||||
|
mpq_clears(a, log2, NULL);
|
||||||
|
mpz_clears(xz, power, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* calculate y = (a-1)/(a+1) */
|
/* calculate y = (a-1)/(a+1) */
|
||||||
mpq_t y, temp; mpq_inits(y, temp, NULL);
|
mpq_t y, temp; mpq_inits(y, temp, NULL);
|
||||||
|
|
||||||
@ -366,13 +390,6 @@ void mpq_log_ui(mpq_t rop, size_t x, size_t digits) {
|
|||||||
mpq_fprintf(stderr, d+2, "[mpq_log_ui] lower bound: %q...\n", low);
|
mpq_fprintf(stderr, d+2, "[mpq_log_ui] lower bound: %q...\n", low);
|
||||||
mpq_fprintf(stderr, d, "[mpq_log_ui] series: %q...\n", sum);
|
mpq_fprintf(stderr, d, "[mpq_log_ui] series: %q...\n", sum);
|
||||||
|
|
||||||
// calculate log(2)*(m-1)
|
|
||||||
mpq_t log2; mpq_init(log2);
|
|
||||||
mpq_log2(log2, digits);
|
|
||||||
|
|
||||||
mpz_mul_ui(mpq_numref(log2), mpq_numref(log2), m-1);
|
|
||||||
mpq_canonicalize(log2);
|
|
||||||
|
|
||||||
// series += log(2)*(m-1)
|
// series += log(2)*(m-1)
|
||||||
mpq_add(sum, sum, log2);
|
mpq_add(sum, sum, log2);
|
||||||
mpq_set(rop, sum);
|
mpq_set(rop, sum);
|
||||||
|
Loading…
Reference in New Issue
Block a user