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...
Dave may have something for you. (http://masm32.com/board/index.php?topic=222.0)
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...
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
movq pi,xmm0
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
Quote from: Mikl__ on July 19, 2017, 10:51:33 PMWhat should I do to output 128-bits float to the screen?
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:
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.
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
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.
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
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:
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.
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+
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?
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.
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.
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.
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
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.
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
Unlike other vendors, when it is time to print, Microsoft considers "long double"="double". :eusa_snooty:
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)
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???
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:
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.
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:
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
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).
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
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
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
Hi, jj2007, aw27, TWell, jack, FORTRAN!
Many thanks for the tips and helpness!(https://wasm.in/styles/smiles_s/good2.gif)
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 :(
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:
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 ::)
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.
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
?
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?
I don't have GCC installed now. :( :shock:
codepage=866
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)
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
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]
Hi,
Little-endian, ESI+4?
Regards,
Steve
Of course! Stupid mistake...