Algoritmus druhej odmocniny s vysokou presnostou

C,C++,C#

Moderátori: psichac, Moderátori

miso156
Pokročilý člen
Pokročilý člen
Príspevky: 648
Dátum registrácie: 06 Dec 2020, 11:46
Bydlisko: Banska Stiavnica
Vek: 38

Algoritmus druhej odmocniny s vysokou presnostou

Príspevok od používateľa miso156 » 02 Máj 2023, 07:16

Zdar.
Potrebujem implementovat funkciu druhej odmocniny do MCU presnu na 9 a viac cislic.
Pouzil by som z math.h, ale mam float rieseny svojpomocne (mam dovod), nie cez beznu kniznicu a tym padom by mi to nespolupracovalo.
Preto som hladal nejaku metodu pre vypocet sqrt(). Nasiel som nieco na stranke:
https://davinci.fmph.uniba.sk/~forgacov ... /A13_4.php
Skusil som to hodit do Cecka.
Nie je to extra rychle, pre presny vypocet to potrebuje bajoko 10 iteracii.
Poznate nieco lepsie?

Fast inverse square root ktory je implem. napr. v Quake III Arena mi nevyhovuje lebo rata s nizkou presnostou.


Screenshot from 2023-05-02 06-57-15.png
0
"No pain, no gain." (KC238)

epto
Stály člen
Stály člen
Príspevky: 151
Dátum registrácie: 09 Nov 2012, 16:23
Bydlisko: Seňa

Re: Algoritmus druhej odmocniny s vysokou presnostou

Príspevok od používateľa epto » 02 Máj 2023, 13:10

ked sa opytas AI, vypluje ti toto:
Samozrejme, môžem vám pomôcť s algoritmom na výpočet druhej odmocniny z čísla bez použitia knižnice math pre platformu Arduino.

Na začiatok je dobré poznamenať, že existuje niekoľko rôznych spôsobov, ako vypočítať odmocninu. Tu vám ukážem jeden zo spôsobov pomocou iterácií a postupného zlepšovania odhadu odmocniny.

Algoritmus by mohol vyzerať takto:

Na začiatku si určíme, pre ktoré číslo chceme vypočítať druhú odmocninu.
Nastavíme si hodnotu pre odhad odmocniny (napr. p), ktorú si môžeme zvoliť napr. ako polovicu zadaného čísla.
V cykle budeme postupne zlepšovať náš odhad. Pre každú iteráciu budeme vypočítať nový odhad odmocniny ako priemer predchádzajúceho odhadu a zadaného čísla podeleného predchádzajúcim odhadom:
css
Copy code
p = (p + (number / p)) / 2
Tento vzorec pochádza z Newtonovej metódy na výpočet odmocniny.
Opakujeme krok 3. určitý počet krát (napr. 10-20), alebo dokým sa hodnota nového odhadu odmocniny dostatočne nezmení.
Po skončení cyklu máme vypočítanú druhú odmocninu zadaného čísla.
Tu je ukážka kódu pre tento algoritmus v jazyku Arduino:

C++
Copy code
<code>
float square_root(float number) {
float p = number / 2.0;
float e = 0.00001; // tolerancia
for (int i = 0; i < 20; i++) { // maximálny počet iterácií
float p_next = (p + (number / p)) / 2.0;
if (abs(p_next - p) < e) { // kontrola na dostatočnú zmenu odhadu
return p_next;
}
p = p_next;
}
return p;
}
/<code>
V tejto ukážke sme si zvolili toleranciu (t.j. maximálnu zmenu medzi dvomi po sebe nasledujúcimi odhadmi) ako 0.00001 a maximálny počet iterácií ako 20, ale tieto hodnoty môžete prispôsobiť vašim potrebám.

Dúfam, že vám toto pomôže a že sa vám podarí vypočítať druhú odmocninu čísla pomocou tohto algoritmu na platforme Arduino.
0

epto
Stály člen
Stály člen
Príspevky: 151
Dátum registrácie: 09 Nov 2012, 16:23
Bydlisko: Seňa

Re: Algoritmus druhej odmocniny s vysokou presnostou

Príspevok od používateľa epto » 02 Máj 2023, 13:12

dakujem, potreboval by som kod pre dosiahnutie vysokej presnosti vysledku

ChatGPT
Ak hľadáte spôsob, ako dosiahnuť vyššiu presnosť výsledku, môžete vylepšiť náš predchádzajúci algoritmus a pridať niekoľko iterácií na zlepšenie presnosti. Niekedy však môže byť veľký počet iterácií nepraktický, pretože bude znamenať dlhšiu dobu výpočtu.

Jedným z možných spôsobov, ako dosiahnuť vyššiu presnosť, je použitie knižnice BigDecimal, ktorá umožňuje pracovať s číslami s veľkým počtom desatinných miest. Táto knižnica nie je súčasťou štandardnej knižnice Arduino, ale môže byť nainštalovaná ako externá knižnica.

Tu je ukážka kódu, ktorý používa knižnicu BigDecimal na výpočet druhej odmocniny s vyššou presnosťou:

C++
Copy code
#include <BigDecimal.h>

BigDecimal square_root(BigDecimal number, int precision) {
BigDecimal p = number / 2;
BigDecimal e("0.1");
e = e.pow(precision + 1);
for (int i = 0; i < 50; i++) {
BigDecimal p_next = (p + (number / p)) / 2;
if ((p - p_next).abs() < e) {
return p_next.round(precision, ROUND_HALF_UP);
}
p = p_next;
}
return p.round(precision, ROUND_HALF_UP);
}

void setup() {
Serial.begin(9600);
BigDecimal::begin(30); // inicializácia knižnice s presnosťou 30 desatinných miest
BigDecimal number("1234.5678");
BigDecimal result = square_root(number, 20); // presnosť výsledku je 20 desatinných miest
Serial.println(result.toString());
}

void loop() {
}
V tomto príklade sme si zvolili presnosť 20 desatinných miest, ale túto hodnotu môžete prispôsobiť podľa vašich potrieb.

Poznámka: Použitie knižnice BigDecimal môže byť náročné na pamäť a výpočetný výkon, preto ju odporúčame používať iba v prípadoch, keď je veľká presnosť naozaj nevyhnutná. Ak nie je potrebná taká vysoká presnosť, odporúčame použiť predchádzajúci algoritmus a zvoliť primeranú toleranciu a počet iterácií na dosiahnutie dostatočnej presnosti výsledku.
0

miso156
Pokročilý člen
Pokročilý člen
Príspevky: 648
Dátum registrácie: 06 Dec 2020, 11:46
Bydlisko: Banska Stiavnica
Vek: 38

Re: Algoritmus druhej odmocniny s vysokou presnostou

Príspevok od používateľa miso156 » 02 Máj 2023, 16:34

Dik.

Je to to iste len uhladnejsie napisane. Tym sa rovnako presny vysledok dosiahne uz pri 9tej iteracii.
Aj to pomoze, hehe.
Presiel som nejake fora, zazraky sa cakat nedaju. Vsetko je to na iteracnej baze.
Trochu sa to da asi zrychlit vhodnym odhadom vysledku pred zacatim vypoctu.

Screenshot from 2023-05-02 16-35-02.png
0
"No pain, no gain." (KC238)

Napísať odpoveď