News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

multiplying/dividing a positive decimal number by a positive number

Started by shankle, February 28, 2015, 01:57:08 PM

Previous topic - Next topic

shankle

So on a computer how to div/mul a positive decimal number by a positive number?
Ex:  1.00416 by 15??? If this involves Floating Point math then I will have to start from scratch.
Works fine on a calculator but loses the decimal places on the computer.

Yuri

Yes, you will have to use the FPU.

DATA SECTION

n1  DQ 1.00416
n2  DQ 15.0
n3  DQ 0

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.
#if x64     ; Show the result.
    invoke msvcrt:printf, "%g / %g = %g", [n1], [n2], [n3]
#else
    invoke msvcrt:printf, "%g / %g = %g", [n1], [n1+4], [n2], [n2+4], [n3], [n3+4]
    add esp,1Ch
#endif
    ret

dedndave

well - learning to use the FPU is a good idea, and the results will be much faster

but, you can use "fixed point" math, as an alternative

1.00416 x 100000 = 100416
you can then divide 100416 by 15 using DIV
understand that the result is 100,000 times the desired answer
you can convert it to a string, and insert the decimal point   :biggrin:

FORTRANS

Hi,

   In the old forum I posted a DOS program to show how fixed point
arithmetic works.  Sort of.

http://www.masmforum.com/archive2012/5486_FIX2DEC.zip

  I think that is it.

Steve


shankle

Sorry Fortrans the file unzipped is not compatible with Windows 7.
Maybe you know some other way of reading it?

FORTRANS

HI,

   You can install a DOS emulator or virtual machine to run
16-bit programs.  DOSBOX, Bochs, and Virtual PC have been
mentioned by others as good solutions.

   As that program uses the BIOS to write to video memory in CGA
mode 3, I do not think it a good program to translate to 32-bit (64-bit?)
Windows.  Dave, or others, can correct me if I have erred in my
estimate.

Steve

Gunther

Hi shankle,

for the operation you can use the XMM registers, too.

For the program provided by FORTRANS you could use the VMWare Player as another alternative for the Virtual Machine.

Gunther
You have to know the facts before you can distort them.

dedndave

Jack,

i used fixed-point math to display the Gamma value in the status bar

http://masm32.com/board/index.php?topic=4052.msg42784#msg42784

the track bar gives you integers (i used 0 to 400, in this case)
i convert those values to a range of 033 to 300
then, i display the value in the status bar by inserting a decimal point in the string (0.33 to 3.00)

later, i use the converted integer to perform floating point math
i load it into the FPU and divide by 100 for those calculations
but, it's easier to display using fixed-point integer math

shankle

        3-5-2015
      
I loaded this code into my 64-bit GoAsm Program.
I got nothing on the screen. Thought that was what msvcrt:printf did.      
The program compiled without errors.
I am not familiar with msvcrt:printf.

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
    invoke msvcrt:printf, "%g / %g = %g", [n1], [n2], [n3]
   
Tnanks Yuri for the sample code.
Thanks Dave for the pointer to "fpu tutorial by Raymond Filiatreault"   


rrr314159

shankle, here's how I would do that ...

[edit] woops, didn't realize I was in the GoAsm forum at first, shouldn't have said anything; removed irrelevant material ...  ::)

...

GoAsm has some logical ideas, I should check it out further someday
I am NaN ;)

Yuri

shankle
Yes, it should show the result on the screen. If you just double-click the resulting exe, then probably the console window quickly flashes and disappers and you can't see what is in it. If so, then you can tell it to wait till you press any key, using the "system" function.

DATA SECTION

n1  DQ 1.00416
n2  DQ 15.0
n3  DQ 0

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.
#if x64     ; Show the result.
    invoke msvcrt:printf, "%g / %g = %g", [n1], [n2], [n3]
    invoke msvcrt:system, "echo. & pause"
#else
    invoke msvcrt:printf, "%g / %g = %g", [n1], [n1+4], [n2], [n2+4], [n3], [n3+4]
    add esp,1Ch
    invoke msvcrt:system, "echo. & pause"
    add esp,4
#endif
    ret


rrr314159
GoLink looks for imported functions directly in DLLs, so the "msvcrt" prefix is the name of the DLL. The ".dll" extension can be omitted. DLLs can also be bound with the #dynamiclinkfile directive in source code or specified on GoLink's command line, in that case the prefix is not needed.

rrr314159

Thanks Yuri, that's a very good feature. I got here by clicking on "show unread posts since last visit", didn't realize I was in the GoAsm forum at first, or I would have researched it b4 saying anything.

Thanks for the info!
I am NaN ;)

MichaelW

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. You need only a single instruction to get the return value into an appropriate variable, FSTP for 32-bit code where FP values are returned on the FPU stack, or MOVLPD for 64-bit code where FP values are returned in XMM0 (at least for Pelles C and I think also for the Microsoft compilers and CRT). The attachment contains the source for the DLL, the 64-bit DLL and import library, the C source and executable for my C test app, and a JWASM 64-bit test app linked with POLINK (sorry, I don't currently have GoAsm installed).

Also, I seem to recall that GoAsm does not use import libraries, so I'm not sure how you should link with the DLL.
Well Microsoft, here's another nice mess you've gotten us into.