Any integer POW function?

Monkey Forums/Monkey Programming/Any integer POW function?

ziggy(Posted 2012) [#1]
I need a fast integer pow functino. Current function is Float, and when I assign its result to an integer, it gets truncated. As instance, 10^2 is 99.9999999 (becouse of floating point precission)wich is converted to 99 when set to an integer, instead of 100. I could add a rounding routine BUT, is there any integer POW function, or do anybody have a decent implementation for it?

This example shows the ussue on stdcpp:
[monkeycode]Function Main()
Local a:Int = 10
Local b:Int = 2
Local result:Int = math.Pow(a,b)
Print result
End[/monkeycode]
It looks like it should output 100, but it is showing 99 due truncation.

I've written this as a workaround, but I'm pretty sure there may be a faster solution:[monkeycode]Function PowInt:Int(value1:Int, value2:Int)
Local result:Int
if value2>0 Then
result = value1
For Local i:Int = 2 to value2
result*=result
Next
Return result
ElseIf value2 = 0 Then Return 1

Else
Return 0
EndIf
End[/monkeycode]


Beaker(Posted 2012) [#2]
Is this any good?
Function ipow:Int(base:Int, exp:Int)
	Local result:Int = 1
	While exp
		If exp & 1
			result *= base
		End
		exp Shr= 1
		base *= base
	Wend

	Return result
End



ziggy(Posted 2012) [#3]
Yes, this is great! Thanks Beaker. I've just added a possitive exp check before to avoid an infinite loop. Other than that, it works perfectly well, It's appreciated.


Floyd(Posted 2012) [#4]
I was going to complain about exp as a variable name, thinking it was already used by Monkey. But that is Exp, which is case sensitive as it is a function name, not a keyword.

Powers of a number grow so quickly that this will be of limited use. For small exponents you can just multiply, e.g. x*x and x*x*x for square and cube.

And if x=2, which is often the only value of interest, Pow should already be exact.


ziggy(Posted 2012) [#5]
And if x=2, which is often the only value of interest, Pow should already be exact.

The problem with current Pow is it is Float, and it truncates the result when assigned to an Int. In the example I posted in the first post shows the issue where 10^2 evaluates to 99 instead of 100 (you have to compile it using stdcpp to see the issue).


Floyd(Posted 2012) [#6]
What I meant was that a replacement for Pow(x,n) is not needed for the most common values of x and n.

Pow(2,n) is exact, so no problem there.

And we don't really need Pow(x,2) since we can use x*x.

Even Pow(x,3) and Pow(x,4) can be done conveniently by x*x*x and x*x*x*x.

Of course there are situations where none of this applies and iPow is useful.


ziggy(Posted 2012) [#7]
Ah yes, I was looking for a generic integer function as I need it for a scripting language I'm working on, as in the language the Pow is an operator, it has to behave properly on integer data-types avoiding any issues caused by internal conversion of data types and truncation of results. The compiler cannot always detect the value of the exp at compile time, so if it has to be executed in the form of a function at runtime, I need something reliable. That's what the function was for.


NoOdle(Posted 2012) [#8]
Thank you, I really needed this as well. I've been having problems with Pow( 10, x ) visually the numbers are not correct as ziggy mentioned, and when multiplied the results are quite inaccurate which is a problem as its for a LC Resonance Frequency Calculator.