17. marts 2011 - 20:40Der er
6 kommentarer og 1 løsning
BCMath Arbitrary Precision Mathematics
Hej folkens,
Jeg forsøger at lave en kemisk beregning i PHP - af pH-værdien af vandige opløsninger af syrer i meget lave koncentrationer. De meget lave koncentrationer medfører, at tallene vil være meget små - tilsyneladende mindre end PHP umiddelbart kan regne med dem. Mit script ser ud som følgende:
Langt udtryk: float(NAN) x: float(NAN) pH: float(NAN)
Hvis jeg derimod erstatter sqrt i ovenstående udtryk med bcsqrt er outputtet følgende:
Langt udtryk: float(6.53924680941E-8) x: float(1.05122255286E-7) pH: float(6.97830533036)
Jeg har lavet den samme beregning manuelt med henblik på at kontrollere resultatet - og jeg får følgende resultater:
x = 1,025 * 10^-7 pH = 6,989
Afvigelsen ude på 2. decimal skyldes formodentlig blot afrunding, så det må siges at være acceptabelt. Så langt, så godt - jeg fik noget der lignede det, jeg gerne ville have.
Derimod bliver det rigtig mystisk, når jeg giver $ks andre værdier - eksempelvis:
$ks = 1.738 * pow(10, -5);
Nu får jeg nemlig - selv ved brug af bcsqrt() - følgende output:
Langt udtryk: float(NAN) x: float(NAN) pH: float(NAN)
Jeg testede lige dit script. Den udregning du forsøger at tage sqrt af, er et negativt tal. Af samme grund kan man selvfølgelig ikke beregne sqrt :) Derfor får du NAN fejlen (not a number).
@intenz: Mange tak for dit svar. Du har selvfølgelig ret - det er i PHP ikke umiddelbart muligt at tage kvadratroden af et negativt tal, da PHP ikke kan håndtere imaginære tal. Du får selvfølgelig point for din observation - og det i øvrigt helt korrekte svar på, hvorfor output er NAN.
Det afføder dog et nyt problem. Formlen er nemlig korrekt. Jeg kan desværre ikke blot efter forgodtbefindende ændre fortegn - hvorfor det desværre ikke er en mulighed at tage den absolutte værdi af tallet. Min manuelle kontrolberegning er udført i MathCad - som også kan regne med komplekse (dvs. imaginære) tal. Kontrolberegningen i MathCad viser, at "langt udtryk" i MathCad bliver imaginær, hvis jeg udskriver værdien:
Langt udtryk = 2,142 * 10^-7 + 1,24i * 10^-7
Og i PHP: Langt udtryk = float(NAN)
Da dette blot er en midlertidig variabel (som er til for overskuelighedens skyld) er det ikke problematisk at tallet bliver imaginært, idet slutresultaterne (x og pH) bliver fine reelle tal:
x = 1,051 * 10^-7 pH = 6,978
Mit problem er således ikke af matematisk karakter - at jeg får et imaginært tal. Mit problem er derimod - så vidt jeg nu kan se - at PHP ikke kan håndtere imaginære tal. Jeg har forgæves kigget på nogle classes, men uden helt at finde hvad jeg søgte.
Men foreløbig mange tak! Yderligere input er meget velkomne.
@intenz: Tak for tippet. Jeg har i mellemtiden set nærmere på de to muligheder - og min umiddelbare konklusion er, at førstnævnte ser ud til at være lettest at gå til. Der ser ud til at være et væld af muligheder i PEAR, men den er temmelig dårligt dokumenteret - og da jeg endnu ikke har særlig meget erfaring med objektorienteret programmering vil jeg i første omgang ty til den mest veldokumenterede. Der medfølger nemlig bl.a. en sample.php - med en række eksempler på brug af klassen. Jeg melder tilbage, når jeg har gjort mig nogle erfaringer. Foreløbig mange tak!
Det ser umiddelbart brugbart ud - jeg er i stand til at udføre simple beregninger ved brug af den første PHP-klasse. Så langt, så godt. Desværre kommer jeg nu matematisk til kort, idet klassen ikke indeholder nogen potensfunktion - svarende til PHP's indbyggede pow-funktion, som desværre kun kan håndtere reelle tal. Jeg kunne ikke umiddelbart google mig til svaret på, hvad z^(1/3) er.
Tak for alle indspark - jeg ville blot lige lade jer vide, at problemet var løst.
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.