Author Topic: multiplying/dividing a positive decimal number by a positive number  (Read 23170 times)

dedndave

  • Member
  • *****
  • Posts: 8823
  • Still using Abacus 2.0
    • DednDave
Re: multiplying/dividing a positive decimal number by a positive number
« Reply #15 on: March 07, 2015, 12:03:38 AM »
not sure i see an advantage in that Michael
seems like more work   :redface:

shankle

  • Member
  • ****
  • Posts: 833
Re: multiplying/dividing a positive decimal number by a positive number
« Reply #16 on: March 07, 2015, 12:44:18 AM »
This is my latest attempt.......        3-6-2015
Revision Number two.

I loaded this code into my 64-bit GoAsm Program.
The program compiled without errors.
I changed your code from msvcrt:printf to Textout.
dwtoa has been changed to handle 64-bit registers.

I gave up on the fixed point suggestion.
Got a lot of invalid results that made no sense.
So something hidden was altering the results.

    n1        dq  1.00416
    n2        dq  15.0
    n3        dq  0
    fld  Q[n1]   ; load n1 into the ST0 register on the fpu stack
    fdiv Q[n2]   ; divide it by n2 directly from memory
    fstp Q[n3]   ; pop the results off the stack to memory
   
;   test code begin
    testout  db '                       ',0
    BufAdd   dq  0
    hdc      dq  0
    mov rcx,[n3]
    lea rbx,testout
    mov [BufAdd],rbx
    invoke dwtoa,rcx,[BufAdd]      ; Hex DD to string
                               ; output is in testout
    invoke TextOut, [hdc],200,600,addr testout,20
; test code end

The result of this code should be 0.066944
This is what I got - 4571453861756211473

Thanks Yuri for the sample code.
Thanks Dave for the pointer to "fpu tutorial by Raymond Filiatreault"

MichaelW

  • Global Moderator
  • Member
  • *****
  • Posts: 1209
Re: multiplying/dividing a positive decimal number by a positive number
« Reply #17 on: March 07, 2015, 12:53:52 AM »
seems like more work
Floating point operations in a HLL are much easier to understand and code. For a complex series of equations there would be a very large difference in coding effort.

Well Microsoft, here’s another nice mess you’ve gotten us into.

GoneFishing

  • Member
  • *****
  • Posts: 1071
  • Gone fishing
Re: multiplying/dividing a positive decimal number by a positive number
« Reply #18 on: March 07, 2015, 02:10:42 AM »
I realize that the "Real Men" here are going to frown on this, but you can ease the task of using the FPU by creating a simple helper DLL in a HLL (I used Pelles C for this) that provides functions that make it relatively easy to do simple calculations.
...
  Agree with Michael . Realising this fact was one another little step forward in my learning process.
I thought about implementing  this in ASM . As I don't have appropriate math background / floating point understanding I desided to make first draft in C++ and it took 100 lines of code to do that.
I borrowed Vec structure from famous on internet SMALLPT program :
Code: [Select]
struct Vec {       
  double x, y, z;               
  Vec(double x_=0, double y_=0, double z_=0){ x=x_; y=y_; z=z_; }
  Vec operator+(const Vec &b) const { return Vec(x+b.x,y+b.y,z+b.z); }
  Vec operator-(const Vec &b) const { return Vec(x-b.x,y-b.y,z-b.z); }
  Vec operator*(double b) const { return Vec(x*b,y*b,z*b); }
  Vec mult(const Vec &b) const { return Vec(x*b.x,y*b.y,z*b.z); }
  Vec& norm(){ return *this = *this * (1/sqrt(x*x+y*y+z*z)); }
  double dot(const Vec &b) const { return x*b.x+y*b.y+z*b.z; } // cross:
  Vec operator%(Vec&b){return Vec(y*b.z-z*b.y,z*b.x-x*b.z,x*b.y-y*b.x);}
};

How much lines of code will it take in ASM ?

P.S.: Moreover, it's a good way to learn from compiler - he(or she?) does know SSE better and I can tell him(or her?)  to optimize my code for , say, SSE2

Yuri

  • Member
  • **
  • Posts: 175
Re: multiplying/dividing a positive decimal number by a positive number
« Reply #19 on: March 07, 2015, 02:26:58 AM »
shankle
n3 is not an integer. It's in a floating point format, so you can't use dwtoa to convert it to a string. You need a function that does the same for floating point numbers. Or you can use one of the msvcrt.dll's functions.
Code: [Select]
DATA SECTION

n1  DQ 1.00416
n2  DQ 15.0
n3  DQ 0
buf DB 100 DUP ?

CODE SECTION

Start:
    fld Q[n1]   ; Load n1 into the ST0 register on the FPU stack.
    fdiv Q[n2]  ; Divide it by n2 directly from memory.
    fstp Q[n3]  ; Pop the result off the stack to memory.
    invoke msvcrt:sprintf_s, addr buf, sizeof buf, "%g / %g = %g", [n1], [n2], [n3]
    invoke user32:MessageBoxA, 0, addr buf, "Result", 0
    ret

dedndave

  • Member
  • *****
  • Posts: 8823
  • Still using Abacus 2.0
    • DednDave
Re: multiplying/dividing a positive decimal number by a positive number
« Reply #20 on: March 07, 2015, 06:51:58 AM »
hi Jack

i wrote this little test program
of course, it's 32-bit MASM syntax, but it might help

all you need is a 64-bit equiv of the FloatToStr2 function, which is part of the Masm32 library
i used REAL8's, because that's what the FloatToStr2 function uses

