_Title "Power Function 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
' 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 "Far from precise of course, but 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 2 other subs
'bExpand20$
'split though for this split is overkill
r$
= "0" + Str$(pow
) 'in case pow starts with decimal Split s$(), r$, "."
build = 1.0
build = build * x
'that takes care of integer part,
'now for the fraction part convert decimal to fraction
n$ = s$(1)
denom& = 10
denom& = denom& * 10
'OK for bExpand20$ don't have to simplify and that saves us having to extract n and d again from n/d
bs$ = bExpand60$(numer&, 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 of 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 be a 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$
curpos = 1: arrpos = 0
c
= Mid$(mystr
, curpos
, 1) ' Get 1 ctr arr(arrpos) = arr(arrpos) + c
arrpos = arrpos + 1
curpos = curpos + 1