2016-08-12 5 views
5

Ich habe eine Struktur darstellt, eine nicht-negative rationale Zahl p/q:Multipliziert ganze Zahl durch rationale ohne Zwischenüberlauf

struct rational { 
    uint64_t p; 
    uint64_t q; // invariant: always > 0 
}; 

Ich mag würde mein rational durch eine uint64 n und bekommen eine ganze Zahl Ergebnis abgerundet multiplizieren. Das heißt, würde ich berechnen mag:

uint64_t m = (n * r.p)/r.q; 

während Zwischenüberlauf zu vermeiden in n * r.p. (Natürlich kann das Endergebnis überlaufen, was akzeptabel ist.)

Wie kann ich das tun? Gibt es einen Weg, dies ohne eine hohe Multiplikation zu tun?

(ich boost :: sah rational, aber es scheint nicht, diese Funktion zur Verfügung zu stellen.)

+0

wäre es mit 'uint64_t m nicht funktioniert = (n/r.q) * r.p'? – dangom

+0

Berechnen Sie die rationale Zahl 'n/r.q', und reduzieren Sie sie auf ihre niedrigste Form, dann multiplizieren Sie diese mit' r.p'. – Barmar

+2

@DanielG, Barmar: Keine von diesen hilft, wenn "p == n" und "p q". – lorro

Antwort

0

Entweder 128-Bits und man könnte es Karatsuba Multiplikation verwenden; oder Sie könnten den chinesischen Restsatz verwenden, um (n * r.p) mod p1 und auch mod p2 darzustellen. Die zweite könnte langsamer sein.

0

können Sie peasant multiplication verwenden:

// requires 0 < c < 2^63 
// returns (a * b)/c. 
uint64_t multDiv(uint64_t a, uint64_t b, uint64_t c) { 
    uint64_t rem = 0; 
    uint64_t res = (a/c) * b; 
    a = a % c; 
    // invariant: a_orig * b_orig = (res * c + rem) + a * b 
    // a < c, rem < c. 
    while (b != 0) { 
    if (b & 1) { 
     rem += a; 
     if (rem >= c) { 
     rem -= c; 
     res++; 
     } 
    } 
    b /= 2; 
    a *= 2; 
    if (a >= c) { 
     a -= c; 
     res += b; 
    } 
    } 
    return res; 
} 
Verwandte Themen