Python Forum
Difference between math.pow and **
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Difference between math.pow and **
#1
I'm trying to write a script which uses the Steinhart-Hart equation to calculate the temperature of a thermistor from its measured resistance.

The formula is:
1/T = A + B(ln(R)) + C(ln(R))³
Where T is the temperature in Kelvin and A, B and C are given constants.
In this case:
a = 1.068981*10**-4
b = 2.120700*10**-4
c = 9.019537*10**-8

In my script, I have the formula as:
tk = 1/(a + b*math.log(r) + (c*math.log(r))**3)
But, when trying to fix another problem, I found someone has written it like this:
temp =   1 / (a + b * math.log(r) + c * pow(math.log(r), 3))
I thought both are technically the same, but when I tried the above example, it returns different values.

My version (using **3), returns this:
Temperature = 436.09 K
Temperature = 162.94 °C


Whereas the other version, using pow, returns this:
Temperature = 418.07 K
Temperature = 144.92 °C


So, what is the difference?

My full script:
# Resistance to temperature convertor for Betatherm 30K6A1* thermistor
print("Resistance to temperature convertor for Betatherm 30K6A1* thermistor")
print("====================================================================")
print("")
def main():
    
    import math

    # Constants
    a = 1.068981*10**-4
    b = 2.120700*10**-4
    c = 9.019537*10**-8    

    # Input measured resistance value
    while True:
        try:
            r = float(input("Enter the measured resistance value (Ω): "))
        except ValueError:
            print("Must be a numeric value...")
            continue
        else:
                break

    # Calculate temperature
    # This calculator uses the Steinhart-Hart equation
    # Formual: 1/T = A + B(ln(R)) + C(ln(R))³

    tk = 1/(a + b*math.log(r) + (c*math.log(r))**3)
    # Alternate version found on the internet
    # tk = 1/(a + b*math.log(r) + c*pow(math.log(r),3))
    tk = round(tk,2)
    print(f"Temperature = {tk} K")

    # Convert to celcius
    tc = tk-273.15
    print(f"Temperature = {tc} °C")
    print("Resistance at 25 °C should be 30 kΩ")
    print("")

    # Restart? yay or nay?
    restart = input("Do you want to convert another value? Y/N: ")
    print("")
    if restart.lower() == 'y':
        main()
    else:
        print("Goodbye")

main()
Reply
#2
The difference between c * pow(math.log(r), 3)) and (c*math.log(r))**3 is that the constant c is being cubed in the second one but not the first. Compare that to c*(math.log(r))**3
alloydog likes this post
Reply
#3
Aha, the problem was between keyboard and chair - a typo, I had too many brackets. Thanks.

Which is the "preferred" way of doing it? pow or **?

Or is it just personal preference?
Reply
#4
The function math.pow takes only x and y as arguments, where x is the base and y the exponent.
The function pow takes base, exp and mod. The docstring of pow says the following:
Output:
Signature: pow(base, exp, mod=None) Docstring: Equivalent to base**exp with 2 arguments or base**exp % mod with 3 arguments Some types, such as ints, are able to use a more efficient algorithm when invoked using the three argument form. Type: builtin_function_or_method
For calculations with cryptography algorithms integers and the modulo is used.
The pow function is optimized for this use case.

The math.pow doesn't have this kind of optimization and I think it uses the C implementation.
So, pow is like math.pow with an extra feature.

In addition, pow and ** calls __pow__(exp) on the instance.
You can't do this with math.pow, which expects a real number.
I think math.pow calls lesser functions behind the scenes, which should be faster with real numbers.
The call to __pow__ of instances is slower.
alloydog likes this post
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#5
Thanks for expanded explanation - I actually thought that pow was just a short hand version of math.pow. But now I know :)
Reply
#6
Additional bit of information from Python documentation which could help to avoid some pitfalls down the road:

Quote:The power operator binds more tightly than unary operators on its left; it binds less tightly than unary operators on its right. /../

Thus, in an unparenthesized sequence of power and unary operators, the operators are evaluated from right to left (this does not constrain the evaluation order for the operands): -1**2 results in -1.
alloydog likes this post
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  math.log versus math.log10 stevendaprano 10 2,315 May-23-2022, 08:59 PM
Last Post: jefsummers
  Why getting ValueError : Math domain error in trig. function, math.asin() ? jahuja73 3 3,707 Feb-24-2021, 05:09 PM
Last Post: bowlofred

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020