News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

how to print extended numbers?

Started by thomas_remkus, August 27, 2009, 03:12:43 AM

Previous topic - Next topic

bruce1948

Mines only unsigned integer I have addition, subtraction, multiplication and division working and i can print them. This is only at a low level though needs a layer above before it really becomes usable, this is because i've taken an easy option and the routines expect all numbers to be the same length, keeps the routines a little bit shorter and maybe faster.



Bruce

thomas_remkus

LOL. You say that is should be easy to convert but I'm having a heck of a time. From Dave's comments it sounds like this is well optomized so I'm trying to convert and learn at the same time ... that might be my problem but I'm not totally sure what it's doing.

dedndave

#17
ok - i have converted the routine to work with win32
i managed to get a couple speed-ups along the way

there are still a few things i want to change:
1) make it an "invoke" routine, rather than calling and returning parameters in register
2) preserve ebx, ebp, esi, edi for use with win32
3) this version overwrites the input value - i can make the first pass put it on the stack, preserving the original

if you give me a little time, i will post the completed proc and a file
in the mean time, you can test it for me and see if i injected any bugs - lol

see post below - attachment:
http://www.masm32.com/board/index.php?action=dlattach;topic=12186.0;id=6633

thomas_remkus

This looks so different from mine. I'm just guessing with my conversion so I'm going to focus on your version. I have so much to learn.

dedndave

#19
let's hope i got it right - lol
i noticed something - in the previous post, the end of string pointer points to end of string +1
i will fix the previous post in case someone tries to run that code
for this one, the original value is retained, as well as ebx, ebp, esi, edi:

        INVOKE  Arbitrary2Str,
                lpFirstDword,
                dwNumberOfDwords,
                lpResultStringEnd

     lpFirstDword = offset of input value
dwNumberOfDwords = number of dwords in input value
lpResultStringEnd = offset of end of result string + 1 (null terminator)

Returns: eax = pointer to first byte of ASCII decimal string
         ecx = number of decimal digits

output for a 1024 bit value (all 1's)
17976931348623159077293051907890247336179769789423065727343008115773267580550096
31327084773224075360211201138798713933576587897688144166224928474306394741243777
67893424865485276302219601246094119453082952085005768838150682342462881473913110
540827237163350510684586298239947245938479716304835356329624224137215
length = 309

see the attached file
EDIT - revision 3
EDIT - revision 4
updated attachment...
http://www.masm32.com/board/index.php?action=dlattach;topic=12186.0;id=6633

dedndave

i made one last change (and cleaned up the comments)
instead of pointing to the last dword, the input parameter points to the first dword of the input value
a bit more convenient to use

FORTRANS

Hi,

   Looking at the code (Dave's and Richard's), I thought
there was something fishy going on.  Well, not what I was
looking at.  But, I have a suggestion to improve the routine(s).

Change

mov cx,8 ;maximum needed to check
repe scasb ;advances di PAST first non-zero digit


To

pop cx ;restore original pointer (was di)
push cx
repe scasb ;advances di PAST first non-zero digit


For smaller numbers with a LOT of leading zeroes.  Tested
with the original routine, not Dave's improved version.

   The original post.
http://groups.google.com/group/comp.lang.asm.x86/browse_thread/thread/2296450bda0c5398?hl=en#

Regards,

Steve N.

dedndave

hiya Steve
you only need to examine 8 leading 0's
the way the loop is written, it won't create any more than that

i am sure there are many ways to improve this routine
Lingo, Drizz, and Jochen could have a ball with it - lol
i am no expert at optimizing code - i just wanted it to work
i have tried several values and it seems to be ok

i made a modified version of the routine that gives me the number of loop passes and leading zero's

89884656743115795386465259539451236680898848947115328636715040578866337902750481
56635423866120376801056005693993569667882939488440720831124642371531973706218888
39467124327426381511098006230470597265414760425028844190753411712314407369565552
70413618581675255342293149119973622969239858152417678164812112068607
       Length: 308
  Loop Passes: 39
Leading Zeros: 4
Press any key to continue ...

4294967295
       Length: 10
  Loop Passes: 2
Leading Zeros: 6
Press any key to continue ...

updated attachment...
http://www.masm32.com/board/index.php?action=dlattach;topic=12186.0;id=6633

dedndave

i see that i need to make a 4th revision - lol
if you invoke it with size=0, it hangs
let me fix that.....

dedndave

ok - revision 4

0
       Length: 1
  Loop Passes: 0
Leading Zeros: 0
Press any key to continue ...

this attachment has revision 4 and a test program
note: the test version of the routine has additional code in it that is not required for normal use

dedndave

i plan to make one FINAL version of this thing - then go play with something else - lol
i need to check the input length to make sure it isn't too large
as such, i will want to return the status in EAX, as is standard practice in win32
that means the output string pointer will get moved to EDX
revision 5 coming up....
(if my electricity stays on - lol)

i need some input from you guys, here
if the input size is 0, i can return a 0 string easily enough, which seems to be mathematically correct
should i return an error condition in that case ?

thomas_remkus

it's possible that in real execution you will have the opportunities to create a 0 and will need to have the 0 returned. creating room for a really large number does not gaurantee that the situation will return a really large number. with that, i guess if it's determined that the big number is really just loaded  with a DWORD then a different algor would be run. if the bignum is 0 then it would be a non-error and the buffer returns a <"0", 0>. i'm working from an iPhone so it's hard to test right now. i do think you are awesome for working so diligently on this. wow!

dedndave

i dunno 'bout "diligent" - lol
i just want a proc that is usable
on the LAST (lol) revision that i am working on, i am adding tests for errors
i am also changing it to point to the beginning of the output buffer (you have to specify the length)
while i am at it - lol - i decided to add support for selecting signed or unsigned input values
that way, i don't have to have a revision 6 - lol

FORTRANS

Quote from: dedndave on August 29, 2009, 03:55:11 PM
i need some input from you guys, here
if the input size is 0, i can return a 0 string easily enough, which seems to be mathematically correct
should i return an error condition in that case ?

Hi Dave,

   Actually a case can be made for null not being equal to
zero.  And the empty set is not the same as the set of
zero.  For erroneous input I vote for flagging an error and
doing as little else as possible.  If the input is bad, what
says the output buffer is okay?  However, it's your call.
Either way, document it so the result is defined.

Regards,

Steve N.

dedndave

Thanks for your input, Steve
i was trying to accomodate an off-the-wall case where they may be using variable-length values
something like "it takes N number of bits to express M set of values"
after giving it more thought, i think you are right
for unsigned integers, if Q is the number of possible values and N is the number of bits
Q = 2N

No of Bits     Formula     Number of Possible Values
    1              21                   2
    2              22                   4
    3              23                   8
    4              24                  16

but i think that is only a valid equation for N > 0 - if we DID plug a 0 in for N, Q = 1
of course, in most cases, they will have a constant there (the same constant throughout the entire program)
all in all, i think you are right - a 0 length is more likely to be caused by a coding error than by intention

i feel i should return some kind of a valid string pointer in all cases
(if they try to print a string at address 0, it crashes with access violation, as an example)