Non so se esiste un qualche tipo di algoritmo standard per questo tipo di problema, ma mi incuriosisce, quindi ecco il mio tentativo di sviluppare un algoritmo che trovi l'approssimazione necessaria.
Chiama il numero reale in questione r
. Quindi, per prima cosa suppongo che a
possa essere negativo, in tal caso possiamo ridurre il problema e ora dobbiamo solo trovare un b
in modo che la parte decimale di sqrt(b)
sia una buona approssimazione della parte decimale di r
. Scriviamo ora r
come r = x.y
con x
essendo il numero intero e la parte decimale.
Now:
b = r^2
= (x.y)^2
= (x + .y)^2
= x^2 + 2 * x * .y + .y^2
= 2 * x * .y + .y^2 (mod 1)
Ora abbiamo solo per trovare un x
tale che 0 = .y^2 + 2 * x * .y (mod 1)
(circa).
Riempimento che x
nelle formule sopra otteniamo b
e possiamo quindi calcolare a
come a = r - b
. (Tutti questi calcoli devono essere accuratamente arrotondati.)
Ora, per il momento non sono sicuro se c'è un modo per trovare questo x
senza forzarlo. Ma anche in questo caso, si può semplicemente usare un semplice ciclo per trovare uno x
abbastanza buono.
Sto pensando a qualcosa di simile (pseudo codice semi):
max_diff_low = 0.01 // arbitrary accuracy
max_diff_high = 1 - max_diff_low
y = r % 1
v = y^2
addend = 2 * y
x = 0
while (v < max_diff_high && v > max_diff_low)
x++;
v = (v + addend) % 1
c = (x + y)^2
b = round(c)
a = round(r - c)
Ora, credo che questo algoritmo è abbastanza efficiente, mentre anche che consente di specificare la precisione desiderata della approssimazione. Una cosa che potrebbe essere fatta per trasformarla in un algoritmo O (1) è calcolare tutti gli x
e inserirli in una tabella di ricerca. Se ci si preoccupa solo delle prime tre cifre decimali di r
(ad esempio), la tabella di ricerca avrà solo 1000 valori, che sono solo 4kb di memoria (supponendo che siano utilizzati gli interi a 32 bit).
Spero che questo sia utile a tutti. Se qualcuno trova qualcosa di sbagliato nell'algoritmo, per favore fammelo sapere in un commento e lo aggiusterò.
MODIFICA: Riflettendo, ritiro la mia richiesta di efficienza. In effetti, non posso garantire che l'algoritmo sopra descritto finisca mai e, anche se dovesse accadere, potrebbe richiedere molto tempo per trovare un valore molto ampio di x
che risolva adeguatamente l'equazione.
Si potrebbe forse tenere traccia dei migliori x
trovati finora e rilassare i limiti di precisione nel tempo per assicurarsi che l'algoritmo si interrompa rapidamente, al possibile costo di precisione.
Questi problemi sono ovviamente inesistenti, se si calcola semplicemente una tabella di ricerca.
Due cose non sono chiare per me: 1- in quale forma hai inizialmente il tuo numero reale; 2- considerando che l'algoritmo naive a forza bruta fornisce la risposta migliore nel tempo O (r) assumendo operazioni aritmetiche a tempo costante, come si chiama "sano"? (a meno che tu non permetta al parametro a di essere negativo, nel qual caso la forza bruta non funziona) –
Sì, sarebbe utile una migliore descrizione dei tuoi numeri reali. Alcuni real non possono essere rappresentati da un + sqrt (b), come Pi. – ckb
A e b dovrebbero essere interi positivi? –