From e829a9e3ec39a8c18d5c5ce7a80c4fff9a2cdc2f Mon Sep 17 00:00:00 2001 From: DiamondNether90 Date: Wed, 17 Sep 2025 17:58:06 +1000 Subject: [PATCH] Exponents and logarithms --- packages/math/math.grnd | 119 +++++++++++++++++++++++++++++++++++++++- packages/math/readme.md | 12 ++++ 2 files changed, 128 insertions(+), 3 deletions(-) diff --git a/packages/math/math.grnd b/packages/math/math.grnd index 22f1db6..40e5cc1 100644 --- a/packages/math/math.grnd +++ b/packages/math/math.grnd @@ -29,6 +29,10 @@ fun -double !pi return 3.141592653589793 endfun +fun -double !e + return 2.718281828459045 +endfun + fun -double !intexp -double &base -int &power lesser $power 1 &store set &ans 1 @@ -206,8 +210,117 @@ fun -double !sqrt -double &in return $ans @error - error "Cannot find square root of a negative double" + error "Cannot find square root of a negative double" "mathError" endfun -pusharg -0.5 -call !sqrt &store \ No newline at end of file +fun -double !abs -double &in + lesser $in 0 &store + if $store %negative + return $in + + @negative + multiply $in -1 &in + return $in +endfun + +fun -double !exp -double &in + call !e &e + + lesser $in 0 &store + if $store %negative + + # Find $in rounded down + pusharg $in + stod "1.00" &store + pusharg $store + call !mod &floorin + subtract $in $floorin &floorin + pusharg $floorin + call !dtoi &floorin + + # e^(a+x)=e^a*e^x + pusharg $e + pusharg $floorin + call !intexp &e^a + + # Find e^($in - $floorin) + subtract $in $floorin &x + + # e^x = 1 + x + x^2/2 + x^3/6 + ... + x^k/k! + set &idx 0 + set &e^x 0 + @loop + equal $idx 10 &store + if $store %return + + pusharg $x + pusharg $idx + call !intexp &store + + pusharg $idx + call !factorial &fact + + divide $store $fact &store + + add $e^x $store &e^x + add $idx 1 &idx + + jump %loop + + @return + multiply $e^a $e^x &ans + return $ans + + @negative + # e^-x = 1/e^x + multiply $in -1 &in + pusharg $in + call !exp &store + divide 1 $store &store + return $store + +endfun + +fun -double !ln -double &in + greater $in 0 &store + if $store %calculate + jump %error + + @calculate + equal $in 1 &store + if $store %zero + + # We will use Newton's method. + # ln(a) is the root of e^x-a + # Therefore x_k+1 = x_k - (e^x_k - a)/(e^x_k) + + set &ans 0.9 + + @loop + pusharg $ans + call !exp &e^x + subtract $e^x $in &store + divide $store $e^x &store + subtract $ans $store &ans + + pusharg $store + call !abs &store + lesser $store 0.000000000001 &store + if $store %return + + jump %loop + + @return + return $ans + + @zero + stod "0" &zero + return $zero + + @error + error "Cannot find ln of a non-positive double" "mathError" +endfun + +pusharg 0.0000000000000000000000000000000000000000000001 +call !ln &store +stdlnout $store \ No newline at end of file diff --git a/packages/math/readme.md b/packages/math/readme.md index 11e34e8..226f2de 100644 --- a/packages/math/readme.md +++ b/packages/math/readme.md @@ -22,6 +22,14 @@ Gets the tan of input. Returns base^power, for positive integer values of power. Returns 1 if power is non-positive (and thus is inaccurate for negative values of power). +### fun -double !exp -double &input + +Finds exp($input), where exp(x)=e^x, e is Euler's number = 2.718281828... + +### fun -double !ln -double &in + +Finds the natural log (log_e) of $input, i.e. finds x such that e^x = $input, e is Euler's number = 2.718281828... + ### fun -double !sqrt -double &input Returns the positive value *x* that satisfies x^2 = input. Throws an error if input is negative. @@ -30,6 +38,10 @@ Returns the positive value *x* that satisfies x^2 = input. Throws an error if in Returns *n* such that *n* is congruent to the input modulo $modulus, where *n* is at least 0 and less than $modulus. +### fun -double !abs -double &in + +Returns the absolute value of *n*. + ### fun -double !random -int &seed Gets a random double in the domain [0,1), using a LCG. A seed is required.