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

#### dedndave

• Member
• Posts: 8828
• Still using Abacus 2.0
##### 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: 868
##### 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
hdc      dq  0
mov rcx,[n3]
lea rbx,testout
invoke dwtoa,rcx,[BufAdd]      ; Hex DD to string
; output is in testout
; 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: 1196
##### 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: 179
##### 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 SECTIONn1  DQ 1.00416n2  DQ 15.0n3  DQ 0buf DB 100 DUP ?CODE SECTIONStart:    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: 8828
• Still using Abacus 2.0
##### 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;###############################################################################################        .DATAn1  REAL8 1.00416n2  REAL8 15.0n3  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,0main    ENDP;###############################################################################################        END     main`
result:
Code: [Select]
`0.06694399999999999Press any key to continue ...`

#### shankle

• Member
• Posts: 868
##### 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: 1378
##### 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: 179
##### 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: 868
##### 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: 868
##### 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
"%g",[n3]

#### dedndave

• Member
• Posts: 8828
• Still using Abacus 2.0
##### Re: multiplying/dividing a positive decimal number by a positive number
« Reply #26 on: March 09, 2015, 08:02:00 AM »
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: 8828
• Still using Abacus 2.0
##### 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: 868
##### 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: 8828
• Still using Abacus 2.0
##### 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