Code: [Select]
        INCLUDE    \Masm32\Include\Masm32rt.inc

;###############################################################################################

        .DATA

n1  REAL8 1.00416
n2  REAL8 15.0
n3  REAL8 0.0

;***********************************************************************************************

        .DATA?

buf db 20 dup(?)

;###############################################################################################

        .CODE

;***********************************************************************************************

main    PROC

    fld     n1   ; Load n1 into the ST0 register on the FPU stack.
    fdiv    n2   ; Divide it by n2 directly from memory.
    fstp    n3   ; Pop the result off the stack to memory

    INVOKE  FloatToStr2,n3,offset buf
    print   offset buf

        print   chr$(13,10)
        inkey
        INVOKE  ExitProcess,0

main    ENDP

;###############################################################################################

        END     main

result:
Code: [Select]
0.06694399999999999
Press any key to continue ...

shankle

  • Member
  • ****
  • Posts: 833
Re: multiplying/dividing a positive decimal number by a positive number
« Reply #21 on: March 07, 2015, 07:33:15 AM »
Thanks Dave and thanks for realizing I'm just a novice with FPU.
I tried your little proggie and the compiler complained that "Floattostr2
was not defined. I was unable to find any trace of it in GoAsm 64.
That does not mean it's not there.

In the mean time Yuris example does not work for me either.
I have no idea what goes in "Result". I would think it would be n3.
Anyway the example with "Result" in it gives errors.
« Last Edit: March 07, 2015, 09:57:37 AM by shankle »

rrr314159

  • Member
  • *****
  • Posts: 1382
Re: multiplying/dividing a positive decimal number by a positive number
« Reply #22 on: March 07, 2015, 10:34:49 AM »
shankle, this suggestion may be useless to you but, just to learn about FPU, u could drop back to 32-bit MASM and do it there. Nothing wrong with GoAsm or 64-bit but there are many more examples in good ol' MASM32 world. Figure it out with that tool, then it's easy to translate to other environments.

This is not to denigrate GoAsm, which looks like fine product, 64-bit, which I prefer, or Yuri's help; but he's only one person; dozens can help with MASM32.
I am NaN ;)

Yuri

  • Member
  • **
  • Posts: 175
Re: multiplying/dividing a positive decimal number by a positive number
« Reply #23 on: March 07, 2015, 05:47:36 PM »
Anyway the example with "Result" in it gives errors.
What errors does it give? Did you compile it as a standalone exe or put it in your program? It compiles and runs without errors for me.

shankle

  • Member
  • ****
  • Posts: 833
Re: multiplying/dividing a positive decimal number by a positive number
« Reply #24 on: March 08, 2015, 01:53:51 AM »
Thanks Yuri,
Your response made me take a closer look at the code I typed.
And yes, I made a typo. :redface:  Your code is now working.

shankle

  • Member
  • ****
  • Posts: 833
Re: multiplying/dividing a positive decimal number by a positive number
« Reply #25 on: March 09, 2015, 06:15:05 AM »
        3-8-2015
 This code gives the wrong value in GoAsm 64-bit
 Value should be 0.006
 Incorrect value is 280461;

hdc        dq  0
n1         dq  0
n2         dq  15  ;fixed value
n3         dq  0   ; result
buf        db '       ',0
HoldValue  db '     ',0 ; keyed in variable input ex: 0.090

    lea rcx,HoldValue   ; value is keyed input

    mov [n1],rcx ; (This is what I don't know how to do)
    fld Q[n1]    ;load n1 into the ST0 register on the fpu stack
   fdiv Q[n2]   ; divide it by n2 directly from memory
   fstp Q[n3]   ; pop the results off the stack to memory
    invoke msvcrt:sprintf_s,addr buf,sizeof buf,\
                   "%g",[n3]
    invoke TextOut, [hdc],200,345,addr buf,7
 

dedndave

  • Member
  • *****
  • Posts: 8823
  • Still using Abacus 2.0
    • DednDave
Re: multiplying/dividing a positive decimal number by a positive number
« Reply #26 on: March 09, 2015, 08:02:00 AM »
you want to use FILD (float integer load), instead of FLD (float load)
the value from RCX must be in memory
so, i sometimes just PUSH it on the stack and load it from there

Code: [Select]
    push    rcx
    fild qword ptr [rsp]   ;we have to tell the assembler the size of the integer
;
;
;
    pop     rcx

i guess, for GoAsm, it would be

Code: [Select]
    fild    Q[rsp]
« Last Edit: March 09, 2015, 09:39:03 AM by dedndave »

dedndave

  • Member
  • *****
  • Posts: 8823
  • Still using Abacus 2.0
    • DednDave
Re: multiplying/dividing a positive decimal number by a positive number
« Reply #27 on: March 09, 2015, 08:06:02 AM »
by the way, when you load an integer into the FPU,
it converts it, internally, to a REAL10 float
(all FPU operations are internally REAL10)

shankle

  • Member
  • ****
  • Posts: 833
Re: multiplying/dividing a positive decimal number by a positive number
« Reply #28 on: March 09, 2015, 10:40:43 AM »
Just a tad of clarification Dave.
Is [rsp] a typo or the 32-bit esp register?

dedndave

  • Member
  • *****
  • Posts: 8823
  • Still using Abacus 2.0
    • DednDave
Re: multiplying/dividing a positive decimal number by a positive number
« Reply #29 on: March 09, 2015, 11:08:34 AM »
RSP is the 64-bit wide stack pointer, counterpart to the 32-bit ESP

i'm assuming that you are writing 64-bit code