The MASM Forum

General => The Campus => Topic started by: Mikl__ on July 19, 2017, 10:51:33 PM

Title: How to output 128 bits to the screen?
Post by: Mikl__ on July 19, 2017, 10:51:33 PM
Hi, All!
If I need to output 64-bits float to the screen, I do so; CONSOLE #
include win64a.inc
include msvcrt.inc
includelib msvcrt.lib
.data
pi  dq 3.14159265358979323846264338327
textformat db "hello, %.16llf!",0
.code
WinMain proc
sub rsp,28h
lea rcx,textformat
mov rdx,pi
call printf
xor rax,rax
add rsp,28h
ret
WinMain endp
end
What should I do to output 128-bits float to the screen? Thanks...
Title: Re: How to output 128 bits to the screen?
Post by: jj2007 on July 19, 2017, 10:56:47 PM
Dave may have something for you. (http://masm32.com/board/index.php?topic=222.0)
Title: Re: How to output 128 bits to the screen?
Post by: Mikl__ on July 19, 2017, 11:09:30 PM
Ciao, jj2007! Come stai?
I do not need an exact calculation of the Pi number, but I need an example of using format string for prints and  xmm-registers...
Title: Re: How to output 128 bits to the screen?
Post by: jj2007 on July 19, 2017, 11:27:24 PM
Display with "normal" code ends with Real10 precision:
include \masm32\MasmBasic\MasmBasic.inc
  Init
  fldpi
  Inkey Str$("PI=%Jf", ST(0)v) ; PI=3.141592653589793238
EndOfCode


Everything beyond needs special libraries, like Dave's Ling Long Kai Fang Bignum library. Rumours say Drizz also has one (http://masm32.com/board/index.php?topic=1280.0).

If you want to see C/C++/G++ coders fighting with 128-bit windmills, check
how to print __uint128_t number using gcc? (https://stackoverflow.com/questions/11656241/how-to-print-uint128-t-number-using-gcc)
or
How to print __int128 in g++? (https://stackoverflow.com/questions/25114597/how-to-print-int128-in-g)

Of course, you can always use hex representation:My128Bits xmmword 1111111111abcdef2222222222abcdefh
  movups xmm0, My128Bits
  deb 4, "Test", x:xmm0


Output: Test    x:xmm0          11111111 11ABCDEF 22222222 22ABCDEF
Title: Re: How to output 128 bits to the screen?
Post by: nidud on July 20, 2017, 12:47:15 AM

    movq pi,xmm0
Title: Re: How to output 128 bits to the screen?
Post by: aw27 on July 20, 2017, 02:45:12 AM
Another alternative:


; x64
;uasm64 -win64 -Zp8 -c p128.asm

.xmm
option casemap:none
option frame:auto

includelib \masm32\lib64\msvcrt.lib
printf proto :ptr, :vararg

_DOUBLESTOXMM MACRO par1, par2
Local xmmValue
  .const
  align 16
  xmmValue REAL8 par1, par2
  .code
  exitm <xmmValue>
ENDM

.data
format db "Results: %.16llf, %.16llf",13,10,0

.code

main proc
       ;sub rsp, 8 by uasm
sub rsp, 20h
movaps xmm0, XMMWORD ptr _DOUBLESTOXMM(3.14159265358979323846264338327, -6.28318530717958647692528676654)

movq r8, xmm0 ; Note: ML64 does not accept movq, it is a know bug. But it accepts movd and converts it to movq. Weird
shufpd xmm0, xmm0, 1
movq rdx, xmm0
mov rcx, offset format
call printf

add rsp, 20h
ret
main endp

end



Results: -6.2831853071795862, 3.1415926535897931
Title: Re: How to output 128 bits to the screen?
Post by: jj2007 on July 20, 2017, 05:12:49 AM
Quote from: Mikl__ on July 19, 2017, 10:51:33 PMWhat should I do to output 128-bits float to the screen?
Title: Re: How to output 128 bits to the screen?
Post by: aw27 on July 20, 2017, 05:29:12 AM
Quote from: jj2007 on July 20, 2017, 05:12:49 AM
Quote from: Mikl__ on July 19, 2017, 10:51:33 PMWhat should I do to output 128-bits float to the screen?

Are you telling that you printed a float?  :badgrin:

Title: Re: How to output 128 bits to the screen?
Post by: jj2007 on July 20, 2017, 08:07:47 AM
Yes, I printed a float: PI=3.141592653589793238

But that is "only" an 80 bit float. OP wants 128 bits, and that is not possible with "normal" code. You need a bignum library.
Title: Re: How to output 128 bits to the screen?
Post by: RuiLoureiro on July 20, 2017, 08:36:00 AM
Quote from: jj2007 on July 20, 2017, 08:07:47 AM
Yes, I printed a float: PI=3.141592653589793238

But that is "only" an 80 bit float. OP wants 128 bits, and that is not possible with "normal" code. You need a bignum library.
Yes it seems Mikl__ wants a 128 bits converter. But if there is one BIGNUM library then it
has the converter. Where to see it Jochen (but i dont want it) ? And what is a bignum library, what it does ?
Does it real128 * real128 = real128 ? What is the format ? (real128 means any real with 128 bits in the same way real80 is the same as REAL10- 10 bytes)
:t
Title: Re: How to output 128 bits to the screen?
Post by: aw27 on July 20, 2017, 03:05:40 PM
Quote from: jj2007 on July 20, 2017, 08:07:47 AM
Yes, I printed a float: PI=3.141592653589793238

But that is "only" an 80 bit float. OP wants 128 bits, and that is not possible with "normal" code. You need a bignum library.

Of course, it is not possible without a bignum library.
And he asked for "an example of using format string for prints and  xmm-register".
So what comes closer to what he wants, in the realm of possibilities, is what I did.
I also did it in Assembly Language, which this forum is all about.
Title: Re: How to output 128 bits to the screen?
Post by: jj2007 on July 20, 2017, 04:39:32 PM
Quote from: aw27 on July 20, 2017, 03:05:40 PM
I also did it in Assembly Language, which this forum is all about.

call printf

:t
Title: Re: How to output 128 bits to the screen?
Post by: aw27 on July 20, 2017, 04:53:54 PM
Quote from: jj2007 on July 20, 2017, 04:39:32 PM
call printf
:t
You do the same, or equivalent, hidden in the middle of obscure code supported by undocumented libs you developed (MasmBasic, JBasic.*).
That way, I can only expect newbies to learn ASM when pigs can fly.  :badgrin:
Title: Re: How to output 128 bits to the screen?
Post by: jj2007 on July 20, 2017, 05:10:13 PM
We are doing almost the same. The difference is that I am not pretending to solve the problem, I just demonstrate that it is NOT possible, and I do it using a library that is written 100% in assembly, developed here in this forum by many members, without even a trace of C code. And I really don't understand why this turns into a pissing contest, José. If you want to be constructive, start a bignum library thread in the Laboratory. That could be interesting indeed.
Title: Re: How to output 128 bits to the screen?
Post by: aw27 on July 20, 2017, 05:26:34 PM
Quote from: jj2007 on July 20, 2017, 05:10:13 PM
If you want to be constructive, start a bignum library thread in the Laboratory. That could be interesting indeed.
In my opinion there are already enough BigNum libraries out there. Probably the best one for Windows, is the MPIR, which is written partially in YASM. I used it to do a freeware I published called Googol+
Title: Re: How to output 128 bits to the screen?
Post by: jj2007 on July 20, 2017, 05:47:05 PM
Quote from: aw27 on July 20, 2017, 05:26:34 PMIn my opinion there are already enough BigNum libraries out there. Probably the best one for Windows, is the MPIR

MPIR: Multiple Precision Integers and Rationals (http://mpir.org/downloads.html)

Looks interesting, but sources only. How big are the lib or dll files, could you post them here?

There is a thread on The best cross platform (portable) arbitrary precision math library (https://stackoverflow.com/questions/2568446/the-best-cross-platform-portable-arbitrary-precision-math-library) at SOF; they recommend GMP.

@Mikl: How would you declare a 128-bit float? Or do you read it from a file?
Title: Re: How to output 128 bits to the screen?
Post by: aw27 on July 20, 2017, 06:00:30 PM
Quote from: jj2007 on July 20, 2017, 05:47:05 PM
Looks interesting, but sources only. How big are the lib or dll files, could you post them here?
The sources are in their website.
When I was interested in these matters, I bothered to produce all libs, static and dynamic, and dlls and posted them here (http://www.atelierweb.com/mpir-and-mpfr/). They are not big.

Quote
There is a thread on The best cross platform (portable) arbitrary precision math library (https://stackoverflow.com/questions/2568446/the-best-cross-platform-portable-arbitrary-precision-math-library) at SOF; they recommend GMP.

MPIR is a fork of GMP, the guy that developed GMP really hates Windows and makes things extremely difficult to use GMP within Windows.
Title: Re: How to output 128 bits to the screen?
Post by: jj2007 on July 20, 2017, 06:14:13 PM
Quote from: aw27 on July 20, 2017, 06:00:30 PMThey are not big.

MpfrMpir\Static\Lib32\mpfr.lib is 6MB, that is indeed small compared to all the stuff that M$ forces us to install.
Title: Re: How to output 128 bits to the screen?
Post by: aw27 on July 20, 2017, 06:18:57 PM
Quote from: jj2007 on July 20, 2017, 06:14:13 PM
Quote from: aw27 on July 20, 2017, 06:00:30 PMThey are not big.

MpfrMpir\Static\Lib32\mpfr.lib is 6MB, that is indeed small compared to all the stuff that M$ forces us to install.
Static libraries don't use the dll. In a static library only the functions you need are taken out. Your .exe will not be over 6MB, can be pretty small indeed.
Dynamic libs, the ones that masm32 uses, contain just stubs to use the dll.
Title: Re: How to output 128 bits to the screen?
Post by: Mikl__ on July 20, 2017, 07:03:36 PM
QuoteMikl: How would you declare a 128-bit float? Or do you read it from a file?
Until I didn't announce it, I'm interested in a bunch/Bundle of printf-function and xxm-registers. I spent many time searching on Google and therefore decided to ask on the forum. If I output the contents of an 80-bit memory cell, then how would it look at 64 bits MASM/FASM/NASM?.data
pi dt 3.14159265358979323846264338327
fmt db "%1.25llf",0 <-- Or not correct format ?
.code
         .....
        lea rcx,fmt
       lea rdx,pi  <-- ? Address don't work         or need two 64-bits registers (RDX+R8)  ?
       call printf
Title: Re: How to output 128 bits to the screen?
Post by: hutch-- on July 20, 2017, 09:17:35 PM
I have a sneaking suspicion that it can be done with the a 128 bit memory operand if you read it 4 bytes at a time. I don't have time to play with it at the moment as I have too much 64 bit code to write but it should not be that big a deal.
Title: Re: How to output 128 bits to the screen?
Post by: jj2007 on July 20, 2017, 09:40:12 PM
It isn't a big deal to print an xmm register, but it is limited to 64 bits. The CRT doesn't allow more.

include \Masm32\MasmBasic\Res\JBasic.inc        ; # console demo, builds in 32- or 64-bit mode with ML, AsmC, JWasm, HJWasm #
.data?
tmpQ    dq ?
tmpR8   REAL8 ?
.data
MyInt   dq 123456789012345
MyFloat         REAL8 123456789012345.6789
Init            ; OPT_64 1      ; put 0 for 32 bit, 1 for 64 bit assembly
  PrintLine Chr$("This code was assembled with ", @AsmUsed$(1), " in ", jbit$, "-bit format", 13, 10)

  movlps xmm0, MyInt            ; load data to xmm0
  usedeb=1      ; enable console debugging
  deb 4, "debug macro", xmm0
  movlps tmpQ, xmm0             ; store data in temporary qword
  jinvoke crt_printf, Chr$("xmm0=%lld", 13, 10), tmpQ
 
  movlps xmm0, MyFloat
  movlps tmpR8, xmm0
  jinvoke crt_printf, Chr$("xmm0=%f", 13, 10), tmpR8

  MsgBox 0, "Wow, it works!!!!", "Hi", MB_OK or MB_SETFOREGROUND
EndOfCode
Title: Re: How to output 128 bits to the screen?
Post by: aw27 on July 20, 2017, 09:45:16 PM
Unlike other vendors, when it is time to print, Microsoft considers "long double"="double".   :eusa_snooty:

Title: Re: How to output 128 bits to the screen?
Post by: jj2007 on July 20, 2017, 10:24:28 PM
Quote from: aw27 on July 20, 2017, 09:45:16 PM
Unlike other vendors, when it is time to print, Microsoft considers "long long double"="double".   :eusa_snooty:

Which vendor supports a long long double? If yes, is that a REAL10? I've heard rumours that FORTRAN supports REAL16 ::)

#include <stdio.h>
#include <windows.h> // needs Gcc or Visual C and the Compile plugin
#include <conio.h>  // RichMasm: Hit Ctrl F5 to pick a commandline (afterwards, F5 is enough)

int main(int argc, char* argv[]) {
  long long q=1234567890123456789;
  printf("A long long:\t%lld\n", q);

  double nd=1234567890.1234567890;
  printf("A double:\t%9.9f\n", nd);
  long double ld=1234567890.1234567890;
  printf("A long double:\t%9.9f (ok with VC, no luck with Gcc)\n\n", ld);
  _getch();
}


Output:
  VS:
  A long long:    1234567890123456789
  A double:       1234567890.123456700
  A long double:  1234567890.123456700 (ok with VC, no luck with Gcc)

  GCC:
  A long long:    1234567890123456789
  A double:       1234567890.123456700
  A long double:  -0.000000000 (ok with VC, no luck with Gcc)
Title: Re: How to output 128 bits to the screen?
Post by: TWell on July 20, 2017, 10:25:25 PM
https://en.wikipedia.org/wiki/Long_double

Microsoft made a bad decision with long double with 32-bit compiler?
In 16-bit C they have it supporting 80-bits???
Title: Re: How to output 128 bits to the screen?
Post by: aw27 on July 20, 2017, 10:33:46 PM
Quote from: jj2007 on July 20, 2017, 10:24:28 PM
Which vendor supports a long long double? If yes, is that a REAL10?
Intel compiler and GCC support long double (REAL10).


Quote
I've heard rumours that FORTRAN supports REAL16 ::)

I don't remember, I don't do FORTRAN since I left school.  :biggrin:

PS: I think GCC may not print them when using VS libraries, but I have not GCC installed at the moment to see.  :badgrin:
Title: Re: How to output 128 bits to the screen?
Post by: jack on July 20, 2017, 11:04:39 PM
as far as I know gcc's long double on Windows is the same as double.
for printing long double have a look at smldbl12.zip found here http://www.moshier.net/#Rubid_pc, it's in the public domain.
Title: Re: How to output 128 bits to the screen?
Post by: aw27 on July 20, 2017, 11:11:52 PM
Quote from: jack on July 20, 2017, 11:04:39 PM
as far as I know gcc's long double on Windows is the same as double.
for printing long double have a look at smldbl12.zip found here http://www.moshier.net/#Rubid_pc, it's in the public domain.
You may need to run it in Cygwin for it to work as advertised. :icon_eek:
Title: Re: How to output 128 bits to the screen?
Post by: FORTRANS on July 20, 2017, 11:14:10 PM
Hi Jochen,

Quote from: jj2007 on July 20, 2017, 10:24:28 PM
I've heard rumours that FORTRAN supports REAL16 ::)

   That depends on the vendor and systems involved.  IIRC Cray
had 64-bit REAL and 128-bit DOUBLE PRECISION types.  And various
Unix minicomputers had the same.  (Long time ago though.)

   Here is some information from a X86 product typed in from a
set of help screens.

Compaq Visual Fortran 6.6 (1998)?

Real Data Types

Real data types can be specified as follows:

   REAL
   REAL([KIND=]n)
   REAL*n
   DOUBLE PRECISION

   n
   Is kind 4, 8, or 16.  Kind 16 is only available on
   OpenVMS, Tru64 UNIX, and Linux systems.


HTH,

Steve
Title: Re: How to output 128 bits to the screen?
Post by: jack on July 20, 2017, 11:19:06 PM
Quote from: aw27 on July 20, 2017, 11:11:52 PM
You may need to run it in Cygwin for it to work as advertised. :icon_eek:
have not checked the precision of gcc's long double on Cygwin, am not fond of the many dll dependencies.
as for the code linked above, it should be trivial to extend it to print 128-bit floats (I think the code is already there).
Title: Re: How to output 128 bits to the screen?
Post by: jj2007 on July 20, 2017, 11:37:00 PM
Quote from: jack on July 20, 2017, 11:19:06 PMit should be trivial to extend it to print 128-bit floats (I think the code is already there).

Great, show us :t
Title: Re: How to output 128 bits to the screen?
Post by: jack on July 20, 2017, 11:54:59 PM
I have minimal C experience otherwise I would take you up on the challenge, but you can convert a 128-bit float in exponential format to string using e113toasc, you just have to #define UNUSED 1
Title: Re: How to output 128 bits to the screen?
Post by: jj2007 on July 21, 2017, 01:19:33 AM
Quote from: jack on July 20, 2017, 11:54:59 PM
I have minimal C experience

Me too ;)

Quoteotherwise I would take you up on the challenge, but you can convert a 128-bit float in exponential format to string using e113toasc, you just have to #define UNUSED 1

There are many competent C/C++ coders here, so soon we'll see a DLL or LIB :t
Title: Re: How to output 128 bits to the screen?
Post by: Mikl__ on July 22, 2017, 10:03:41 AM
Hi, jj2007, aw27, TWell, jack, FORTRAN!
Many thanks for the tips and helpness!(https://wasm.in/styles/smiles_s/good2.gif)
Title: Re: How to output 128 bits to the screen?
Post by: jj2007 on July 23, 2017, 08:42:02 PM
I am working on a MasmBasic implementation. Here is cos(45):
QuadMath        7.071067811865475244008443621048490885e-01
Wolfram Alpha   7.071067811865475244008443621048490392e-01


Not bad, but it will require a GCC installation :(
Title: Re: How to output 128 bits to the screen?
Post by: aw27 on July 23, 2017, 09:45:21 PM
Quote from: jj2007 on July 23, 2017, 08:42:02 PM
I am working on a MasmBasic implementation. Here is cos(45):
QuadMath        7.071067811865475244008443621048490885e-01
Wolfram Alpha   7.071067811865475244008443621048490392e-01


Not bad, but it will require a GCC installation :(

Are you working on a BigNum library or on a way to print a 128 bit float to the screen?  :icon_eek:
Title: Re: How to output 128 bits to the screen?
Post by: jj2007 on July 23, 2017, 10:01:43 PM
The latter. Since GCC is a very popular compiler, and has the QuadMath library "out of the box", I am trying to get an assembler interface to that lib. Pretty useless, I know :badgrin:

Anyway, this works already:

        PrintLine "xmm0=", Tb$, Quad$(xmm0)
        PrintLine "MyReal16=", Tb$, Quad$(MyReal16)


But I must say that GCC QuadMath is not user-friendly. Badly documented, you need to read the header file to get info ::)
Title: Re: How to output 128 bits to the screen?
Post by: aw27 on July 23, 2017, 10:10:19 PM
Quote from: jj2007 on July 23, 2017, 10:01:43 PM
The latter. Since GCC is a very popular compiler, and has the QuadMath library "out of the box", I am trying to get an assembler interface to that lib. Pretty useless, I know :badgrin:

Anyway, this works already:

        PrintLine "xmm0=", Tb$, Quad$(xmm0)
        PrintLine "MyReal16=", Tb$, Quad$(MyReal16)


But I must say that GCC QuadMath is not user-friendly. Badly documented, you need to read the header file to get info ::)

Just note that SSE/AVX does not support 128-bit floats/Real16 and Intel has no current plans to implement. So, printing a xmm/ymm/zmm register looking for the 128-bit float in there, just prints garbage. Of course you can work with a software only solution.
Title: Re: How to output 128 bits to the screen?
Post by: jj2007 on July 23, 2017, 10:44:27 PM
Quote from: aw27 on July 23, 2017, 10:10:19 PMOf course you can work with a software only solution.

Exactly. It's called "QuadMath", and it works already, see above.

I attach a proggie that reads a RAD string (e.g. 45*PI/180=0.785398163397448309615660845819875721049292349843776455243) and spits out the cosine. As mentioned before, it needs C:\TDM-GCC-32\bin\libquadmath-0.dll
Title: Re: How to output 128 bits to the screen?
Post by: Mikl__ on July 23, 2017, 11:01:57 PM
?
Title: Re: How to output 128 bits to the screen?
Post by: jj2007 on July 23, 2017, 11:13:02 PM
Hi Mikl,

You were too fast - the first version had an exception handler, and instead of telling you that the DLL doesn't exist, it just threw an exception. Try the new attachment, and make sure you have GCC installed in the right location.

Interesting that you got non-printable characters, though. Which codepage? What do you get with chcp 65001?
Title: Re: How to output 128 bits to the screen?
Post by: aw27 on July 23, 2017, 11:18:21 PM
I don't have GCC installed now.   :(  :shock:
Title: Re: How to output 128 bits to the screen?
Post by: Mikl__ on July 23, 2017, 11:19:30 PM
codepage=866
Title: Re: How to output 128 bits to the screen?
Post by: jj2007 on July 23, 2017, 11:36:14 PM
Try this one, the "Dll not found" warning was broken :icon_redface:

And yes, it won't work without C:\TDM-GCC-32\bin\libquadmath-0.dll 8)
Title: Re: How to output 128 bits to the screen?
Post by: jj2007 on July 24, 2017, 12:52:38 AM
Stupid question: Where am I wrong?include \masm32\include\masm32rt.inc
.data
My4 REAL4 -1.23456789012345678901234567890e0
My8 REAL8 -1.23456789012345678901234567890e0

.code
start:
  mov esi, offset My4
  mov eax, [esi]
  sar eax, 23
  and eax, 11111111b ; 8 bits expo
  sub eax, 127  ; bias
  print str$(eax), 9, "expo R4", 13, 10

  mov esi, offset My8
  mov eax, [esi]
  sar eax, 52-32
  and eax, 11111111111b ; 11 bits expo
  sub eax, 1023 ; bias
  print str$(eax), 9, "expo R8", 13, 10
  exit
end start


Should be 2x0, right?
0       expo R4
41      expo R8
Title: Re: How to output 128 bits to the screen?
Post by: aw27 on July 24, 2017, 01:13:03 AM
Quote from: jj2007 on July 24, 2017, 12:52:38 AM
Stupid question: Where am I wrong?include \masm32\include\masm32rt.inc
.data
My4 REAL4 -1.23456789012345678901234567890e0
My8 REAL8 -1.23456789012345678901234567890e0

.code
start:
  mov esi, offset My4
  mov eax, [esi]
  sar eax, 23
  and eax, 11111111b ; 8 bits expo
  sub eax, 127  ; bias
  print str$(eax), 9, "expo R4", 13, 10

  mov esi, offset My8
  mov eax, [esi]
  sar eax, 52-32
  and eax, 11111111111b ; 11 bits expo
  sub eax, 1023 ; bias
  print str$(eax), 9, "expo R8", 13, 10
  exit
end start


Should be 2x0, right?
0       expo R4
41      expo R8


real8 is a qword   :idea:

mov esi, offset My8
mov eax, [esi+4]
Title: Re: How to output 128 bits to the screen?
Post by: FORTRANS on July 24, 2017, 01:15:19 AM
Hi,

   Little-endian, ESI+4?

Regards,

Steve
Title: Re: How to output 128 bits to the screen?
Post by: jj2007 on July 24, 2017, 03:41:57 AM
Of course! Stupid mistake...