News:

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

Main Menu

Help on simple mathematics

Started by clamicun, November 05, 2015, 07:23:30 AM

Previous topic - Next topic

clamicun

include \masm32\MasmBasic\MasmBasic.inc   
include ..\cmctools\cmc_macros.inc

include \masm32\include\Shlwapi.inc
includelib \masm32\lib\Shlwapi.lib

include \masm32\include\msvcrt.inc
   
value   dd ?
result  dd ?

;result2 dq ?  ;??? for atof

;The inputs are from a dialogbox in my programm, which takes care to exclusively accept - . and 0 to 9.
;After processing they will be uploaded to mysql.

test1_input1  db "200",0
test1_input2  db "470",0
test1_input3  db "100",0

test2_input1  db "200.55",0

result_buffer db 30 dup(?),0
show_result   db "%s + %s  - %s = %s",0
showeax       db "%li",0

output        db 30 dup(?),0

;=====================
.code
start:

INVOKE crt_atoi,offset test1_input1
push eax

INVOKE crt_atoi,offset test1_input2
mov value,eax

pop eax
add eax,value
mov result,eax

INVOKE crt_atoi,offset test1_input3
sub result,eax

INVOKE crt__itoa,result,offset result_buffer,10

INVOKE wsprintf,offset output,offset show_result,offset test1_input1,offset test1_input2,offset test1_input3,offset result_buffer
INVOKE MessageBox,0,offset output,0,0

;ok that is easy, but I nedd to do this with inputs like (for example) 200.55 

;----------------------------
;After hours in the net I guess it might be atof. Hundreds of entries and not one asm example. 
;atof converts a string to double.... returns a double value.
;But where is the result ?
;The return of itoa is in a given buffer, so the atof result should be in eax. 
;I obviously do not understand this function.
;The value in eax is different every time. That does not make sense or the syntax is wrong.
;Please - can someone explain it to me or give me a link, which explains it understandably.

xor eax,eax
INVOKE crt_atof,offset test2_input1

INVOKE wsprintf,offset output,offset showeax,eax
INVOKE MessageBox,0,offset output,0,0

INVOKE ExitProcess,0
end start


;=====================

dedndave

use crt__atodbl

    INVOKE  crt__atodbl,offset real8value,offset inpstring

dedndave

if you have a fixed or limited number of decimal digits, you could also use fixed-point math

i.e., 200.55 might be stored as 20055 or 200550

jj2007

  INVOKE crt_atof,offset test2_input1
  deb 1, "There it is:", ST(0)
;)

dedndave

 :t

took me a minute to figure that out - it's in the top register of the FPU   :P

dedndave

by the way....

it depends on the range and precision required
you may be able to use single-precision values (REAL4)

single precision: ~ -3.438 to +3.438, precision = 24 bits
double precision: ~ -1.79308 to +1.79308, precision = 53 bits

jj2007

Quote from: dedndave on November 05, 2015, 08:27:20 AMit depends on the range and precision required

crt is by default real8=double, assembler allows real10:

include \masm32\MasmBasic\MasmBasic.inc      ; download
.data
test2_input1  db "200.55", 0
test4      REAL4 ?
  Init
  INVOKE crt_atof, offset test2_input1      ; real8 precision
  MovVal ST(0), offset test2_input1      ; real10 precision
  fst test4
  deb 4, "There they are:", ST(0), ST(1), test4
  Inkey Str$("test4\t\t%Jf", test4)
EndOfCode


Output:
There they are:
ST(0)           200.5500000000000000
ST(1)           200.5500000000000114
test4           200.5500
test4           200.5500030517578125

dedndave

right - i normally use REAL10 - just because that's the FPU "native language", so to speak

well - for intermediate calculations, i do
for user I/O, 7 digits is enough for most real-world stuff
except when talking about times or frequencies - lol

example.....
a mile is 5280 feet
if we use 7 digits, that might be 5280.000 feet

0.001 feet is 0.012 inches
that's like measuring a mile with dial calipers

clamicun

dedndave, jj ,good evening and many thanks.

Lots of info to think about.
FPU is quite new to me.

The examples of jj work well, like always, but I do not know what to do with the results.
Like I wrote above - I will add one input to the other or others, convert that result back into a string and upload it to mysql.

I guess the result in the messagebox  or in the console  is ST(0).
How do I process it ?

