### Author Topic: Power function  (Read 2287 times)

#### B+

• Guest ##### Power function
« on: July 24, 2018, 02:39:24 am »
what? Naalaa has no power (function)! well here is one that offers some rough estimates:
Code: [Select]
`' 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' 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, 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.constant:wW 800wH 720hidden:set window 100, 20, wW, wHdo     wln "And now for the main event! We test the power#(x#, pow#) function!"    write "(nothing) quits, Please enter a real (float) decimal number raise to some power. x# = "    x# = rln#()    if x# = 0.0 then break    write "(nothing) quits, Please enter a real (float) decimal power. pow# = "    pw# = rln#()    if pw# = 0.0 then break    result# = power#(x#, pw#)    wln result#, " is what we estimate for x# raised to power of pow#"    wlnloopwlnwln "Far from precise of course, but this code is clear proof of concept!"wln " OMG, it worked!!!"wait keydown' A power function for real numbers (small ones but still!)' x# to the power of pow#function power#(x#, pow#)'this sub needs 2 other subs'rite\$'bExpand20\$    'this is going to follow covertReal2Fraction\$, first deal with integer part if any    r\$ = str\$(pow#)    s\$[] = split(r\$, ".")    integer\$ = s\$    build# = 1.0    if integer\$ <> "0"         p = int(integer\$)        for i = 1 to p            build# = build# * x#        next    endif    'that takes care of integer part,     'now for the fraction part convert decimal to fraction    n\$ = s\$    ld = len(n\$)    while rite\$(n\$, 1) = "0"        n\$ = left\$(n\$, ld - 1)         ld = len(n\$)     wend    denom = 10    for i = 2 to ld        denom = denom * 10        next    numer = int(n\$)    'OK for bExpand20\$ don't have to simplify and that saves us having to extract n and d again from n/d    bs\$ = bExpand20\$(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    for i = 1 to len(bs\$)        '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) = "1" then build# = build# * runningXSQR#    next    'our build# should be a estimate or x# to power of pow#    return build#endfunc'write a series of 1s and 0s that represent the decimal fraction n/d in binary 20 places longfunction bExpand20\$(nOver, d)    ' b for base    b# = 0.5    ' r for remainder    r# = float(nOver)/float(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    while f = 0        if r# < b#            s\$ = s\$ + "0"        else            s\$ = s\$ + "1"            if r# > b#                 r# = r# - b#            else                f = 1            endif        endif        c = c + 1        if c >= 20 then f = 1        b# = b# * 0.5     wend    return s\$endfunc'not right\$function rite\$(stringy\$, amount)    return mid\$(stringy\$, len(stringy\$) - amount, amount)endfunc`
« Last Edit: July 24, 2018, 03:34:23 pm by B+ »

#### B+

• Guest ##### Re: Power function
« Reply #1 on: July 24, 2018, 12:15:08 pm »
Oh apparently Naalaa does have a power function pow#(a#, b#) a closely kept secret I guess.

Here is why I thought it didn't have a power function (plus the keyword does not highlight when typed because I tried that before rolling my own):
« Last Edit: July 24, 2018, 03:34:33 pm by B+ »

#### B+

