Author Topic: GCC QuadMath library - REAL16 math  (Read 441 times)

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 7760
  • Assembler is fun ;-)
    • MasmBasic
GCC QuadMath library - REAL16 math
« on: August 17, 2017, 10:28:30 AM »
Attached a testbed for the QuadMath lib - about 90 functions. Building requires MasmBasic 17 August and a 32-bit GCC installation.

It seems to work so far (in the sense: with arbitrary numbers, it doesn't throw exceptions), but my math skills are clearly not good enough. Unfortunately, the documentation for that library is lousy. Does anybody know enough about these functions to design meaningful tests?

Code: [Select]
3.16227766016837933199889354443272e-01
Complex numbers:
-0.300000000000000000000000000000000r   0.100000000000000000000000000000000i
-0.500000000000000000000000000000000r   0.200000000000000000000000000000000i
1       6.79675056344163539816123196439774e-01    Quad$(QuadMath(acosq, f128_1))       arc cosine function
2       -nan                                      Quad$(QuadMath(acoshq, f128_1))      inverse hyperbolic cosine function
3       8.91121270450733079415198495199977e-01    Quad$(QuadMath(asinq, f128_1))       arc sine function
4       7.15220808521240713368180068139420e-01    Quad$(QuadMath(asinhq, f128_1))      inverse hyperbolic sine function
5       6.61042684235119596446884984928197e-01    Quad$(QuadMath(atanq, f128_1))       arc tangent function
6       1.03971880209293260540357689630520e+00    Quad$(QuadMath(atanhq, f128_1))      inverse hyperbolic tangent function
7       7.18829999621624505417014151525905e-01    Quad$(QuadMath(atan2q, f128_1, f128  arc tangent function
8       9.19641085579807331708184954882012e-01    Quad$(QuadMath(cbrtq, f128_1))       cube root function
9       1.00000000000000000000000000000000e+00    Quad$(QuadMath(ceilq, f128_1))       ceiling value function
10      7.77777000000000000000000000000000e-01    Quad$(QuadMath(copysignq, f128_1, f  copy sign of a number
11      1.31802721007488863001046816772184e+00    Quad$(QuadMath(coshq, f128_1))       hyperbolic cosine function
12      7.12475170303218178481897562102759e-01    Quad$(QuadMath(cosq, f128_1))        cosine function
13      7.28642947148188881602143870565993e-01    Quad$(QuadMath(erfq, f128_1))        error function
14      2.71357052851811118397856129434007e-01    Quad$(QuadMath(erfcq, f128_1))       complementary error function
15      2.17662823878251521093957473563285e+00    Quad$(QuadMath(expq, f128_1))        exponential function
16      1.17662823878251521093957473563285e+00    Quad$(QuadMath(expm1q, f128_1))      exponential minus 1 function
17      7.77777000000000000000000000000000e-01    Quad$(QuadMath(fabsq, f128_1))       absolute value function
18      0.00000000000000000000000000000000e+00    Quad$(QuadMath(fdimq, f128_1, f128_  positive difference function
19      1                                         Str$(QuadMath(finiteq, f128_1))      check finiteness of value
20      0.00000000000000000000000000000000e+00    Quad$(QuadMath(floorq, f128_1))      floor value function
21      1.69135564197599999999999999999999e+00    Quad$(QuadMath(fmaq, f128_1, f128_2  fused multiply and add
22      8.88887999999999999999999999999999e-01    Quad$(QuadMath(fmaxq, f128_1, f128_  determine maximum of two values
23      7.77776999999999999999999999999999e-01    Quad$(QuadMath(fminq, f128_1, f128_  determine minimum of two values
24      7.77776999999999999999999999999999e-01    Quad$(QuadMath(fmodq, f128_1, f128_  remainder value function
25      7.77776999999999999999999999999999e-01    Quad$(QuadMath(frexpq, f128_1, &int  extract mantissa and exponent
26      1.18112613139875963037219043508971e+00    Quad$(QuadMath(hypotq, f128_1, f128  Eucledian distance function
27      0                                         Str$(QuadMath(isinfq, f128_1))       check for infinity
28      -1                                        Str$(QuadMath(ilogbq, f128_1))       get exponent of the value
29      0                                         Str$(QuadMath(isnanq, f128_1))       check for not a number
30      8.54388504707771712092309739814944e-01    Quad$(QuadMath(j0q, f128_1))         Bessel function of the first kind, first order
31      3.60213810637432487067489691829813e-01    Quad$(QuadMath(j1q, f128_1))         Bessel function of the first kind, second order
33      7.77776999999999999999999999999999e-01    Quad$(QuadMath(ldexpq, f128_1))      load exponent of the value
34      1.74081138059681937201628653041458e-01    Quad$(QuadMath(lgammaq, f128_1))     logarithmic gamma function
35      0                                         Str$(QuadMath(llrintq, f128_1))      round to nearest integer value
36      1                                         Str$(QuadMath(llroundq, f128_1))     round to nearest integer value away from zero
37      -2.51315428281406078018471313735404e-01   Quad$(QuadMath(logq, f128_1))        natural logarithm function
38      -1.09144903719767094515383760835130e-01   Quad$(QuadMath(log10q, f128_1))      base 10 logarithm function
39      -3.62571522080470492430259119929199e-01   Quad$(QuadMath(log2q, f128_1))       base 2 logarithm function
40      5.75363707403466151725524591370230e-01    Quad$(QuadMath(log1pq, f128_1))      compute natural logarithm of the value plus one
41      0                                         Str$(QuadMath(lrintq, f128_1))       round to nearest integer value
42      1                                         Str$(QuadMath(lroundq, f128_1))      round to nearest integer value away from zero
43      7.77776999999999999999999999999999e-01    Quad$(QuadMath(modfq, f128_1, OWORD  decompose the floating-point number
44      nan                                       Quad$(QuadMath(nanq, dword PTR [ebx  return quiet NaN
45      0.00000000000000000000000000000000e+00    Quad$(QuadMath(nearbyintq, f128_1))  round to nearest integer
46      7.77776999999999999999999999999999e-01    Quad$(QuadMath(nextafterq, f128_1,   next representable floating-point number
47      1.00000000000000000000000000000000e+00    Quad$(QuadMath(powq, f128_1, f128_2  power function
48      -nan                                      Quad$(QuadMath(remainderq, f128_1,   remainder function
49      -nan                                      Quad$(QuadMath(remquoq, f128_1, f12  remainder and part of quotient
50      0.00000000000000000000000000000000e+00    Quad$(QuadMath(rintq, f128_1))       round-to-nearest integral value
51      1.00000000000000000000000000000000e+00    Quad$(QuadMath(roundq, f128_1))      round-to-nearest integral value, return __float128
52      7.77776999999999999999999999999999e-01    Quad$(QuadMath(scalblnq, f128_1))    compute exponent using FLT_RADIX
53      7.77776999999999999999999999999999e-01    Quad$(QuadMath(scalbnq, f128_1))     compute exponent using FLT_RADIX
54      0                                         Str$(QuadMath(signbitq, f128_1))     return sign bit
55_     7.77776999999999999999999999999999e-01    QuadMath(sincosq, f128_1, OWORD PTR  calculate sine and cosine simultaneously
56      8.58601028707626580929106567911009e-01    Quad$(QuadMath(sinhq, f128_1))       hyperbolic sine function
57      7.01697321999592822577494428203881e-01    Quad$(QuadMath(sinq, f128_1))        sine function
58      8.81916662729534779709025956238766e-01    Quad$(QuadMath(sqrtq, f128_1))       square root function
59      9.84872668195526766344208902855793e-01    Quad$(QuadMath(tanq, f128_1))        tangent function
60      6.51428909922764009034212653601591e-01    Quad$(QuadMath(tanhq, f128_1))       hyperbolic tangent function
61      1.19015212853728978240171569191066e+00    Quad$(QuadMath(tgammaq, f128_1))     true gamma function
62      0.00000000000000000000000000000000e+00    Quad$(QuadMath(truncq, f128_1))      round to integer, towards zero
63      -1.08823755104290320639507753297712e-01   Quad$(QuadMath(y0q, f128_1))         Bessel function of the second kind, first order
64      -1.00388964645596038174697269505841e+00   Quad$(QuadMath(y1q, f128_1))         Bessel function of the second kind, second order
65      -inf                                      Quad$(QuadMath(ynq, f128_1))         Bessel function of the second kind, n-th order
66      1.11111100000000000000000000000000e+00    Quad$(QuadMath(cabsq, c128_1))       complex absolute value function
67      0.00000000000000000000000000000000e+00    Quad$(QuadMath(cargq, c128_2))       calculate the argument
68      0.00000000000000000000000000000000e+00    Quad$(QuadMath(cimagq, c128_1))      imaginary part of complex number
69      1.11111100000000000000000000000000e+00    Quad$(QuadMath(crealq, c128_1))      real part of complex number
70      0.00000000000000000000000000000000e+00    Quad$(QuadMath(cacosq, c128_1))      complex arc cosine function
71      4.67145078687467774975308067585712e-01    Quad$(QuadMath(cacoshq, c128_1))     complex arc hyperbolic cosine function
72      1.57079632679489661923132169163975e+00    Quad$(QuadMath(casinq, c128_1))      complex arc sine function
73      9.57800374871255507537319505105416e-01    Quad$(QuadMath(casinhq, c128_1))     complex arc hyperbolic sine function
74      8.37981175284630374344180916658704e-01    Quad$(QuadMath(catanq, c128_1))      complex arc tangent function
75      1.47221996326768006396617005905066e+00    Quad$(QuadMath(catanhq, c128_1))     complex arc hyperbolic tangent function
76      4.43666121279137034963262698715523e-01    Quad$(QuadMath(ccosq, c128_1))       complex cosine function
77      1.68346223218832726875681425264904e+00    Quad$(QuadMath(ccoshq, c128_1))      complex hyperbolic cosine function
78      3.03773143999174827676530639951211e+00    Quad$(QuadMath(cexpq, c128_1))       complex exponential function
79      7.12475170303218178481897562102759e-01    Quad$(QuadMath(cexpiq, f128_1))      computes the exponential function of "i" times a real value
80      1.05360415657821301227167647480979e-01    Quad$(QuadMath(clogq, c128_1))       complex natural logarithm
81      4.57574471312247636122071472795808e-02    Quad$(QuadMath(clog10q, c128_1))     complex base 10 logarithm
82      1.11111100000000000000000000000000e+00    Quad$(QuadMath(conjq, c128_1))       complex conjugate function
83      1.00000000000000000000000000000000e+00    Quad$(QuadMath(cpowq, c128_1, c128_  complex power function
84      1.11111100000000000000000000000000e+00    Quad$(QuadMath(cprojq, c128_1))      project into Riemann Sphere
85      8.96192151733726168465708950029809e-01    Quad$(QuadMath(csinq, c128_1))       complex sine function
86      1.35426920780342100800849214686307e+00    Quad$(QuadMath(csinhq, c128_1))      complex hyperbolic sine function
87      1.05409250068483079024421803054925e+00    Quad$(QuadMath(csqrtq, c128_1))      complex square root
88      2.01996976724278164327568071148291e+00    Quad$(QuadMath(ctanq, c128_1))       complex tangent function
89      8.04454761092567379921780988485073e-01    Quad$(QuadMath(ctanhq, c128_1))      complex hyperbolic tangent function
------------- all done -------------

nidud

  • Member
  • *****
  • Posts: 1411
    • https://github.com/nidud/asmc
Re: GCC QuadMath library - REAL16 math
« Reply #1 on: August 17, 2017, 11:16:01 AM »
So, from Wiki:

Quote
4000 921f b544 42d1 8469 898c c517 01b8 =
3.1415926535897932384626433832795028

https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format

Test case

Code: [Select]
#include <stdio.h>
#include <quadmath.h>

int main(void)
{
    __float128 q = 3.1415926535897932384626433832795028;
    __int64   *p = (__int64 *)&q;

    printf("%p%p - gcc\n", p[1],p[0]);
    return 0;
}

Code: [Select]
include stdio.inc

.data

x real10 3.1415926535897932384626433832795028
y real16 3.1415926535897932384626433832795028

.code

main proc
    lea edx,y
    printf("%p%p%p%p - REAL16\n",[edx+12],[edx+8],[edx+4],[edx]);
    lea edx,x
    movzx eax,word ptr [edx+8]
    mov ecx,[edx+4]
    mov edx,[edx]
    shl edx,1
    rcl ecx,1
    printf("%04X%p%pxxxxxxxxxxxx - REAL10\n",eax,ecx,edx);
    ret
main endp

    end main

output:
Code: [Select]
4000921FB54442D18469898CC51701B8 - REAL16
4000921FB54442D1846Axxxxxxxxxxxx - REAL10
4000921FB54442D18000000000000000 - gcc

So is it "real" or do they just use the FPU?

TWell

  • Member
  • ****
  • Posts: 748
Re: GCC QuadMath library - REAL16 math
« Reply #2 on: August 17, 2017, 02:55:51 PM »
__float128 q = 3.1415926535897932384626433832795028q;

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 7760
  • Assembler is fun ;-)
    • MasmBasic
Re: GCC QuadMath library - REAL16 math
« Reply #3 on: August 17, 2017, 06:08:19 PM »
__float128 q = 3.1415926535897932384626433832795028q;

Indeed :t

include \masm32\MasmBasic\MasmBasic.inc         ; download
include \masm32\MasmBasic\Res\QuadMath.inc

  SetGlobals MyPI:REAL16

  Init quad

  PrintLine "digits", Tb$, "1.23456789012345678901234567890123"
  PrintLine "PI", Tb$, "3.14159265358979323846264338327950", Tb$, "(as text)"

  movups MyPI, Quad(3.1415926535897932384626433832795028841971)
  PrintLine "MyPI", Tb$, Quad$(MyPI, g), Tb$, "Real16 precision"

  movups MyPI, Quad(FP10(3.1415926535897932384626433832795028841971))
  Inkey "MyPI", Tb$, Quad$(MyPI, g), Tb$, "Real10 precision"

EndOfCode


Code: [Select]
digits  1.23456789012345678901234567890123
PI      3.14159265358979323846264338327950      (as text)
MyPI    3.14159265358979323846264338327950      Real16 precision
MyPI    3.14159265358979323851280895940619      Real10 precision

But that is under control, thanks. I am more interested in the more complicated math stuff...

nidud

  • Member
  • *****
  • Posts: 1411
    • https://github.com/nidud/asmc
Re: GCC QuadMath library - REAL16 math
« Reply #4 on: August 17, 2017, 09:36:20 PM »
Yes, that works  :t
Code: [Select]

    __float128 q = 31415926535897932384626433832795028q-34;

4000921FB54442D18469898CC51701B8 - REAL16
4000921FB54442D18469898CC51701B8 - gcc

https://software.intel.com/en-us/node/678511
Quote
Valid REAL(16) Constants

123456789Q4000
-1.23Q-400
+2.72Q0
1.88_16

Siekmanski

  • Member
  • *****
  • Posts: 1145
Re: GCC QuadMath library - REAL16 math
« Reply #5 on: August 18, 2017, 12:03:20 AM »
Does anybody know enough about these functions to design meaningful tests?

Most of the functions can be used in high precision Digital Signal Processing.
Ask Raistlin, AFAIK he does calculations on pulsar data.

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 7760
  • Assembler is fun ;-)
    • MasmBasic
Re: GCC QuadMath library - REAL16 math
« Reply #6 on: August 19, 2017, 11:50:44 AM »
Thanks, Marinus.

Just discovered that C:\Windows\System32\calc.exe uses quad precision. But PEView doesn't give any hint to an undocumented Windows quadmath DLL :(

So they do it probably with a tiny part of the 776,192 bytes of calc.exe...

TWell

  • Member
  • ****
  • Posts: 748
Re: GCC QuadMath library - REAL16 math
« Reply #7 on: August 19, 2017, 03:20:04 PM »
Quote
In Windows 98 and later, it uses an arbitrary-precision arithmetic library
https://en.wikipedia.org/wiki/Windows_Calculator

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 7760
  • Assembler is fun ;-)
    • MasmBasic
Re: GCC QuadMath library - REAL16 math
« Reply #8 on: August 19, 2017, 07:28:16 PM »
Yes, but they don't tell you which one :(

The Wiki has a link to a defunct "calc plus" page:
Quick Details
File Name:   CalcPlus.msi
...
Download Size:   476 KB
Estimated Download Time:    2 min 56K
Good ol' times :P

mabdelouahab

  • Member
  • ***
  • Posts: 346
Re: GCC QuadMath library - REAL16 math
« Reply #9 on: October 21, 2017, 03:04:27 AM »
Quote
POLINK: fatal error: File not found: 'C:\TDM-GCC-32\lib\gcc\mingw32\4.9.2\libquadmath.a'.
I've installed the version tdm-gcc-5.1.0

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 7760
  • Assembler is fun ;-)
    • MasmBasic
Re: GCC QuadMath library - REAL16 math
« Reply #10 on: October 21, 2017, 03:10:38 AM »
Try Init dynaquad (that forces using the DLLs, which should always be in the same location).

If that doesn't work, try inserting this line before Init:

QuadLibStaticP$ equ   <C:\TDM-GCC-32\lib\gcc\mingw32\5.1.0\>

There are more constants that can be adapted, but normally you shouldn't touch them:

QmStatic$ equ      <libquadmath.a>
GccStatic$ equ      <libgcc.a>
QuadLibDynaP$ equ   <C:\TDM-GCC-32\bin\>
QmDll$ equ      <libquadmath-0>
GccDll$ equ      <libgcc_s_dw2-1>

mabdelouahab

  • Member
  • ***
  • Posts: 346
Re: GCC QuadMath library - REAL16 math
« Reply #11 on: October 21, 2017, 05:47:37 AM »
Try Init dynaquad (that forces using the DLLs, which should always be in the same location).
It works, thanks :t

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 7760
  • Assembler is fun ;-)
    • MasmBasic
Re: GCC QuadMath library - REAL16 math
« Reply #12 on: October 21, 2017, 06:54:57 AM »
The static version should work, too. It will give you plenty of warnings of the type "POLINK: warning: Section name '.debug_info' is longer than 8 characters; truncated." but they can be ignored.

In RichMasm, File/New Masm source opens a list of templates; towards the bottom is a QuadMath example; I just remembered that Quad(immediate) is no longer necessary, i.e. you can use the immediate REAL16 directly:

  movups PiBy180, QuadMath(__divtf3, MyPI, Quad(180.0))
  PrintLine "PI/180", Tb$, Quad$(PiBy180)
  movups PiBy180, QuadMath(__divtf3, MyPI, 180.0)
  PrintLine "PI/180", Tb$, Quad$(PiBy180)

LiaoMi

  • Member
  • **
  • Posts: 172
Re: GCC QuadMath library - REAL16 math
« Reply #13 on: October 21, 2017, 11:51:47 PM »
Hi,

here is the latest version libquadmath_x32_x64_gcc-7_2_0 https://mega.co.nz/#!VxQhGYiZ!AAAAAAAAAACUIvLONoOxdwAAAAAAAAAAlCLyzjaDsXc from the msys package, with headers  :eusa_boohoo:

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 7760
  • Assembler is fun ;-)
    • MasmBasic
Re: GCC QuadMath library - REAL16 math
« Reply #14 on: October 22, 2017, 01:50:23 AM »
Code: [Select]
  QuadLibDynaP$ equ <\Masm32\MasmBasic\Members\LiaoMi\x32\> ; path to the DLLs
  Init dynaquad ; use dynaquad to link the DLLs dynamically

Works fine, thanks. Any big difference to the previous version? The new ones are a few kBytes shorter.