## Recommended Posts

I've implemented a certain algorithm which uses fractional exponents (PowF(float, float)) to calculate intermediate values.

Now I'm trying to convert this calculation (from AutoIt) to simple ASM instructions. Since PowF is quite a complex operation in ASM, because you have to balance instruction count and error (which should be less than 16bit precision in this case), I'd like to know more about the implementation of fractional exponents in AutoIt itself. The goal is to accurately recreate the results AutoIt would produce given the same input values If there are multiple different ways each calculation is handled given the size of the exponent, I'll only need the details for n^{0.9..1.5}. My approach would be to use a simple cvtps2dq SSE cycle, but I'm curious I will answer every single PM, and you are free to ask anything anytime.

##### Share on other sites

According to the latest (...) AutoIt 3.1 source code

```case OPR_POW:                           // ^
vOp2 = valStack.top();  valStack.pop();
vOp1 = valStack.top();  valStack.pop();

if ( vOp2.fValue() == 0.0 )
vOp1 = 1.0;
else if ( vOp1.fValue() == 0.0 && vOp2.fValue() < 0.0)
{
//double fTmp = 0.0;    // needed to prevent compiler error.

//vOp1 = 1.0/fTmp;  // invalid.  Return 1.#INF by forcing divide by 0. GIVES COMPILER WARNING
vOp1 = 0.0;
}
else if ( vOp1.fValue() < 0.0 && (vOp2.type() == VAR_INT32 || vOp2.type() == VAR_INT64) ) // integer (32 or 64 bit)
{
#ifdef _MSC_VER
// MS Compiler
vOp1 = qmathPow(qmathFabs(vOp1.fValue()), vOp2.fValue());
#else
vOp1 = pow(fabs(vOp1.fValue()), vOp2.fValue());
#endif
if (vOp2.nValue() & 1) // odd number
{
vOp2 = -1.0;
vOp1 *= vOp2;
}
}
else
#ifdef _MSC_VER
// MS Compiler
vOp1 = qmathPow(vOp1.fValue(), vOp2.fValue());
#else
vOp1 = pow(vOp1.fValue(), vOp2.fValue());
#endif

valStack.push(vOp1);
break;```
, AutoIt uses

```double _QMATH_LINK qmathPow(double __x, double __y)
{
__asm fld       qword ptr [esp + 12]
__asm fld       qword ptr [esp +  4]
__asm ftst
__asm fstsw     ax
__asm sahf
__asm jz        pow_zero

__asm fyl2x
__asm fld1
__asm fld       st(1)
__asm fprem
__asm f2xm1
__asm fscale

pow_zero:

__asm fstp      st(1)
__asm ret       16
}```
as long as it is compiled using a MSVC compliant compiler. Is this still the case? Edited by minx

I will answer every single PM, and you are free to ask anything anytime.

##### Share on other sites

I'll just answer this for myself by testing. It seems to still use MSVCs qmath.h or similar native library implementation:

```#include <AssembleIt.au3>

Local \$double_qmathPow
Local \$asmstrc = DllStructCreate("double __x;double __y;")
\$asmstrc.__x = 5.8
\$asmstrc.__y = 0.9535

_("             use32               ")

_("             fld qword[esp+12]   ")
_("             fld qword[esp+4]    ")
_("             ftst                ")
_("             fstsw ax            ")
_("             sahf                ")
_("             jz pow_zero         ")

_("             fyl2x               ")
_("             fld1                ")
_("             fld st1             ")
_("             fprem               ")
_("             f2xm1               ")
_("             fscale              ")

_(" pow_zero:                       ")
_("             fstp st1            ")
_("             ret                 ")
EndFunc

;_AssembleIt(\$double_qmathPowurntype, \$Name_of_Func_with_code, \$Type1 = "type", \$Param1 = 0, \$Type2 = "type", \$Param2 = 0....up to 20 params)
\$double_qmathPow    = _AssembleIt("double", "_QMATH_NAKED__QMATH_INLINE_double__QMATH_LINK_qmathPow", "double", \$asmstrc.__x, "double", \$asmstrc.__y)  ;thats all^^
\$double_autoit      = \$asmstrc.__x ^ \$asmstrc.__y

ConsoleWrite(@LF)
ConsoleWrite("+> (FASM)qmathPow: " & \$double_qmathPow & @LF)
ConsoleWrite("+> (AutoIt)^     : " & \$double_autoit & @LF)```
Edited by minx

I will answer every single PM, and you are free to ask anything anytime.

##### Share on other sites

It doesn't use qmath anymore. It uses the native MSVC libs. I think we stopped using qmath because of a couple of bugs.

##### Share on other sites

K, but the results are effectively the same (It works fine in this scenario.)

Edited by minx

I will answer every single PM, and you are free to ask anything anytime.

## Create an account

Register a new account

• ### Recently Browsing   0 members

×

• Wiki

• Back

• #### Beta

• Git
• FAQ
• Our Picks
×
• Create New...