--------------------
INVOKE  crt__atodbl,offset real8value,offset inpstring

Sounds good. ascii to double. That is what I want.
Could you be a bit more explicit on the two parameters, please.
atof has only one.

Ok. - ate ja

INVOKE  crt__atodbl,offset real8value,offset inpstring

dedndave

the first argument points to a REAL8 (the address of the location, offset)

    .DATA?

r8SomeName REAL8 ?


the second argument points to the string buffer
it should contain an ascii string in the general form
-1.123E-3
1.0
will also work - and, the string should be terminated with a NUL

if you want to add a series of real's, you will want to use the FPU
adding a few numbers together is not that hard
you should look at Ray's tutorial
FLD, FST, FSTP, FADD, FADDP, FFREE are the instructions of interest

http://www.ray.masmcode.com/tutorial/index.html

dedndave

result:
8.888

Press any key to continue ...


code:
;###############################################################################################

        .XCREF
        .NoList
        INCLUDE    \Masm32\Include\Masm32rt.inc
        .686p
        .MMX
        .XMM
        .List

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

        .DATA
        ALIGN   8

r8Val1   REAL8 1.225
r8Val2   REAL8 2.122
r8Val3   REAL8 5.541

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

        .DATA?
        ALIGN   8

r8Result REAL8 ?
szBuffer db    20 dup(?)

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

        .CODE

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

main    PROC

    fld     r8Val1          ;float load          - r8Val1 is in ST(0)
    fadd    r8Val2          ;float add           - r8Val2 is added to ST(0)
    fadd    r8Val3          ;float add           - r8Val3 is added to ST(0)
    fstp    r8Result        ;float store and pop - ST(0) is stored in r8Result, and ST(0) is emptied

    INVOKE  FloatToStr,r8Result,offset szBuffer
    print   offset szBuffer,13,10

    print   chr$(13,10)
    inkey
    exit

main    ENDP

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

        END     main

jj2007

Quote from: clamicun on November 05, 2015, 10:46:39 AMLike I wrote above - I will add one input to the other or others, convert that result back into a string and upload it to mysql.

Why don't you simply use Str$()?

include \masm32\MasmBasic\MasmBasic.inc      ; download
.data
Some8      REAL8 11111.11111
Some4      REAL4 22222.22222
SomeDw      dd 33333

  Init
  Let esi=Str$(Some4/Some8*SomeDw/1000)      ; ca. 22/11*33.333 = 66
;   SendData "MyClient", esi      ; whatever works
;   FileWrite "Result.txt", esi      ; for sending to MySQL
  Inkey esi
EndOfCode


Output: 66.66600

Attention, there is no operator precedence: 20+50*3 = 210 (wrong), so use 50*3+20 instead.

BTW it would be nice to see a simple MySql example application here. Can you cook up something?

clamicun

jj, dedndave thank you guys very much.

ok - I know how it will work. (various possibilities).

Because the input is always like  '12345.67'  or  '-12345.67'

dedndave's idea to  simply delete the  '.' , treat it as signed integer
and finally write   '.'   two bytes before the end of the string. 

is probably the easiest method, but I'll have to check it out.

I'll send an example of how to work with mysql.
Must write a simple demoversion.
Looks like php.

Good night, clamicun

raymond

If you intend to go with fixed point, you may get some more info from the "Fixed point math" section which you can access from the main page at:
http://www.ray.masmcode.com/

You can also access the FPU tutorial and the Fpulib from that site. The Fpulib comes with the source code of each function where you can learn how various operations are performed.
Whenever you assume something, you risk being wrong half the time.
https://masm32.com/masmcode/rayfil/index.html

jj2007

Quote from: clamicun on November 06, 2015, 06:57:19 AM
Because the input is always like  '12345.67'  or  '-12345.67'

Str$() is perhaps the easiest option, but if you want a solution with plain Masm32, here it is:

include \masm32\include\masm32rt.inc

.data
a$ db "123.456", 0
b$ db "321.432", 0
Result REAL8 ?

.code
start:
  invoke crt_atof, offset a$ ; load 1st result to ST(0)
  invoke crt_atof, offset b$ ; load 2nd result to ST(0), move 1st to ST(1)
  fadd ; add ST(0)+ST(1)
  fstp Result ; pop result from FPU to REAL8 variable
  printf("The result is %f", Result)
  inkey " - ok?"
  exit

end start