_TITLE "Power Function 2 by bplus" 'QB64 X 64 version 1.2 20180228/86 from git b301f92
' started 2018-07-23 Naalaa has no power function (or operator), so I wrote a power function for it.
' ''Power pack the short version.txt
' ''written for Naalaa 6 by bplus posted 2018-07-23
' ''extracted from large test of fractions, random number functions, string... in Power test.txt
' 2018-07-24 Power Function 2 split is replaced with two much smaller and very handy string functions.
' OMG the crazy thing worked! It produced decent estimates of roots given the limitations of precision...
' Now I want to see how well it works with far greater precision available. So here we are, looking to see
' how this function compares to the regualar ^ operator in QB64.
'from Naalaa comments:
' The main purpose of this code: to demo a power function for real numbers,
' I had an idea for how real numbers to the power of real numbers might be done ie x ^ y = ?
' This means that not only can you take SQR of a number, you can get cube or cube root, quartic, 5th 6th... roots and any multiple
' It came from this simple idea
' 2 ^ 3.5 = 2 ^ 3 * 2 ^ .5 = 8 * Sqr(2)
' 3 ^ 3.5 = 3 ^ 3 * 3 ^ .5 = 27 * Sqr(3)
' so 2 ^ 3.25 = 2 ^ 3 * 2 ^ .25
' what is 2 ^ .25 ? It is sqr(sqr(2)) !
' likewise 2 ^ 3.125 = 2 ^ 3 * 2 ^ 1/8
' what is 2 ^ 1/8 ? It is sqr(sqr(sqr(2))) !
' any decimal can be written as a sum of fraction powers of 2 ie 1/2^n, as any integer can be written in powers of 2.
' in binary expansions
' 1/2 = .1 or .5 base 10
' 1/4 = .01 or .25 base 10
' 1/8 = .001 or .125 base 10
' 1/16 = .0001 or .0625 base 10
' So with binary expansion of decimal, we can SQR and multiply our way to an estimate
' of any real number to the power of another real number using binary expansion of
' the decimal parts as long as we stay in Naalaa integer limits and are mindful of precision.
PRINT "Testing the power(x, pow) function:" INPUT "(nothing) quits, Please enter a real number to raise to some power. x = "; x
INPUT "(nothing) quits, Please enter a real number for the power. pow = ", pw
result = power(x, pw)
PRINT result;
" is what we estimate for"; x;
" raised to power of"; pw
PRINT x
^ pw;
" is what the ^ operator gives us." PRINT "This is matching the ^ operator very well! This code is clear proof of concept!" PRINT " OMG, it worked!!!"
' A power function for real numbers (small ones but still!)
' x to the power of pow
'this sub needs: bExpand60$, leftOf$, rightOf$
r$
= "0" + STR$(pow
) 'in case pow starts with decimal build = 1.0
build = build * x
'that takes care of integer part
n$ = rightOf$(r$, ".")
'remove 0's to right of main digits
'note: we are pretending that the ^ operator is not available, so this is hand made integer power
denom& = 10
denom& = denom& * 10
'OK for bExpand60$ don't have to simplify fraction and that saves us having to extract n and d again from n/d
bs$
= bExpand60$
(VAL(n$
), denom&
)
'at moment we haven't taken any sqr of x
runningXSQR = x
'run through all the 0's and 1's in the bianry expansion, bs$, the fraction part of the power float
'this is the matching sqr of the sqr of the sqr... of x
runningXSQR
= SQR(runningXSQR
) 'for every 1 in the expansion, multiple our build with the running sqr of ... sqr of x
IF MID$(bs$
, i
, 1) = "1" THEN build
= build
* runningXSQR
'our build should now be an estimate or x to power of pow
power = build
'write a series of 1s and 0s that represent the decimal fraction n/d in binary 60 places long
' b for base
b = 0.5
' r for remainder
r = nOver& / d&
' s for string$ 0's and 1's that we will build and return for function value
s$ = ""
' f for flag to stop
f% = 0
' c for count to track how far we are, don't want to go past 20
c% = 0
s$ = s$ + "0"
s$ = s$ + "1"
r = r - b
f% = 1
c% = c% + 1
b = b * 0.5
bExpand60$ = s$
posOf
= INSTR(source$
, of$
) IF posOf
> 0 THEN leftOf$
= MID$(source$
, 1, posOf
- 1)
posOf
= INSTR(source$
, of$
)