guys I need another help on conversion of character to integer or decimal numbers. actually i am trying to read the character from file and trying to do some arithmetic operation with those numbers , can't do without convert to integer so please help me out. here i am pasting my code.
mov esi,offset buffer ;contents the data read from file
L1:
mov al,[esi]
cmp al,'0'
jb L1
cmp al,'9'
ja L1
sub al,'0'
call WriteInt ;make sure output is integer
inc esi
cmp ecx,0 ; compare null terminator
jne L1
jz quit
exit
Try something simple:
include \masm32\include\masm32rt.inc
.code
Hello db "The result:", 0
My$ db "1234567", 0
start:
mov esi, offset My$
xor edx, edx
.Repeat
lodsb
.Break .if !eax
imul edx, edx, 10
sub eax, "0"
add edx, eax
.Until 0
MsgBox 0, str$(edx), addr Hello, MB_OK
exit
end start
Going to need an XOR EAX,EAX outside the loop to clear the high order bits in EAX for that LODSB to work reliably inside the loop.
Oops, that's right. Windows was so nice to zero eax for me, so no problem showed up when testing, but an xor eas, eax right before the .Repeat is certainly a good idea.
I may also be a good idea to count the number of decimal ascii digits while converting the string to binary. Anything exceeding 9 digits could lead to an erroneous result.
And the code posted by xerox would have allowed the correct conversion of inputs separated by delimiters (such as comas in for example 12,345,678). However, his code would have failed if the input contained fractional digits (such as $12.34).
Quote from: raymond
Anything exceeding 9 digits could lead to an erroneous result.
About 43% of 10 digit integer numbers should be just fine, so a subset of anything, and a set that is pretty well constrained and not wholly random.
Edit 32-bit unsigned range 0 - 4,294,967,295 (43%)
include \masm32\MasmBasic\MasmBasic.inc
Init
.data
My$ db "1234567890.1234567890", 0
MyReal10 REAL10 ?
.code
MovVal MyReal10, offset My$
Inkey Str$("The fastest way to convert a string: %If", MyReal10)
Exit
end start
The fastest way to convert a string: 1234567890.12345679
Hi xerox,
Here is a quick example :
include asciiTOint.inc
.data
number1 db '1048576',0
format1 db 'atodw = %u',13,10,13,10
db 'atoi = %u',0
.data?
temp dd ?
.code
start:
invoke atodw,ADDR number1
mov temp,eax
invoke crt_atoi,ADDR number1
invoke crt_printf,ADDR format1,temp,eax
invoke ExitProcess,0
END start
atodw = function from masm32.lib
atoi = function from msvcrt.lib
QuoteAnything exceeding 9 digits could lead to an erroneous result.
QuoteAbout 47% of 10 digit integer numbers should be just fine
That's why I used the word "could" and not the word "would".
it's easy enough to test the carry flag, guys :P
Quote from: dedndave on March 27, 2011, 04:17:52 AM
it's easy enough to test the carry flag, guys :P
Indeed, my point was that it's very predictable and several useful 10 digit numbers are quite representable, and Raymond's that people should sanity check the input, handle different formats and catch out-of-bounds conditions. All important considerations once the basis mechanics are grasped.
Using a suitable multiply would permit the capture of a 64-bit result.
Notwithstand, the people generally asking the question about numeric conversions need to understand the underlying math first. The unfamiliarity with simply multiple and divide strategies for base conversions at a college level is kind of scary.
on a side note....
it is much more interesting to write routines that convert binary values to strings
than it is to write routines that convert strings to binary :P
not sure why that is
for a simple routine, you could stop at the first non-numeric ascii character
that would allow you to handle decimal points, although it will just truncate - not round
but - it would catch carriage returns, line feeds, tabs, nulls, spaces
All external input must ALWAYS be checked for validity. We should make it a point to stress that to beginners.
Some of the pros were probably never educated on that aspect. We can all remember all the problems caused by buffer overflows. :eek ::) :(