News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

cubic root

Started by clamicun, March 18, 2017, 04:13:29 AM

Previous topic - Next topic

clamicun

I am "playing around" with FPU instructions.
Trying to build a small calculator.
It exists FSQRT to get the square root of the value in ST(0).
But I am breaking my head to get a cubic root.
There is no FPU instruction.
Any ideas ?

FORTRANS

Hi,

Quote from: clamicun on March 18, 2017, 04:13:29 AM
Any ideas ?

   Look at the exponential function and raise your value to the
one third power.

Cheers,

Steve N.

clamicun

Thank you Steve,

if you say "function" do you refer to
Logarithmic and exponential instructions ?

F2XM1     2 to the X power Minus 1
FSCALE    SCALE ST(0) by ST(1)
FYL2X     Y*Log2X
FYL2XP1   Y*Log2(X+1)

FORTRANS

Hi,

   Yes.  Particularly F2XM1.  FSCALE uses only integer exponents.

HTH,

Steve

clamicun

Thanks ... will try it

jj2007

Example:

include \masm32\MasmBasic\MasmBasic.inc      ; download
  Init

  fld FP10(0.33333333333333333333333333333)
  fld FP10(8.0)      ; 2^3
  fyl2x
  f2xm1
  fld1
  fadd
  Print Str$("The result is %Jf\n", ST(0))

  fld FP10(0.33333333333333333333333333333)
  fld FP10(1.8816763723536577724902657494247)      ; 1.2345^3
  fyl2x
  f2xm1
  fld1
  fadd
  Print Str$("The result is %Jf\n", ST(0))

EndOfCode


Output:
The result is 2.000000000000000000
The result is 1.234567890123456789


There is a more detailed example Posted on 2003-08-20 12:59:18 by Raymond, plus a fairly complex function that does not have the limitations of the log functions - see attachment (opens in WordPad in case you don't have RichMasm).

Mikl__

Root of the N-th power of the number
      fld Exponent
      fld st ;st=st(1)
      fabs ;st=|exp|
      fld Max
      fcompp ;leave exp in st(0)
      fstsw ax
      sahf
      jb @@RealPower ;exp > MaxInt?
      fld st ;exp=st(0)=st(1)
      frndint ;round(exp)
      fcomp ;compare exp and round(exp)
      fstsw ax
      sahf
      jne @@RealPower
      fistp IntExp
      mov eax, IntExp ;eax=Trunc(Exponent)
      mov ecx, eax
      cdq
      fld1 ;st(0)=1
      xor eax, edx
      sub eax, edx ;eax=|exp|
      jz @@Exit
      fld Base
      jmp @@Entry
@@Loop:fmul st, st ;st(0)=Base^2
@@Entry:shr eax, 1
      jnc @@Loop
      fmul st(1), st ;Result * X
      jnz @@Loop
      fstp st
      cmp ecx, 0
      jge @@Exit
      fld1
      fdivrp ;st(0)=1/Result
      jmp @@Exit
@@RealPower:fld Base
      ftst
      fstsw ax
      sahf
      jz @@Done
      fldln2
      fxch
      fyl2x
      fxch
      fmulp st(1), st
      fldl2e
      fmulp st(1), st
      fld st(0)
      frndint
      fsub st(1), st
      fxch st(1)
      f2xm1
      fld1
      faddp st(1), st
      fscale
@@Done:fstp st(1)
@@Exit:

clamicun

JJ,
fld FP10(8.0)      ; 2^3 ok.
If I change this to e.g.
fld FP10(27.0)      ; 3^3 not ok.
fld FP10(64.0)      ; 4^3 not ok.
??

raymond

If you have the MASM32 FDK,  you can use the FpuXexpY function of the provided Fpu.lib library, with 1/3 as the exponent. Or, if you want to code the FPU yourself, you can always look at the source code of that function and adapt it to your own specific needs.
Whenever you assume something, you risk being wrong half the time.
https://masm32.com/masmcode/rayfil/index.html

clamicun


Mikl__

Guten Abend, clamicun!
Wählen Sie die Daten auf eigene Faust. Das Programm berechnet nicht nur die Wurzel des Würfels

clamicun

Mikl__ Danke,
aber was ist der "Input" ? --- also der Wert aus dem die 3Wurzel berechnet werden soll --- Max ?

intExp ??
base  ??

jj2007

Quote from: clamicun on March 19, 2017, 02:26:48 AM
JJ,
fld FP10(8.0)      ; 2^3 ok.
If I change this to e.g.
fld FP10(27.0)      ; 3^3 not ok.
fld FP10(64.0)      ; 4^3 not ok.
??

Quote from: jj2007 on March 18, 2017, 12:02:36 PMThere is a more detailed example Posted on 2003-08-20 12:59:18 by Raymond, plus a fairly complex function that does not have the limitations of the log functions

There is no easy way out :bgrin:

clamicun

JJ,
"CubeLogA"  from Raymond works perfekt  with integers ...
wonder how floats are working.

Mikl__

#14
; GUI #
include win64a.inc
include msvcrt.inc
includelib msvcrt.lib
.data
n dd 3.0,3.0,3.0,3.0;exponent
y dd 125.0,?,?,?;number
x dd ?,?,?,?;result
.code
WinMain proc
sub esp,28h
movups xmm0,y
rcpps xmm1,n ;xmm1=1/exponent
invoke powf;float powf(float x, float y);Calculates x raised to the power of y 
        movups x,xmm0;x=y^{1/n}
fld x
fistp x
mov eax,x
invoke ExitProcess,0
WinMain endp
end