• Guest ##### Re: Power function
« Reply #2 on: July 24, 2018, 03:33:18 pm »
Wow in QB64, this power estimator is on par with the ^ operator!
Code: [Select]
`_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.CONST wW = 800CONST wH = 600SCREEN _NEWIMAGE(wW, wH, 32)_SCREENMOVE 360, 60_DEFINE A-Z AS _FLOATDO    PRINT "Testing the power(x, pow) function:"    INPUT "(nothing) quits, Please enter a real number to raise to some power. x = "; x    IF x = 0 THEN EXIT DO    INPUT "(nothing) quits, Please enter a real number for the power. pow = ", pw    IF pw = 0 THEN EXIT DO    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."    PRINTLOOPPRINTPRINT "This is matching the ^ operator very well! This code is clear proof of concept!"PRINT " OMG, it worked!!!"SLEEP' A power function for real numbers (small ones but still!)' x to the power of powFUNCTION power## (x AS _FLOAT, pow AS _FLOAT)    'this sub needs: bExpand60\$, leftOf\$, rightOf\$    DIM build AS _FLOAT    r\$ = "0" + STR\$(pow) 'in case pow starts with decimal    integer\$ = leftOf\$(r\$, ".")    build = 1.0    IF integer\$ <> "0" THEN        p = VAL(integer\$)        FOR i = 1 TO p            build = build * x        NEXT    END IF    'that takes care of integer part    n\$ = rightOf\$(r\$, ".")    IF n\$ = "" THEN power = build: EXIT SUB    'remove 0's to right of main digits    ld = LEN(n\$)    WHILE RIGHT\$(n\$, 1) = "0"        n\$ = LEFT\$(n\$, ld - 1)        ld = LEN(n\$)    WEND    'note: we are pretending that the ^ operator is not available, so this is hand made integer power    denom& = 10    FOR i = 2 TO ld        denom& = denom& * 10    NEXT    '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    FOR i = 1 TO LEN(bs\$)        '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    NEXT    'our build should now be an estimate or x to power of pow    power = buildEND FUNCTION'write a series of 1s and 0s that represent the decimal fraction n/d in binary 60 places longFUNCTION bExpand60\$ (nOver&, d&)    DIM b AS _FLOAT, r AS _FLOAT    ' 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    WHILE f% = 0        IF r < b THEN            s\$ = s\$ + "0"        ELSE            s\$ = s\$ + "1"            IF r > b THEN                r = r - b            ELSE                f% = 1            END IF        END IF        c% = c% + 1        IF c% >= 60 THEN f% = 1        b = b * 0.5    WEND    bExpand60\$ = s\$END FUNCTIONFUNCTION leftOf\$ (source\$, of\$)    posOf = INSTR(source\$, of\$)    IF posOf > 0 THEN leftOf\$ = MID\$(source\$, 1, posOf - 1)END FUNCTIONFUNCTION rightOf\$ (source\$, of\$)    posOf = INSTR(source\$, of\$)    IF posOf > 0 THEN rightOf\$ = MID\$(source\$, posOf + LEN(of\$))END FUNCTION`

#### ScriptBasic

• Guest ##### Re: Power function
« Reply #3 on: July 27, 2018, 04:18:36 am »
Quote
' 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)

Good luck finding a language that allows the results to be an expression rather than a variable.

#### B+

• Guest ##### Re: Power function
« Reply #4 on: July 27, 2018, 01:52:42 pm »
Quote
' 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)

Good luck finding a language that allows the results to be an expression rather than a variable.

Hi John,

The point of those 2 little examples was to show that 2 ^ 3.5 for instance can be calculated without the ^ operator.
The SQR(2) part of course is further evaluated down to a single value. 8 * 1.4142.. = 11.3137...

x to an integer power like x ^ n  where n is positive integer (and not real number with decimals) is easy peasy without ^

p = 1
for i = 1 to n
p = p * x
next

result: p = x ^ n when n is positive integer

Integer powers are easy to do without the ^ operator but how can we do a power that is a real number (AKA float or decimal) (and positive).

This became the first most crude estimate for x ^ power for the return value of function for the integer part only.

For the decimal part of the power, I took it as a fraction .75 = 75/100
and expanded that fraction to binary 1's and 0's.

Then I ran down the expansion a 0 or 1 at a time, keeping a running value of the sqr(sqr... (sqr(x))) for each step.
If the expansion had a 1 in it, then the return result was multiplied by that running value.
Such that by the time you reach the end of the expansion, you have a very decent estimate of x ^ power without using the ^.

From the time BASIC started using the ^ operator there had to be a way to calculate that expression because of course you can't use ^ to calculate an expression using the ^ operator. I don't know if this is the way it was done but it is the way it could have been done if the SQR() function was available.

#### ScriptBasic

• Guest ##### Re: Power function
« Reply #5 on: July 27, 2018, 11:22:45 pm »
Sorry!

I get what you meant now.

Code: [Select]
`' 2 ^ 3.5 = 2 ^ 3 * 2 ^ .5 = 8 * Sqr(2)' 3 ^ 3.5 = 3 ^ 3 * 3 ^ .5 = 27 * Sqr(3)PRINT FORMAT("%g",2 ^ 3.5),"\n"PRINT FORMAT("%g",2 ^ 3 * 2 ^ .5), "\n"PRINT FORMAT("%g",8 * Sqr(2)), "\n"PRINTNLPRINT FORMAT("%g",3 ^ 3.5),"\n"PRINT FORMAT("%g",3 ^ 3 * 3 ^ .5),"\n"PRINT FORMAT("%g",27 * Sqr(3)),"\n"`

jrs@jrs-laptop:~/sb/examples/test\$ scriba bpwr.sb
11.3137
11.3137
11.3137

46.7654
46.7654
46.7654
jrs@jrs-laptop:~/sb/examples/test\$