News:

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

Main Menu

qword to ascii conversion

Started by allynm, June 06, 2012, 02:36:32 AM

Previous topic - Next topic

jj2007

Quote from: KeepingRealBusy on June 10, 2012, 09:12:49 AM
What about speed (not that it really matters)?

Dave.

Speed is fine, you are on par with TheSvin's code.
uqword is faster but I can't convince it to give a correct result1) ::)

uqword=4362504522858521301

Intel(R) Celeron(R) M CPU        420  @ 1.60GHz (SSE3)
1234567890123456
4444444444444444444

1,234,567,890,123,456
1234567890123456
4444444444444444444

652     cycles for Str$
92      cycles for uqword
295     cycles for uqw2a (The Svin)
322     cycles for uqw2a (mCoder)
1013    cycles for i64toa (Towers)
341     cycles for UBTD (Dave)

633     cycles for Str$
92      cycles for uqword
297     cycles for uqw2a (The Svin)
303     cycles for uqw2a (mCoder)
1008    cycles for i64toa (Towers)
346     cycles for UBTD (Dave)


1) same for Lingo's code which yields the same wrong results and crashes in addition

hutch--



uqword=4362504522858521301
Intel(R) Core(TM)2 Quad CPU    Q9650  @ 3.00GHz (SSE4)
1234567890123456
4444444444444444444

1,234,567,890,123,456
1234567890123456
4444444444444444444

568     cycles for Str$
69      cycles for uqword
277     cycles for uqw2a (The Svin)
315     cycles for uqw2a (mCoder)
665     cycles for i64toa (Towers)
290     cycles for UBTD (Dave)

554     cycles for Str$
69      cycles for uqword
267     cycles for uqw2a (The Svin)
291     cycles for uqw2a (mCoder)
664     cycles for i64toa (Towers)
269     cycles for UBTD (Dave)


--- ok ---

dedndave

prescott w/htt
Intel(R) Pentium(R) 4 CPU 3.00GHz (SSE3)

1527    cycles for Str$
182     cycles for uqword
726     cycles for uqw2a (The Svin)
911     cycles for uqw2a (mCoder)
1973    cycles for i64toa (Towers)
611     cycles for UBTD (Dave)
523     cycles for Ling Long Kai Fang (DednDave)

1548    cycles for Str$
179     cycles for uqword
675     cycles for uqw2a (The Svin)
844     cycles for uqw2a (mCoder)
2007    cycles for i64toa (Towers)
604     cycles for UBTD (Dave)
522     cycles for Ling Long Kai Fang (DednDave)


i wanted to see how Ling Long Kai Fang compared   :biggrin:
not as well as i had hoped
but then, it will handle all practical sizes of integers
so, kind of comparing apples with oranges

jj2007


KeepingRealBusy

JJ,

I replaced the original .zip, t least I thought I did, let me check.

Dave.

KeepingRealBusy

JJ,

I downloaded the .zip from the original post and checked its contents - the posted .zip is correct.

Dave.

dedndave

too many Dave's   :biggrin:

i think he was talking to me

actually, Jochen, i did not attach specifically because the LLKF routine falls in a catagory outside those being tested
if we were testing bignum routines, it would be different

i just wanted to see how it faired along side the others
i already knew it wasn't super-fast for smaller integers
in fact, i don't think the Ling Long Kai Fang method offers an advantage unless you are doing integers larger than, say, 96 bits or so

KeepingRealBusy

Dave,

I will work on a fix to make my posted version ABI compliant.

Dave.

KeepingRealBusy

Allynm,

