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
;=====================
use crt__atodbl
INVOKE crt__atodbl,offset real8value,offset inpstring
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
INVOKE crt_atof,offset test2_input1
deb 1, "There it is:", ST(0)
;)
:t
took me a minute to figure that out - it's in the top register of the FPU :P
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
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 (http://masm32.com/board/index.php?topic=94.0)
.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)
EndOfCodeOutput:
There they are:
ST(0) 200.5500000000000000
ST(1) 200.5500000000000114
test4 200.5500
test4 200.5500030517578125
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
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
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 (http://www.ray.masmcode.com/tutorial/index.html)
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
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 (http://masm32.com/board/index.php?topic=94.0)
.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
EndOfCodeOutput: 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?
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
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.
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
Why use _atodbl?
Per this page (https://msdn.microsoft.com/en-us/library/5948ysye.aspx) the special feature is that the function does not generate floating-point code.
And the double is packed in a _CRT_DOUBLE structure:
typedef struct {
double x;
} _CRT_DOUBLE;
Sorry about the C code, but it's the only way I have to test this ATM:
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
int main(void)
{
_CRT_DOUBLE value;
printf("%d\n", _atodbl( &value, "3.14159265358979323846264"));
printf("%.20f\n", value.x);
_getch();
}
0
3.14159265358979310000
Quote from: MichaelW on January 12, 2016, 07:53:40 PMSorry about the C code
POLINK: error: Unresolved external symbol '__atodbl' ::)
Quote from: jj2007 on January 12, 2016, 09:13:12 PM
POLINK: error: Unresolved external symbol '__atodbl' ::)
I used a recent 64-bit MinGW, selected originally because it supports 64-bit code in inline assembly. The function I could not make work was _atoldbl, no error but the _LDOUBLE value returned doesn't make sense.
Difference
C90FDAA22168C235
C90FDAA22168C233
.386
.model flat, stdcall
option casemap:none
printf proto cdecl :vararg
exit proto cdecl :dword
_atoldbl proto cdecl :dword, :dword
includelib msvcr100.lib
.data
sPI db "3.14159265358979323846264", 0
nPI dt 3.14159265358979323846264;338327
fmt db "%llX", 13, 10, 0
re10 real10 0
.code
start proc
invoke _atoldbl, addr re10, addr sPI
invoke printf, addr fmt, re10
invoke printf, addr fmt, nPI
invoke exit, 0
start endp
end start