I have included a zip my QWORD conversion code (signed and unsigned) and the
test code and the timing code (included this text also). The test code is for
reference only, you need the output routines which I have not included (no, I
don't use the masm32.lib, I roll my own). The timing and conversion PROCs should
be free standing.

The following timing is extracted from a console output for one pass of 8
conversions with output, followed by 1,000,000 (a million) passes of the 8
conversions only - all in just over 2 seconds. That is fast enough for any
output I need to display.


18,446,744,073,709,551,615
0
4,294,967,295
4,294,967,296
9,223,372,036,854,775,807
-9,223,372,036,854,775,808
0
-1

The current time is:  8:59:16.81
The current time is:  8:59:14.68
                      ----------
                      0:00:02.13


This version of my QWORD conversion code is INTEL ABI compliant with the
following timing:


The current time is: 15:58:58.73

18,446,744,073,709,551,615
0
4,294,967,295
4,294,967,296
9,223,372,036,854,775,807
-9,223,372,036,854,775,808
0
-1

The current time is: 15:59:00.75
The current time is: 15:58:58.73
                     -----------
                     00:00:02.02


Dave.

dedndave



jj2007

I finally succeeded in making Lingo's b2a3264 code produce output. It needs a special kind of QWORD, and some extra pushes and pops for esi & edi to avoid GPFs, but on the bright side it is pretty fast, hehe :biggrin:

Intel(R) Celeron(R) M CPU        420  @ 1.60GHz (SSE3)
687     cycles for Str$
101     cycles for uqword
298     cycles for uqw2a (The Svin)
316     cycles for uqw2a (mCoder)
1056    cycles for i64toa (Towers)
412     cycles for JJ
349     cycles for UBTD (Dave)
87      cycles for b2a3264

654     cycles for Str$
97      cycles for uqword
307     cycles for uqw2a (The Svin)
313     cycles for uqw2a (mCoder)
1055    cycles for i64toa (Towers)
408     cycles for JJ
347     cycles for UBTD (Dave)
87      cycles for b2a3264

jj2007

Quote from: Antariy on June 10, 2012, 11:07:35 AM
It is Windows C standard: LARGE_INTEGER/LONGLONG

There are some pitfalls in C with this "standard":

// works:
  long long q=1234567890123456789;
  printf("long long = %lld\n", q);

// chokes:
//     LARGE_INTEGER LI=1234567890123456789;
// works:
    LARGE_INTEGER LI;
    LI.QuadPart=1234567890123456789;
// works:
  __asm fild q;
  __asm fistp qword ptr LI;
  printf("large_int = %lld\n", LI);        // warning #2234; output large_int = 1234567890123456789
  printf("large_int = %lld\n", LI.QuadPart);        // same output, no warning


That was Pelles C, but I have actually an assembly question: How can you initialise a LARGE_INTEGER?

.data
MyLI0   LARGE_INTEGER <123, 456>   ; error A2179
MyLI1   LARGE_INTEGER <123456>   ; error A2179
MyLI2   LARGE_INTEGER.QuadPart <123456>   ; error A2008
MyLI3   LARGE_INTEGER.QuadPart 123456   ; error A2179

japheth

Quote from: jj2007 on October 18, 2013, 06:40:20 PM
... How can you initialise a LARGE_INTEGER?

.data
MyLI0   LARGE_INTEGER <123, 456>   ; error A2179
MyLI1   LARGE_INTEGER <123456>   ; error A2179
MyLI2   LARGE_INTEGER.QuadPart <123456>   ; error A2008
MyLI3   LARGE_INTEGER.QuadPart 123456   ; error A2179


Since it is an union, you can only initialize the first member. And since the first member is a struct, you'll need 2 levels of angle brackets:

MyLI0 LARGE_INTEGER <<123, 456>>


That's not very "user-friendly", of course. Even more, there's a bug in Masm's v8+ LOW32 or HIGH32 operator, because the following work-around is  rejected:


LI1 equ 123456789abcdeh
MyLI0 LARGE_INTEGER << LOW32 LI1, HIGH32 LI1 >>


And finally, this "fix" also won't work

LI1 equ 123456789abcdeh
X1  LARGE_INTEGER << LI1 and 0ffffffffh, LI1 shr 32 >>

jj2007

Quote from: japheth on October 18, 2013, 07:46:42 PMSince it is an union, you can only initialize the first member. And since the first member is a struct, you'll need 2 levels of angle brackets

Thanks, that works; so the workaround could be another structure. However, even if the first member is just a QWORD, Masm (6.15, 9, 10) and JWasm want the 2 levels of brackets.

include \masm32\MasmBasic\MasmBasic.inc        ; at least Version 18.10.2013
LARGE_INT STRUCT
UNION
  liQw QWORD ?
  liLi        LARGE_INTEGER <>
ENDS
LARGE_INT ENDS

.data
MyLI1        LARGE_INTEGER <<12345, 1000000000>>        ; low32, hi32
MyLI2        LARGE_INT <<1234567890123456789>>          ; one fat QWORD
MyLI3        LONGLONG 1234567890123456789                  ; one fat QWORD

  Init
  Print Str$("LI1=%i\n", MyLI1)        ; LI1=4294967296000012345, OK
  fild MyLI2
  fistp MyLI1
  Print Str$("LI1=%i\n", MyLI1)        ; LI1=1234567890123456789, OK
  Print Str$("LI2=%i\n", MyLI2)        ; LI2=1234567890123456789, OK
  Inkey Str$("LI3=%i\n", MyLI3)        ; LI3=1234567890123456789, OK
  Exit
end start