├── COPYING
├── README.md
├── meson.build
├── src
├── meson.build
├── numeric-glib-1.0.vapi
├── numeric-transform.c
├── numeric-types.c
├── numeric-types.h
├── numeric-vector.c
├── numeric-vector.h
├── numeric.c
└── numeric.h
├── tests
├── decimal-c-test.c
├── decimal-test.vala
├── meson.build
└── numeric-test.vala
└── vapi
└── libdfp.vapi
/COPYING:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Numeric-GLib
2 |
3 | Numeric data types for GLib via GCC extensions
4 |
5 | # Features
6 |
7 | - 128 bit integers with `int128` and `uint128`
8 | - `float80` and quad-precision `float128`
9 | - decimal with `decimal32`, `decimal64` and `decimal128`
10 | - C99 `complex`, `complex80` and `complex128`
11 | - vectorized operations on supported types
12 | - little and big endian variants with `_le` and `_be` suffix
13 |
14 | All types are prefixed with `numeric_`, but can be used as-is by importing the
15 | `Numeric` namespace in Vala.
16 |
17 | # Usage
18 |
19 | In Vala, one can simply add `--pkg=numeric-glib-1.0` to include the type
20 | definitions and link against the shared library to initialize all the types and
21 | transformations.
22 |
23 | ```bash
24 | vala --pkg=numeric-glib-1.0 main.vala
25 | ```
26 |
27 | Or via Meson, the `numeric_glib` dependency can be included in any target.
28 |
29 | ```python
30 | project('Foo')
31 |
32 | glib = dependency('glib-2.0')
33 | gobject = dependency('gobject-2.0')
34 | numeric_glib = dependency('numeric-glib-1.0', fallback: ['numeric-glib', 'numeric_glib_dep'])
35 | numeric_glib_vala = dependency('numeric-glib-1.0', fallback: ['numeric-glib', 'numeric_glib_vala_dep'])
36 |
37 | executable('foo', 'foo.c', dependencies: [glib, gobject, numeric_glib])
38 | executable('foo', 'foo.vala', dependencies: [glib, gobject, numeric_glib_vala])
39 | ```
40 |
--------------------------------------------------------------------------------
/meson.build:
--------------------------------------------------------------------------------
1 | project('Numeric-GLib', 'c', 'vala',
2 | meson_version: '>=0.46')
3 |
4 | add_project_arguments(['--vapidir', join_paths(meson.current_source_dir(), 'vapi')],
5 | language: 'vala')
6 |
7 | glib_dep = dependency('glib-2.0')
8 | gobject_dep = dependency('gobject-2.0')
9 | quadmath_dep = meson.get_compiler('c').find_library('quadmath')
10 | dfp_dep = dependency('libdfp', required: false)
11 |
12 | subdir('src')
13 | subdir('tests')
14 |
--------------------------------------------------------------------------------
/src/meson.build:
--------------------------------------------------------------------------------
1 | numeric_sources = [
2 | 'numeric.c',
3 | 'numeric-transform.c',
4 | 'numeric-types.c',
5 | 'numeric-vector.c']
6 | numeric_glib_lib = library('numeric-glib-1.0', numeric_sources,
7 | dependencies: [glib_dep, gobject_dep, dfp_dep],
8 | c_args: '-DNUMERIC_COMPILATION',
9 | install: true)
10 |
11 | numeric_glib_dep = declare_dependency(link_with: numeric_glib_lib,
12 | include_directories: include_directories('.'))
13 |
14 | numeric_glib_vala_dep = declare_dependency(dependencies: numeric_glib_dep,
15 | sources: 'numeric-glib-1.0.vapi')
16 |
17 | install_headers(['numeric.h', 'numeric-types.h', 'numeric-vector.h'], subdir: 'numeric-glib-1.0')
18 | install_data('numeric-glib-1.0.vapi', install_dir: 'share/vala/vapi')
19 |
20 | pkgconfig = import('pkgconfig')
21 | pkgconfig.generate(numeric_glib_lib,
22 | version: meson.project_version(),
23 | description: 'Numeric data types for GLib via GCC extensions',
24 | subdirs: 'numeric-glib-1.0')
25 |
--------------------------------------------------------------------------------
/src/numeric-glib-1.0.vapi:
--------------------------------------------------------------------------------
1 | /* Copyright 2016 Guillaume Poirier-Morency
2 | *
3 | * This file is part of Numeric-GLib.
4 | *
5 | * Numeric-GLib is free software: you can redistribute it and/or modify it under
6 | * the terms of the GNU Lesser General Public License as published by the Free
7 | * Software Foundation, either version 3 of the License, or (at your option) any
8 | * later version.
9 | *
10 | * Numeric-GLib is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with Numeric-GLib. If not, see .
17 | */
18 |
19 | [CCode (cprefix = "numeric_", cheader_filename = "numeric.h")]
20 | namespace Numeric
21 | {
22 | [IntegerType (rank = 12, width = 16)]
23 | [CCode (get_value_function = "numeric_value_get_int128", set_value_function = "numeric_value_set_int128")]
24 | public struct int128 {}
25 |
26 | [IntegerType (rank = 13, width = 16)]
27 | [CCode (get_value_function = "numeric_value_get_uint128", set_value_function = "numeric_value_set_uint128")]
28 | public struct uint128 {}
29 |
30 | [FloatingType (rank = 10, width = 4)]
31 | [CCode (get_value_function = "numeric_value_get_float_le", set_value_function = "numeric_value_set_float_le")]
32 | public struct float_le
33 | {
34 | public static float_le from_float (float num);
35 | public float to_float ();
36 | }
37 |
38 | [FloatingType (rank = 10, width = 4)]
39 | [CCode (get_value_function = "numeric_value_get_float_be", set_value_function = "numeric_value_set_float_be")]
40 | public struct float_be
41 | {
42 | public static float_be from_float (float num);
43 | public float to_float ();
44 | }
45 |
46 | [FloatingType (rank = 11, width = 8)]
47 | [CCode (get_value_function = "numeric_value_get_double_le", set_value_function = "numeric_value_set_double_le")]
48 | public struct double_le
49 | {
50 | public static double_le from_double (double num);
51 | public double to_double ();
52 | }
53 |
54 | [FloatingType (rank = 11, width = 8)]
55 | [CCode (get_value_function = "numeric_value_get_double_be", set_value_function = "numeric_value_set_double_be")]
56 | public struct double_be {
57 | public static double_be from_double (double num);
58 | public double to_double ();
59 | }
60 |
61 | [FloatingType (rank = 12, width = 10)]
62 | [CCode (get_value_function = "numeric_value_get_float80", set_value_function = "numeric_value_set_float80")]
63 | public struct float80
64 | {
65 | [CCode (cname = "strtold", cheader_filename = "stdlib.h")]
66 | public static float80 parse (string s, out char sp = null);
67 | }
68 |
69 | [FloatingType (rank = 12, width = 16)]
70 | [CCode (cprefix = "FLT128_", get_value_function = "numeric_value_get_float128", set_value_function = "numeric_value_set_float128")]
71 | public struct float128
72 | {
73 | [CCode (cname = "NUMERIC_FLOAT128_FORMAT")]
74 | public const string FORMAT;
75 | [CCode (cname = "NUMERIC_FLOAT128_MODIFIER")]
76 | public const string FORMAT_MODIFIER;
77 |
78 | [CCode (cheader_filename = "quadmath.h")]
79 | public const float128 MAX;
80 | [CCode (cheader_filename = "quadmath.h")]
81 | public const float128 MIN;
82 | [CCode (cheader_filename = "quadmath.h")]
83 | public const float128 EPSILON;
84 | [CCode (cheader_filename = "quadmath.h")]
85 | public const float128 DENORM_MIN;
86 | [CCode (cheader_filename = "quadmath.h")]
87 | public const int MANT_DIG;
88 | [CCode (cheader_filename = "quadmath.h")]
89 | public const int MIN_EXP;
90 | [CCode (cheader_filename = "quadmath.h")]
91 | public const int MAX_EXP;
92 | [CCode (cheader_filename = "quadmath.h")]
93 | public const int DIG;
94 | [CCode (cheader_filename = "quadmath.h")]
95 | public const int MIN_10_EXP;
96 | [CCode (cheader_filename = "quadmath.h")]
97 | public const int MAX_10_EXP;
98 | [CCode (cname = "strtoflt128", cheader_filename = "quadmath.h")]
99 | public static float128 parse (string s, out char sp = null);
100 | [CCode (cname = "quadmath_snprintf")]
101 | private static int _quadmath_snprintf (char[] s, string format, ...);
102 | public string to_string (string format = "%" + FORMAT)
103 | {
104 | var buffer = new char[128];
105 | var n = _quadmath_snprintf (buffer, format, this);
106 | if (n >= buffer.length) {
107 | buffer = new char[n + 1];
108 | _quadmath_snprintf (buffer, format, this);
109 | }
110 | return (string) buffer;
111 | }
112 | }
113 |
114 | [FloatingType (decimal = true, rank = 6, width = 4)]
115 | [CCode (get_value_function = "numeric_value_get_decimal32", set_value_function = "numeric_value_set_decimal32")]
116 | public struct decimal32
117 | {
118 | public const string FORMAT;
119 | [CCode (cname = "NUMERIC_DECIMAL32_MODIFIER")]
120 | public const string FORMAT_MODIFIER;
121 |
122 | [CCode (cname = "DEC_NAN", cheader_filename = "math.h")]
123 | public const decimal32 NAN;
124 | [CCode (cname = "DEC_INFINITY", cheader_filename = "math.h")]
125 | public const decimal32 INFINITY;
126 |
127 | [CCode (cname = "strtod32", cheader_filename = "stdlib.h")]
128 | public static decimal32 parse (string s, out char sp = null);
129 |
130 | public string to_string (string format = "%" + FORMAT)
131 | {
132 | return format.printf (this);
133 | }
134 | }
135 |
136 | [FloatingType (decimal = true, rank = 10, width = 8)]
137 | [CCode (get_value_function = "numeric_value_get_decimal64", set_value_function = "numeric_value_set_decimal64")]
138 | public struct decimal64
139 | {
140 | public const string FORMAT;
141 | [CCode (cname = "NUMERIC_DECIMAL64_MODIFIER")]
142 | public const string FORMAT_MODIFIER;
143 |
144 | [CCode (cname = "strtod64", cheader_filename = "stdlib.h")]
145 | public static decimal64 parse (string s, out char sp = null);
146 |
147 | public string to_string (string format = "%" + FORMAT)
148 | {
149 | return format.printf (this);
150 | }
151 | }
152 |
153 | [FloatingType (decimal = true, rank = 12, width = 16)]
154 | [CCode (get_value_function = "numeric_value_get_decimal128", set_value_function = "numeric_value_set_decimal128")]
155 | public struct decimal128
156 | {
157 | public const string FORMAT;
158 | [CCode (cname = "NUMERIC_DECIMAL128_MODIFIER")]
159 | public const string FORMAT_MODIFIER;
160 |
161 | [CCode (cname = "strtod128", cheader_filename = "stdlib.h")]
162 | public static decimal128 parse (string s, out char sp = null);
163 |
164 | public string to_string (string format = "%" + FORMAT)
165 | {
166 | return format.printf (this);
167 | }
168 | }
169 |
170 | [FloatingType (rank = 6, width = 8)]
171 | [CCode (get_value_function = "numeric_value_get_complex32", set_value_function = "numeric_value_set_complex32")]
172 | public struct complex32
173 | {
174 | [CCode (cname = "crealf", cheader_filename = "complex.h")]
175 | public float real ();
176 | [CCode (cname = "cimagf", cheader_filename = "complex.h")]
177 | public float image ();
178 | }
179 |
180 | [FloatingType (rank = 6, width = 8)]
181 | [CCode (get_value_function = "numeric_value_get_complex64", set_value_function = "numeric_value_set_complex64")]
182 | public struct complex64
183 | {
184 | [CCode (cname = "creal", cheader_filename = "complex.h")]
185 | public double real ();
186 | [CCode (cname = "cimag", cheader_filename = "complex.h")]
187 | public double image ();
188 | }
189 |
190 | [FloatingType (rank = 12, width = 10)]
191 | [CCode (get_value_function = "numeric_value_get_complex80", set_value_function = "numeric_value_set_complex80")]
192 | public struct complex80
193 | {
194 | [CCode (cname = "creall", cheader_filename = "complex.h")]
195 | public float80 real ();
196 | [CCode (cname = "cimagl", cheader_filename = "complex.h")]
197 | public float80 image ();
198 | }
199 |
200 | [FloatingType (rank = 12, width = 16)]
201 | [CCode (get_value_function = "numeric_value_get_complex128", set_value_function = "numeric_value_set_complex128")]
202 | public struct complex128
203 | {
204 | [CCode (cname = "crealq", cheader_filename = "quadmath.h")]
205 | public float128 real ();
206 | [CCode (cname = "cimagq", cheader_filename = "quadmath.h")]
207 | public float128 image ();
208 | }
209 |
210 | public struct int32_v16
211 | {
212 | public static int32_v16 add (int32_v16 x, int32_v16 y);
213 | public static int32_v16 sub (int32_v16 x, int32_v16 y);
214 | public int get (size_t index);
215 | public void set (size_t index, int val);
216 | }
217 |
218 | [CCode (cprefix = "M_", lower_case_cprefix = "", cheader_filename = "math.h,quadmath.h")]
219 | namespace Math
220 | {
221 | [CCode (cprefix = "", cheader_filename = "complex.h")]
222 | public const complex64 I;
223 | public const float128 Eq;
224 | public const float128 LOG2Eq;
225 | public const float128 LOG10Eq;
226 | public const float128 LN2q;
227 | public const float128 LN10q;
228 | public const float128 PIq;
229 | public const float128 PI_2q;
230 | public const float128 PI_4q;
231 | public const float128 1_PIq;
232 | public const float128 2_PIq;
233 | public const float128 2_SQRTPIq;
234 | public const float128 SQRT2q;
235 | public const float128 SQRT1_2q;
236 | public float128 acosq (float128 x);
237 | public float128 acoshq (float128 x);
238 | public float128 asinq (float128 x);
239 | public float128 asinhq (float128 x);
240 | public float128 atanq (float128 x);
241 | public float128 atanhq (float128 x);
242 | public float128 atan2q (float128 x, float128 y);
243 | public float128 cbrtq (float128 x);
244 | public float128 ceilq (float128 x);
245 | public float128 copysignq (float128 x, float128 y);
246 | public float128 coshq (float128 x);
247 | public float128 cosq (float128 x);
248 | public float128 erfq (float128 x);
249 | public float128 erfcq (float128 x);
250 | public float128 expq (float128 x);
251 | public float128 expm1q (float128 x);
252 | public float128 fabsq (float128 x);
253 | public float128 fdimq (float128 x, float128 y);
254 | public float128 finiteq (float128 x);
255 | public float128 floorq (float128 x);
256 | public float128 fmaq (float128 x, float128 y);
257 | public float128 fmaxq (float128 x, float128 y);
258 | public float128 fminq (float128 x, float128 y);
259 | public float128 fmodq (float128 x, float128 y);
260 | public float128 frexpq (float128 x, out int e);
261 | public float128 hypotq (float128 x, float128 y);
262 | public float128 ilogbq (float128 x);
263 | public float128 isinfq (float128 x);
264 | public float128 isnanq (float128 x);
265 | public float128 j0q (float128 x);
266 | public float128 j1q (float128 x);
267 | public float128 jnq (int n, float128 x);
268 | public float128 ldexpq (float128 x, int e);
269 | public float128 lgammaq (float128 x);
270 | public float128 llrintq (float128 x);
271 | public float128 llroundq (float128 x);
272 | public float128 logq (float128 x);
273 | public float128 log10q (float128 x);
274 | public float128 log1pq (float128 x);
275 | public float128 log2q (float128 x);
276 | public float128 lrintq (float128 x);
277 | public float128 lroundq (float128 x);
278 | public float128 modfq (float128 x, float128 y);
279 | public float128 nanq (string x);
280 | public float128 nearbyintq (float128 x);
281 | public float128 nextafterq (float128 x, float128 y);
282 | public float128 powq (float128 x, float128 y);
283 | public float128 remainderq (float128 x, float128 y);
284 | public float128 remquoq (float128 x, float128 y, out int e);
285 | public float128 rintq (float128 x);
286 | public float128 roundq (float128 x);
287 | public float128 scalblnq (float128 x, long e);
288 | public float128 scalbnq (float128 x, int e);
289 | public float128 signbitq (float128 x);
290 | public float128 sincosq (float128 x, float128 y);
291 | public float128 sinhq (float128 x);
292 | public float128 sinq (float128 x);
293 | public float128 sqrtq (float128 x);
294 | public float128 tanq (float128 x);
295 | public float128 tanhq (float128 x);
296 | public float128 tgammaq (float128 x);
297 | public float128 truncq (float128 x);
298 | public float128 y0q (float128 x);
299 | public float128 y1q (float128 x);
300 | public float128 ynq (int n, float128 x);
301 | public float128 cabsq (complex128 x);
302 | public float128 cargq (complex128 x);
303 | public float128 cimagq (complex128 x);
304 | public float128 crealq (complex128 x);
305 | public complex128 cacoshq (complex128 x);
306 | public complex128 cacosq (complex128 x);
307 | public complex128 casinhq (complex128 x);
308 | public complex128 casinq (complex128 x);
309 | public complex128 catanhq (complex128 x);
310 | public complex128 catanq (complex128 x);
311 | public complex128 ccosq (complex128 x);
312 | public complex128 ccoshq (complex128 x);
313 | public complex128 cexpq (complex128 x);
314 | public complex128 cexpiq (complex128 x);
315 | public complex128 real (complex128 x);
316 | public complex128 clogq (complex128 x);
317 | public complex128 clog10q (complex128 x);
318 | public complex128 conjq (complex128 x);
319 | public complex128 cpowq (complex128 x);
320 | public complex128 cprojq (complex128 x);
321 | public complex128 csinq (complex128 x);
322 | public complex128 csinhq (complex128 x);
323 | public complex128 csqrtq (complex128 x);
324 | public complex128 ctanq (complex128 x);
325 | public complex128 ctanhq (complex128 x);
326 | /* the following definitions are in a overwritten math.h file located in dfp/math.h */
327 | public const decimal128 Edl;
328 | public const decimal128 LOG2Edl;
329 | public const decimal128 LOG10Edl;
330 | public const decimal128 LN2dl;
331 | public const decimal128 LN10dl;
332 | public const decimal128 PIdl;
333 | public const decimal128 PI_2dl;
334 | public const decimal128 PI_4dl;
335 | public const decimal128 1_PIdl;
336 | public const decimal128 2_PIdl;
337 | public const decimal128 2_SQRTPIdl;
338 | public const decimal128 SQRT2dl;
339 | public const decimal128 SQRT1_2dl;
340 | public decimal128 expd128 (decimal128 x);
341 | }
342 | }
343 |
--------------------------------------------------------------------------------
/src/numeric-transform.c:
--------------------------------------------------------------------------------
1 | /* Copyright 2016 Guillaume Poirier-Morency
2 | *
3 | * This file is part of Numeric-GLib.
4 | *
5 | * Numeric-GLib is free software: you can redistribute it and/or modify it under
6 | * the terms of the GNU Lesser General Public License as published by the Free
7 | * Software Foundation, either version 3 of the License, or (at your option) any
8 | * later version.
9 | *
10 | * Numeric-GLib is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with Numeric-GLib. If not, see .
17 | */
18 |
19 | #include "numeric-types.h"
20 |
21 | #include
22 |
23 | // if 'src_value' can be copied to 'dest_value'
24 | #define DEFINE_COPY(from_type, to_type) \
25 | static void \
26 | from_type##_to_##to_type (const GValue *src_value, GValue *dest_value) \
27 | { \
28 | dest_value->data[0].v_pointer = g_malloc (sizeof (to_type)); \
29 | memcpy (dest_value->data[0].v_pointer, src_value->data[0].v_pointer, sizeof (from_type)); \
30 | } \
31 |
32 | DEFINE_COPY (numeric_int128, numeric_int128)
33 | DEFINE_COPY (numeric_uint128, numeric_uint128)
34 | DEFINE_COPY (numeric_float80, numeric_float80)
35 | DEFINE_COPY (numeric_float128, numeric_float128)
36 | #ifdef __STD_DEC_FP__
37 | DEFINE_COPY (numeric_decimal32, numeric_decimal32)
38 | DEFINE_COPY (numeric_decimal64, numeric_decimal64)
39 | DEFINE_COPY (numeric_decimal128, numeric_decimal128)
40 | #endif
41 | DEFINE_COPY (numeric_complex32, numeric_complex32)
42 | DEFINE_COPY (numeric_complex64, numeric_complex64)
43 | DEFINE_COPY (numeric_complex80, numeric_complex80)
44 | DEFINE_COPY (numeric_complex128, numeric_complex128)
45 |
46 | #define DEFINE_CAST_FROM_FIELD(src_type, src_field, dest_type) \
47 | static void \
48 | src_type##_to_##dest_type (const GValue *src_value, GValue *dest_value) \
49 | { \
50 | src_type src_data = (src_type) src_value->data[0].src_field; \
51 | dest_type dest_data = (dest_type) src_data; \
52 | dest_value->data[0].v_pointer = g_malloc (sizeof (dest_type)); \
53 | memcpy (dest_value->data[0].v_pointer, &dest_data, sizeof (src_type)); \
54 | }
55 |
56 | #define DEFINE_CAST_FROM_ALL_FIELDS(src_type) \
57 | DEFINE_CAST_FROM_FIELD (gchar, v_int, src_type) \
58 | DEFINE_CAST_FROM_FIELD (guchar, v_int, src_type) \
59 | DEFINE_CAST_FROM_FIELD (gint, v_int, src_type) \
60 | DEFINE_CAST_FROM_FIELD (guint, v_uint, src_type) \
61 | DEFINE_CAST_FROM_FIELD (glong, v_long, src_type) \
62 | DEFINE_CAST_FROM_FIELD (gulong, v_ulong, src_type) \
63 | DEFINE_CAST_FROM_FIELD (gint64, v_int64, src_type) \
64 | DEFINE_CAST_FROM_FIELD (guint64, v_uint64, src_type) \
65 | DEFINE_CAST_FROM_FIELD (gfloat, v_float, src_type) \
66 | DEFINE_CAST_FROM_FIELD (gdouble, v_double, src_type)
67 |
68 | DEFINE_CAST_FROM_ALL_FIELDS (numeric_int128)
69 | DEFINE_CAST_FROM_ALL_FIELDS (numeric_uint128)
70 | DEFINE_CAST_FROM_ALL_FIELDS (numeric_float80)
71 | DEFINE_CAST_FROM_ALL_FIELDS (numeric_float128)
72 |
73 | #ifdef __STD_DEC_FP__
74 | DEFINE_CAST_FROM_ALL_FIELDS (numeric_decimal32)
75 | DEFINE_CAST_FROM_ALL_FIELDS (numeric_decimal64)
76 | DEFINE_CAST_FROM_ALL_FIELDS (numeric_decimal128)
77 | #endif
78 |
79 | DEFINE_CAST_FROM_ALL_FIELDS (numeric_complex32)
80 | DEFINE_CAST_FROM_ALL_FIELDS (numeric_complex64)
81 | DEFINE_CAST_FROM_ALL_FIELDS (numeric_complex80)
82 | DEFINE_CAST_FROM_ALL_FIELDS (numeric_complex128)
83 |
84 | #define DEFINE_CAST_TO_FIELD(src_type, dest_field, dest_type) \
85 | static void \
86 | src_type##_to_##dest_type (const GValue *src_value, GValue *dest_value) \
87 | { \
88 | src_type src_data = *(src_type*) src_value->data[0].v_pointer; \
89 | dest_type dest_data = (dest_type) src_data; \
90 | dest_value->data[0].dest_field = dest_data; \
91 | }
92 |
93 | #define DEFINE_CAST_TO_ALL_FIELDS(src_type) \
94 | DEFINE_CAST_TO_FIELD (src_type, v_int, gchar) \
95 | DEFINE_CAST_TO_FIELD (src_type, v_int, guchar) \
96 | DEFINE_CAST_TO_FIELD (src_type, v_int, gint) \
97 | DEFINE_CAST_TO_FIELD (src_type, v_uint, guint) \
98 | DEFINE_CAST_TO_FIELD (src_type, v_long, glong) \
99 | DEFINE_CAST_TO_FIELD (src_type, v_ulong, gulong) \
100 | DEFINE_CAST_TO_FIELD (src_type, v_int64, gint64) \
101 | DEFINE_CAST_TO_FIELD (src_type, v_uint64, guint64) \
102 | DEFINE_CAST_TO_FIELD (src_type, v_float, gfloat) \
103 | DEFINE_CAST_TO_FIELD (src_type, v_double, gdouble)
104 |
105 | DEFINE_CAST_TO_ALL_FIELDS (numeric_int128)
106 | DEFINE_CAST_TO_ALL_FIELDS (numeric_uint128)
107 | DEFINE_CAST_TO_ALL_FIELDS (numeric_float80)
108 | DEFINE_CAST_TO_ALL_FIELDS (numeric_float128)
109 |
110 | #ifdef __STD_DEC_FP__
111 | DEFINE_CAST_TO_ALL_FIELDS (numeric_decimal32)
112 | DEFINE_CAST_TO_ALL_FIELDS (numeric_decimal64)
113 | DEFINE_CAST_TO_ALL_FIELDS (numeric_decimal128)
114 | #endif
115 |
116 | DEFINE_CAST_TO_ALL_FIELDS (numeric_complex32)
117 | DEFINE_CAST_TO_ALL_FIELDS (numeric_complex64)
118 | DEFINE_CAST_TO_ALL_FIELDS (numeric_complex80)
119 | DEFINE_CAST_TO_ALL_FIELDS (numeric_complex128)
120 |
121 | #define DEFINE_CAST(src_type, dest_type) \
122 | static void \
123 | src_type##_to_##dest_type (const GValue *src_value, GValue *dest_value) \
124 | { \
125 | src_type src_data = *(src_type*) src_value->data[0].v_pointer; \
126 | dest_type dest_data = (dest_type) src_data; \
127 | dest_value->data[0].v_pointer = g_malloc (sizeof (dest_type)); \
128 | memcpy (dest_value->data[0].v_pointer, &dest_data, sizeof (src_type)); \
129 | }
130 |
131 | // int128
132 | DEFINE_CAST(numeric_int128, numeric_uint128)
133 | DEFINE_CAST(numeric_int128, numeric_float80)
134 | DEFINE_CAST(numeric_int128, numeric_float128)
135 | #ifdef __STDC_DEC_FP__
136 | DEFINE_CAST(numeric_int128, numeric_decimal32)
137 | DEFINE_CAST(numeric_int128, numeric_decimal64)
138 | DEFINE_CAST(numeric_int128, numeric_decimal128)
139 | #endif
140 | DEFINE_CAST(numeric_int128, numeric_complex32)
141 | DEFINE_CAST(numeric_int128, numeric_complex64)
142 | DEFINE_CAST(numeric_int128, numeric_complex80)
143 | DEFINE_CAST(numeric_int128, numeric_complex128)
144 |
145 | // uint128
146 | DEFINE_CAST(numeric_uint128, numeric_int128)
147 | DEFINE_CAST(numeric_uint128, numeric_float80)
148 | DEFINE_CAST(numeric_uint128, numeric_float128)
149 | #ifdef __STDC_DEC_FP__
150 | DEFINE_CAST(numeric_uint128, numeric_decimal32)
151 | DEFINE_CAST(numeric_uint128, numeric_decimal64)
152 | DEFINE_CAST(numeric_uint128, numeric_decimal128)
153 | #endif
154 | DEFINE_CAST(numeric_uint128, numeric_complex32)
155 | DEFINE_CAST(numeric_uint128, numeric_complex64)
156 | DEFINE_CAST(numeric_uint128, numeric_complex80)
157 | DEFINE_CAST(numeric_uint128, numeric_complex128)
158 |
159 | // float80
160 | DEFINE_CAST(numeric_float80, numeric_int128)
161 | DEFINE_CAST(numeric_float80, numeric_uint128)
162 | DEFINE_CAST(numeric_float80, numeric_float128)
163 | #ifdef __STDC_DEC_FP__
164 | DEFINE_CAST(numeric_float80, numeric_decimal32)
165 | DEFINE_CAST(numeric_float80, numeric_decimal64)
166 | DEFINE_CAST(numeric_float80, numeric_decimal128)
167 | #endif
168 | DEFINE_CAST(numeric_float80, numeric_complex32)
169 | DEFINE_CAST(numeric_float80, numeric_complex64)
170 | DEFINE_CAST(numeric_float80, numeric_complex80)
171 | DEFINE_CAST(numeric_float80, numeric_complex128)
172 |
173 | // float128
174 | DEFINE_CAST(numeric_float128, numeric_int128)
175 | DEFINE_CAST(numeric_float128, numeric_uint128)
176 | DEFINE_CAST(numeric_float128, numeric_float80)
177 | #ifdef __STDC_DEC_FP__
178 | DEFINE_CAST(numeric_float128, numeric_decimal32)
179 | DEFINE_CAST(numeric_float128, numeric_decimal64)
180 | DEFINE_CAST(numeric_float128, numeric_decimal128)
181 | #endif
182 | DEFINE_CAST(numeric_float128, numeric_complex32)
183 | DEFINE_CAST(numeric_float128, numeric_complex64)
184 | DEFINE_CAST(numeric_float128, numeric_complex80)
185 | DEFINE_CAST(numeric_float128, numeric_complex128)
186 |
187 | // complex32
188 | DEFINE_CAST(numeric_complex32, numeric_int128)
189 | DEFINE_CAST(numeric_complex32, numeric_uint128)
190 | DEFINE_CAST(numeric_complex32, numeric_float80)
191 | DEFINE_CAST(numeric_complex32, numeric_float128)
192 | #ifdef __STDC_DEC_FP__
193 | DEFINE_CAST(numeric_complex32, numeric_decimal32)
194 | DEFINE_CAST(numeric_complex32, numeric_decimal64)
195 | DEFINE_CAST(numeric_complex32, numeric_decimal128)
196 | #endif
197 | DEFINE_CAST(numeric_complex32, numeric_complex64)
198 | DEFINE_CAST(numeric_complex32, numeric_complex80)
199 | DEFINE_CAST(numeric_complex32, numeric_complex128)
200 |
201 | // complex64
202 | DEFINE_CAST(numeric_complex64, numeric_int128)
203 | DEFINE_CAST(numeric_complex64, numeric_uint128)
204 | DEFINE_CAST(numeric_complex64, numeric_float80)
205 | DEFINE_CAST(numeric_complex64, numeric_float128)
206 | #ifdef __STDC_DEC_FP__
207 | DEFINE_CAST(numeric_complex64, numeric_decimal32)
208 | DEFINE_CAST(numeric_complex64, numeric_decimal64)
209 | DEFINE_CAST(numeric_complex64, numeric_decimal128)
210 | #endif
211 | DEFINE_CAST(numeric_complex64, numeric_complex32)
212 | DEFINE_CAST(numeric_complex64, numeric_complex80)
213 | DEFINE_CAST(numeric_complex64, numeric_complex128)
214 |
215 | // complex80
216 | DEFINE_CAST(numeric_complex80, numeric_int128)
217 | DEFINE_CAST(numeric_complex80, numeric_uint128)
218 | DEFINE_CAST(numeric_complex80, numeric_float80)
219 | DEFINE_CAST(numeric_complex80, numeric_float128)
220 | #ifdef __STDC_DEC_FP__
221 | DEFINE_CAST(numeric_complex80, numeric_decimal32)
222 | DEFINE_CAST(numeric_complex80, numeric_decimal64)
223 | DEFINE_CAST(numeric_complex80, numeric_decimal128)
224 | #endif
225 | DEFINE_CAST(numeric_complex80, numeric_complex32)
226 | DEFINE_CAST(numeric_complex80, numeric_complex64)
227 | DEFINE_CAST(numeric_complex80, numeric_complex128)
228 |
229 | // complex128
230 | DEFINE_CAST(numeric_complex128, numeric_int128)
231 | DEFINE_CAST(numeric_complex128, numeric_uint128)
232 | DEFINE_CAST(numeric_complex128, numeric_float80)
233 | DEFINE_CAST(numeric_complex128, numeric_float128)
234 | #ifdef __STDC_DEC_FP__
235 | DEFINE_CAST(numeric_complex128, numeric_decimal32)
236 | DEFINE_CAST(numeric_complex128, numeric_decimal64)
237 | DEFINE_CAST(numeric_complex128, numeric_decimal128)
238 | #endif
239 | DEFINE_CAST(numeric_complex128, numeric_complex32)
240 | DEFINE_CAST(numeric_complex128, numeric_complex64)
241 | DEFINE_CAST(numeric_complex128, numeric_complex80)
242 |
243 | #define DEFINE_BYTESWAP_TO(from_type,to_type,order,bits) \
244 | static void \
245 | from_type##_to_##to_type (const GValue* src_value, GValue* dest_value) \
246 | { \
247 | dest_value->data[0].v_pointer = g_malloc (sizeof (numeric_float_le)); \
248 | *(gint##bits*) dest_value->data[0].v_pointer = GINT##bits##_TO_##order (src_value->data[0].v_int); \
249 | }
250 |
251 | DEFINE_BYTESWAP_TO (gfloat, numeric_float_le, LE, 32)
252 | DEFINE_BYTESWAP_TO (gfloat, numeric_float_be, BE, 32)
253 | DEFINE_BYTESWAP_TO (gdouble, numeric_double_le, LE, 64)
254 | DEFINE_BYTESWAP_TO (gdouble, numeric_double_be, BE, 64)
255 |
256 | #define DEFINE_BYTESWAP_FROM(from_type,to_type,order,bits) \
257 | static void \
258 | from_type##_to_##to_type (const GValue* src_value, GValue* dest_value) \
259 | { \
260 | dest_value->data[0].v_int = GINT##bits##_FROM_##order (*(guint##bits*) src_value->data[0].v_pointer); \
261 | }
262 |
263 | DEFINE_BYTESWAP_FROM (numeric_float_le, gfloat, LE, 32)
264 | DEFINE_BYTESWAP_FROM (numeric_float_be, gfloat, BE, 32)
265 | DEFINE_BYTESWAP_FROM (numeric_double_le, gdouble, LE, 64)
266 | DEFINE_BYTESWAP_FROM (numeric_double_be, gdouble, BE, 32)
267 |
268 | #define REGISTER_ALL_TRANSFORMS_FROM(from_type_id,from_type) \
269 | g_value_register_transform_func (from_type_id, G_TYPE_CHAR, from_type##_to_gchar); \
270 | g_value_register_transform_func (from_type_id, G_TYPE_UCHAR, from_type##_to_guchar); \
271 | g_value_register_transform_func (from_type_id, G_TYPE_INT, from_type##_to_gint); \
272 | g_value_register_transform_func (from_type_id, G_TYPE_UINT, from_type##_to_guint); \
273 | g_value_register_transform_func (from_type_id, G_TYPE_INT64, from_type##_to_gint64); \
274 | g_value_register_transform_func (from_type_id, G_TYPE_UINT64, from_type##_to_guint64); \
275 | g_value_register_transform_func (from_type_id, G_TYPE_LONG, from_type##_to_glong); \
276 | g_value_register_transform_func (from_type_id, G_TYPE_ULONG, from_type##_to_gulong); \
277 | g_value_register_transform_func (from_type_id, G_TYPE_FLOAT, from_type##_to_gfloat); \
278 | g_value_register_transform_func (from_type_id, G_TYPE_DOUBLE, from_type##_to_gdouble); \
279 | g_value_register_transform_func (from_type_id, NUMERIC_TYPE_INT128, from_type##_to_numeric_int128); \
280 | g_value_register_transform_func (from_type_id, NUMERIC_TYPE_UINT128, from_type##_to_numeric_uint128); \
281 | g_value_register_transform_func (from_type_id, NUMERIC_TYPE_FLOAT80, from_type##_to_numeric_float80); \
282 | g_value_register_transform_func (from_type_id, NUMERIC_TYPE_FLOAT128, from_type##_to_numeric_float128); \
283 | g_value_register_transform_func (from_type_id, NUMERIC_TYPE_COMPLEX32, from_type##_to_numeric_complex32); \
284 | g_value_register_transform_func (from_type_id, NUMERIC_TYPE_COMPLEX64, from_type##_to_numeric_complex64); \
285 | g_value_register_transform_func (from_type_id, NUMERIC_TYPE_COMPLEX80, from_type##_to_numeric_complex80); \
286 | g_value_register_transform_func (from_type_id, NUMERIC_TYPE_COMPLEX128, from_type##_to_numeric_complex128);
287 |
288 | #define REGISTER_ALL_TRANSFORMS_TO(to_type_id,to_type) \
289 | g_value_register_transform_func (G_TYPE_CHAR, to_type_id, gchar_to_##to_type); \
290 | g_value_register_transform_func (G_TYPE_UCHAR, to_type_id, guchar_to_##to_type); \
291 | g_value_register_transform_func (G_TYPE_INT, to_type_id, gint_to_##to_type); \
292 | g_value_register_transform_func (G_TYPE_UINT, to_type_id, guint_to_##to_type); \
293 | g_value_register_transform_func (G_TYPE_LONG, to_type_id, glong_to_##to_type); \
294 | g_value_register_transform_func (G_TYPE_ULONG, to_type_id, gulong_to_##to_type); \
295 | g_value_register_transform_func (G_TYPE_INT64, to_type_id, gint64_to_##to_type); \
296 | g_value_register_transform_func (G_TYPE_UINT64, to_type_id, guint64_to_##to_type); \
297 | g_value_register_transform_func (G_TYPE_FLOAT, to_type_id, gfloat_to_##to_type); \
298 | g_value_register_transform_func (G_TYPE_DOUBLE, to_type_id, gdouble_to_##to_type); \
299 | g_value_register_transform_func (NUMERIC_TYPE_INT128, to_type_id, numeric_int128_to_##to_type); \
300 | g_value_register_transform_func (NUMERIC_TYPE_UINT128, to_type_id, numeric_uint128_to_##to_type); \
301 | g_value_register_transform_func (NUMERIC_TYPE_FLOAT80, to_type_id, numeric_float80_to_##to_type); \
302 | g_value_register_transform_func (NUMERIC_TYPE_FLOAT128, to_type_id, numeric_float128_to_##to_type); \
303 | g_value_register_transform_func (NUMERIC_TYPE_COMPLEX32, to_type_id, numeric_complex32_to_##to_type); \
304 | g_value_register_transform_func (NUMERIC_TYPE_COMPLEX64, to_type_id, numeric_complex64_to_##to_type); \
305 | g_value_register_transform_func (NUMERIC_TYPE_COMPLEX80, to_type_id, numeric_complex80_to_##to_type); \
306 | g_value_register_transform_func (NUMERIC_TYPE_COMPLEX128, to_type_id, numeric_complex128_to_##to_type);
307 |
308 | #define REGISTER_ALL_TRANSFORMS(type_id,type) \
309 | REGISTER_ALL_TRANSFORMS_FROM (type_id, type) \
310 | REGISTER_ALL_TRANSFORMS_TO (type_id, type)
311 |
312 | __attribute__ ((constructor))
313 | static void
314 | numeric_transforms_init (void)
315 | {
316 | REGISTER_ALL_TRANSFORMS (NUMERIC_TYPE_INT128, numeric_int128)
317 | REGISTER_ALL_TRANSFORMS (NUMERIC_TYPE_UINT128, numeric_uint128)
318 | REGISTER_ALL_TRANSFORMS (NUMERIC_TYPE_FLOAT80, numeric_float80)
319 | REGISTER_ALL_TRANSFORMS (NUMERIC_TYPE_FLOAT128, numeric_float128)
320 | #ifdef __STDC_DEC_FP__
321 | REGISTER_ALL_TRANSFORMS (NUMERIC_TYPE_DECIMAL32, numeric_decimal32)
322 | REGISTER_ALL_TRANSFORMS (NUMERIC_TYPE_DECIMAL64, numeric_decimal64)
323 | REGISTER_ALL_TRANSFORMS (NUMERIC_TYPE_DECIMAL128, numeric_decimal128)
324 | #endif
325 | REGISTER_ALL_TRANSFORMS (NUMERIC_TYPE_COMPLEX32, numeric_complex32)
326 | REGISTER_ALL_TRANSFORMS (NUMERIC_TYPE_COMPLEX64, numeric_complex64)
327 | REGISTER_ALL_TRANSFORMS (NUMERIC_TYPE_COMPLEX80, numeric_complex80)
328 | REGISTER_ALL_TRANSFORMS (NUMERIC_TYPE_COMPLEX128, numeric_complex128)
329 |
330 | // byteswaps
331 | g_value_register_transform_func (G_TYPE_FLOAT, NUMERIC_TYPE_FLOAT_LE, gfloat_to_numeric_float_le);
332 | g_value_register_transform_func (G_TYPE_FLOAT, NUMERIC_TYPE_FLOAT_BE, gfloat_to_numeric_float_be);
333 | g_value_register_transform_func (G_TYPE_DOUBLE, NUMERIC_TYPE_DOUBLE_LE, gdouble_to_numeric_double_le);
334 | g_value_register_transform_func (G_TYPE_DOUBLE, NUMERIC_TYPE_DOUBLE_BE, gdouble_to_numeric_double_be);
335 | g_value_register_transform_func (NUMERIC_TYPE_FLOAT_LE, G_TYPE_FLOAT, numeric_float_le_to_gfloat);
336 | g_value_register_transform_func (NUMERIC_TYPE_FLOAT_BE, G_TYPE_FLOAT, numeric_float_be_to_gfloat);
337 | g_value_register_transform_func (NUMERIC_TYPE_DOUBLE_LE, G_TYPE_DOUBLE, numeric_double_le_to_gdouble);
338 | g_value_register_transform_func (NUMERIC_TYPE_DOUBLE_BE, G_TYPE_DOUBLE, numeric_double_be_to_gdouble);
339 | }
340 |
--------------------------------------------------------------------------------
/src/numeric-types.c:
--------------------------------------------------------------------------------
1 | /* Copyright 2016 Guillaume Poirier-Morency
2 | *
3 | * This file is part of Numeric-GLib.
4 | *
5 | * Numeric-GLib is free software: you can redistribute it and/or modify it under
6 | * the terms of the GNU Lesser General Public License as published by the Free
7 | * Software Foundation, either version 3 of the License, or (at your option) any
8 | * later version.
9 | *
10 | * Numeric-GLib is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with Numeric-GLib. If not, see .
17 | */
18 |
19 | #include "numeric-types.h"
20 |
21 | #include
22 | #include
23 |
24 | #define DEFINE_NUMERIC(type) \
25 | G_DEFINE_BOXED_TYPE (numeric_##type, \
26 | numeric_##type, \
27 | numeric_##type##_copy, \
28 | numeric_##type##_free) \
29 | \
30 | numeric_##type * \
31 | numeric_##type##_copy (numeric_##type *num) \
32 | { \
33 | gpointer ptr = g_new (numeric_##type, 1); \
34 | memcpy (ptr, num, sizeof (numeric_##type)); \
35 | return ptr; \
36 | } \
37 | \
38 | void \
39 | numeric_##type##_free (numeric_##type *num) \
40 | { \
41 | g_free (num); \
42 | } \
43 | \
44 | numeric_##type \
45 | numeric_value_get_##type (const GValue *val) \
46 | { \
47 | return *(numeric_##type*)g_value_get_boxed (val); \
48 | } \
49 | \
50 | void \
51 | numeric_value_set_##type (GValue *val, numeric_##type x) \
52 | { \
53 | numeric_##type *ptr = g_new (numeric_##type, 1); \
54 | *ptr = x; \
55 | g_value_set_boxed (val, ptr); \
56 | }
57 |
58 | DEFINE_NUMERIC (int128)
59 | DEFINE_NUMERIC (uint128)
60 | DEFINE_NUMERIC (float80)
61 | DEFINE_NUMERIC (float128)
62 | DEFINE_NUMERIC (decimal32)
63 | DEFINE_NUMERIC (decimal64)
64 | DEFINE_NUMERIC (decimal128)
65 | DEFINE_NUMERIC (complex32)
66 | DEFINE_NUMERIC (complex64)
67 | DEFINE_NUMERIC (complex80)
68 | DEFINE_NUMERIC (complex128)
69 |
70 | #define DEFINE_NUMERIC_WITH_BYTESWAP(type,gtype,stype,routine,order) \
71 | DEFINE_NUMERIC (type) \
72 | numeric_##type \
73 | numeric_##type##_from_##gtype (g##gtype num) \
74 | { \
75 | union { \
76 | stype v_swap; \
77 | numeric_##type v_##type; \
78 | g##gtype v_##gtype; \
79 | } data; \
80 | data.v_##gtype = num; \
81 | data.v_swap = routine##_TO_##order (data.v_swap); \
82 | return data.v_##type; \
83 | } \
84 | \
85 | g##gtype \
86 | numeric_##type##_to_##gtype (numeric_##type num) \
87 | { \
88 | union { \
89 | stype v_swap; \
90 | numeric_##type v_##type; \
91 | g##gtype v_##gtype; \
92 | } data; \
93 | data.v_##type = num; \
94 | data.v_swap = routine##_FROM_##order (data.v_swap); \
95 | return data.v_##gtype; \
96 | }
97 |
98 | DEFINE_NUMERIC_WITH_BYTESWAP (int_le, int, gint, GINT, LE)
99 | DEFINE_NUMERIC_WITH_BYTESWAP (int_be, int, gint, GINT, BE)
100 | DEFINE_NUMERIC_WITH_BYTESWAP (uint_le, uint, guint, GUINT, LE)
101 | DEFINE_NUMERIC_WITH_BYTESWAP (uint_be, uint, guint, GUINT, BE)
102 | DEFINE_NUMERIC_WITH_BYTESWAP (long_le, long, glong, GLONG, LE)
103 | DEFINE_NUMERIC_WITH_BYTESWAP (long_be, long, glong, GLONG, BE)
104 | DEFINE_NUMERIC_WITH_BYTESWAP (ulong_le, ulong, gulong, GLONG, LE)
105 | DEFINE_NUMERIC_WITH_BYTESWAP (ulong_be, ulong, gulong, GLONG, BE)
106 | DEFINE_NUMERIC_WITH_BYTESWAP (int64_le, int64, gint64, GINT64, LE)
107 | DEFINE_NUMERIC_WITH_BYTESWAP (int64_be, int64, gint64, GINT64, BE)
108 | DEFINE_NUMERIC_WITH_BYTESWAP (uint64_le, uint64, guint64, GUINT64, LE)
109 | DEFINE_NUMERIC_WITH_BYTESWAP (uint64_be, uint64, guint64, GUINT64, BE)
110 | DEFINE_NUMERIC_WITH_BYTESWAP (float_le, float, gint32, GINT32, LE)
111 | DEFINE_NUMERIC_WITH_BYTESWAP (float_be, float, gint32, GINT32, BE)
112 | DEFINE_NUMERIC_WITH_BYTESWAP (double_le, double, gint32, GINT64, LE)
113 | DEFINE_NUMERIC_WITH_BYTESWAP (double_be, double, gint32, GINT64, BE)
114 |
--------------------------------------------------------------------------------
/src/numeric-types.h:
--------------------------------------------------------------------------------
1 | /* Copyright 2016 Guillaume Poirier-Morency
2 | *
3 | * This file is part of Numeric-GLib.
4 | *
5 | * Numeric-GLib is free software: you can redistribute it and/or modify it under
6 | * the terms of the GNU Lesser General Public License as published by the Free
7 | * Software Foundation, either version 3 of the License, or (at your option) any
8 | * later version.
9 | *
10 | * Numeric-GLib is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with Numeric-GLib. If not, see .
17 | */
18 |
19 | #if !defined (NUMERIC_INSIDE) && !defined (NUMERIC_COMPILATION)
20 | #error "Only can be included directly."
21 | #endif
22 |
23 | #ifndef NUMERIC_TYPES_H
24 | #define NUMERIC_TYPES_H
25 |
26 | #include
27 | #include
28 |
29 | G_BEGIN_DECLS
30 |
31 | #define DEFINE_NUMERIC_PROTOTYPE(type,ctype) \
32 | typedef ctype numeric_##type; \
33 | GType numeric_##type##_get_type (void) G_GNUC_CONST; \
34 | numeric_##type *numeric_##type##_copy (numeric_##type *num); \
35 | void numeric_##type##_free (numeric_##type *num); \
36 | numeric_##type numeric_value_get_##type (const GValue *val); \
37 | void numeric_value_set_##type (GValue *val, numeric_##type x);
38 |
39 | DEFINE_NUMERIC_PROTOTYPE (int128, __int128)
40 | DEFINE_NUMERIC_PROTOTYPE (uint128, unsigned __int128)
41 | DEFINE_NUMERIC_PROTOTYPE (float80, __float80)
42 | DEFINE_NUMERIC_PROTOTYPE (float128, __float128)
43 | DEFINE_NUMERIC_PROTOTYPE (decimal32, _Decimal32)
44 | DEFINE_NUMERIC_PROTOTYPE (decimal64, _Decimal64)
45 | DEFINE_NUMERIC_PROTOTYPE (decimal128, _Decimal128)
46 | DEFINE_NUMERIC_PROTOTYPE (complex32, float _Complex)
47 | DEFINE_NUMERIC_PROTOTYPE (complex64, double _Complex)
48 | DEFINE_NUMERIC_PROTOTYPE (complex80, long double _Complex)
49 | DEFINE_NUMERIC_PROTOTYPE (complex128, __complex128)
50 |
51 | #define NUMERIC_FLOAT128_FORMAT "Qf"
52 | #define NUMERIC_FLOAT128_MODIFIER "Q"
53 |
54 | #define NUMERIC_DECIMAL32_FORMAT "Hf"
55 | #define NUMERIC_DECIMAL64_FORMAT "Df"
56 | #define NUMERIC_DECIMAL128_FORMAT "DDf"
57 |
58 | #define NUMERIC_DECIMAL32_MODIFIER "H"
59 | #define NUMERIC_DECIMAL64_MODIFIER "D"
60 | #define NUMERIC_DECIMAL128_MODIFIER "DD"
61 |
62 | #define NUMERIC_TYPE_INT128 (numeric_int128_get_type ())
63 | #define NUMERIC_TYPE_UINT128 (numeric_uint128_get_type ())
64 | #define NUMERIC_TYPE_FLOAT80 (numeric_float80_get_type ())
65 | #define NUMERIC_TYPE_FLOAT128 (numeric_float128_get_type ())
66 | #define NUMERIC_TYPE_DECIMAL32 (numeric_decimal32_get_type ())
67 | #define NUMERIC_TYPE_DECIMAL64 (numeric_decimal64_get_type ())
68 | #define NUMERIC_TYPE_DECIMAL128 (numeric_decimal128_get_type ())
69 | #define NUMERIC_TYPE_COMPLEX32 (numeric_complex32_get_type ())
70 | #define NUMERIC_TYPE_COMPLEX64 (numeric_complex64_get_type ())
71 | #define NUMERIC_TYPE_COMPLEX80 (numeric_complex80_get_type ())
72 | #define NUMERIC_TYPE_COMPLEX128 (numeric_complex128_get_type ())
73 |
74 | #define DEFINE_NUMERIC_PROTOTYPE_WITH_BITSWAP(type,ctype,gtype) \
75 | DEFINE_NUMERIC_PROTOTYPE (type, ctype) \
76 | numeric_##type \
77 | numeric_##type##_from_##gtype (g##gtype num); \
78 | \
79 | g##gtype \
80 | numeric_##type##_to_##gtype (numeric_##type num);
81 |
82 | DEFINE_NUMERIC_PROTOTYPE_WITH_BITSWAP (int_le, gint, int)
83 | DEFINE_NUMERIC_PROTOTYPE_WITH_BITSWAP (int_be, gint, int)
84 | DEFINE_NUMERIC_PROTOTYPE_WITH_BITSWAP (uint_le, guint, uint)
85 | DEFINE_NUMERIC_PROTOTYPE_WITH_BITSWAP (uint_be, guint, uint)
86 | DEFINE_NUMERIC_PROTOTYPE_WITH_BITSWAP (long_le, glong, long)
87 | DEFINE_NUMERIC_PROTOTYPE_WITH_BITSWAP (long_be, glong, long)
88 | DEFINE_NUMERIC_PROTOTYPE_WITH_BITSWAP (ulong_le, gulong, ulong)
89 | DEFINE_NUMERIC_PROTOTYPE_WITH_BITSWAP (ulong_be, gulong, ulong)
90 | DEFINE_NUMERIC_PROTOTYPE_WITH_BITSWAP (int64_le, gint64, int64)
91 | DEFINE_NUMERIC_PROTOTYPE_WITH_BITSWAP (int64_be, gint64, int64)
92 | DEFINE_NUMERIC_PROTOTYPE_WITH_BITSWAP (uint64_le, guint64, uint64)
93 | DEFINE_NUMERIC_PROTOTYPE_WITH_BITSWAP (uint64_be, guint64, uint64)
94 | DEFINE_NUMERIC_PROTOTYPE_WITH_BITSWAP (float_le, gfloat, float)
95 | DEFINE_NUMERIC_PROTOTYPE_WITH_BITSWAP (float_be, gfloat, float)
96 | DEFINE_NUMERIC_PROTOTYPE_WITH_BITSWAP (double_le, gdouble, double)
97 | DEFINE_NUMERIC_PROTOTYPE_WITH_BITSWAP (double_be, gdouble, double)
98 |
99 | #define NUMERIC_TYPE_INT_LE (numeric_int_le_get_type ())
100 | #define NUMERIC_TYPE_INT_BE (numeric_int_be_get_type ())
101 | #define NUMERIC_TYPE_UINT_LE (numeric_uint_le_get_type ())
102 | #define NUMERIC_TYPE_UINT_BE (numeric_uint_be_get_type ())
103 | #define NUMERIC_TYPE_LONG_LE (numeric_long_le_get_type ())
104 | #define NUMERIC_TYPE_LONG_BE (numeric_long_be_get_type ())
105 | #define NUMERIC_TYPE_ULONG_LE (numeric_ulong_le_get_type ())
106 | #define NUMERIC_TYPE_ULONG_BE (numeric_ulong_be_get_type ())
107 | #define NUMERIC_TYPE_INT64_LE (numeric_int64_le_get_type ())
108 | #define NUMERIC_TYPE_INT64_BE (numeric_int64_be_get_type ())
109 | #define NUMERIC_TYPE_UINT64_LE (numeric_uint64_le_get_type ())
110 | #define NUMERIC_TYPE_UINT64_BE (numeric_uint64_be_get_type ())
111 | #define NUMERIC_TYPE_FLOAT_LE (numeric_float_le_get_type ())
112 | #define NUMERIC_TYPE_FLOAT_BE (numeric_float_be_get_type ())
113 | #define NUMERIC_TYPE_DOUBLE_LE (numeric_double_le_get_type ())
114 | #define NUMERIC_TYPE_DOUBLE_BE (numeric_double_be_get_type ())
115 |
116 | G_END_DECLS
117 |
118 | #endif
119 |
--------------------------------------------------------------------------------
/src/numeric-vector.c:
--------------------------------------------------------------------------------
1 | /* Copyright 2016 Guillaume Poirier-Morency
2 | *
3 | * This file is part of Numeric-GLib.
4 | *
5 | * Numeric-GLib is free software: you can redistribute it and/or modify it under
6 | * the terms of the GNU Lesser General Public License as published by the Free
7 | * Software Foundation, either version 3 of the License, or (at your option) any
8 | * later version.
9 | *
10 | * Numeric-GLib is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with Numeric-GLib. If not, see .
17 | */
18 |
19 | #include "numeric-vector.h"
20 |
21 | #include
22 |
23 | #define DEFINE_VECTOR(ctype, type, twidth, vsize) \
24 | G_DEFINE_BOXED_TYPE (numeric_##type##_v##vsize, \
25 | numeric_##type##_v##vsize, \
26 | numeric_##type##_v##vsize##_copy, \
27 | numeric_##type##_v##vsize##_free) \
28 | numeric_##type##_v##vsize \
29 | numeric_##type##_v##vsize##_init () \
30 | { \
31 | numeric_##type##_v##vsize _ = {}; \
32 | return _; \
33 | } \
34 | numeric_##type##_v##vsize * \
35 | numeric_##type##_v##vsize##_copy (numeric_##type##_v##vsize *self) \
36 | { \
37 | gpointer ptr = g_malloc (sizeof (numeric_##type##_v##vsize)); \
38 | memcpy (ptr, self, sizeof (numeric_##type##_v##vsize)); \
39 | return ptr; \
40 | } \
41 | void \
42 | numeric_##type##_v##vsize##_free (numeric_##type##_v##vsize *self) \
43 | { \
44 | g_free (self); \
45 | } \
46 | ctype \
47 | numeric_##type##_v##vsize##_get (numeric_##type##_v##vsize *self, \
48 | gsize offset) \
49 | { \
50 | return (*self)[offset]; \
51 | } \
52 | void \
53 | numeric_##type##_v##vsize##_set (numeric_##type##_v##vsize *self, \
54 | gsize offset, \
55 | ctype val) \
56 | { \
57 | (*self)[offset] = val; \
58 | } \
59 | void \
60 | numeric_##type##_v##vsize##_add (const numeric_##type##_v##vsize *x, \
61 | const numeric_##type##_v##vsize *y, \
62 | numeric_##type##_v##vsize *z) \
63 | { \
64 | *z = *x + *y; \
65 | } \
66 | void \
67 | numeric_##type##_v##vsize##_sub (const numeric_##type##_v##vsize *x, \
68 | const numeric_##type##_v##vsize *y, \
69 | numeric_##type##_v##vsize *z) \
70 | { \
71 | *z = *x - *y; \
72 | } \
73 | void \
74 | numeric_##type##_v##vsize##_mul (const numeric_##type##_v##vsize *x, \
75 | const numeric_##type##_v##vsize *y, \
76 | numeric_##type##_v##vsize *z) \
77 | { \
78 | *z = *x * *y; \
79 | } \
80 | void \
81 | numeric_##type##_v##vsize##_div (const numeric_##type##_v##vsize *x, \
82 | const numeric_##type##_v##vsize *y, \
83 | numeric_##type##_v##vsize *z) \
84 | { \
85 | *z = *x / *y; \
86 | } \
87 | void \
88 | numeric_##type##_v##vsize##_neg (const numeric_##type##_v##vsize *x, \
89 | numeric_##type##_v##vsize *z) \
90 | { \
91 | *z = -*x; \
92 | } \
93 | void \
94 | numeric_##type##_v##vsize##_eq (const numeric_##type##_v##vsize *x, \
95 | const numeric_##type##_v##vsize *y, \
96 | numeric_##type##_v##vsize *z) \
97 | { \
98 | *z = *x == *y; \
99 | } \
100 | void \
101 | numeric_##type##_v##vsize##_ne (const numeric_##type##_v##vsize *x, \
102 | const numeric_##type##_v##vsize *y, \
103 | numeric_##type##_v##vsize *z) \
104 | { \
105 | *z = *x != *y; \
106 | } \
107 | void \
108 | numeric_##type##_v##vsize##_lt (const numeric_##type##_v##vsize *x, \
109 | const numeric_##type##_v##vsize *y, \
110 | numeric_##type##_v##vsize *z) \
111 | { \
112 | *z = *x < *y; \
113 | } \
114 | void \
115 | numeric_##type##_v##vsize##_le (const numeric_##type##_v##vsize *x, \
116 | const numeric_##type##_v##vsize *y, \
117 | numeric_##type##_v##vsize *z) \
118 | { \
119 | *z = *x <= *y; \
120 | } \
121 | void \
122 | numeric_##type##_v##vsize##_gt (const numeric_##type##_v##vsize *x, \
123 | const numeric_##type##_v##vsize *y, \
124 | numeric_##type##_v##vsize *z) \
125 | { \
126 | *z = *x <= *y; \
127 | } \
128 | void \
129 | numeric_##type##_v##vsize##_ge (const numeric_##type##_v##vsize *x, \
130 | const numeric_##type##_v##vsize *y, \
131 | numeric_##type##_v##vsize *z) \
132 | { \
133 | *z = *x <= *y; \
134 | } \
135 | void \
136 | numeric_##type##_v##vsize##_shuffle (const numeric_##type##_v##vsize *x, \
137 | const numeric_int##twidth##_v##vsize *mask, \
138 | numeric_##type##_v##vsize *z) \
139 | { \
140 | *z = __builtin_shuffle (*x, *mask); \
141 | } \
142 | void \
143 | numeric_##type##_v##vsize##_shuffle2 (const numeric_##type##_v##vsize *x, \
144 | const numeric_##type##_v##vsize *y, \
145 | const numeric_int##twidth##_v##vsize *mask, \
146 | numeric_##type##_v##vsize *z) \
147 | { \
148 | *z = __builtin_shuffle (*x, *y, *mask); \
149 | }
150 |
151 | #define DEFINE_INT_VECTOR(ctype, type, twidth, vsize) \
152 | DEFINE_VECTOR (ctype, type, twidth, vsize)
153 |
154 | DEFINE_INT_VECTOR (gint8, int8, 8, 2)
155 | DEFINE_INT_VECTOR (gint8, int8, 8, 4)
156 | DEFINE_INT_VECTOR (gint8, int8, 8, 8)
157 | DEFINE_INT_VECTOR (gint8, int8, 8, 16)
158 |
159 | DEFINE_INT_VECTOR (guint8, uint8, 8, 2)
160 | DEFINE_INT_VECTOR (guint8, uint8, 8, 4)
161 | DEFINE_INT_VECTOR (guint8, uint8, 8, 8)
162 | DEFINE_INT_VECTOR (guint8, uint8, 8, 16)
163 |
164 | DEFINE_INT_VECTOR (gint16, int16, 16, 4)
165 | DEFINE_INT_VECTOR (gint16, int16, 16, 8)
166 | DEFINE_INT_VECTOR (gint16, int16, 16, 16)
167 |
168 | DEFINE_INT_VECTOR (guint16, uint16, 16, 4)
169 | DEFINE_INT_VECTOR (guint16, uint16, 16, 8)
170 | DEFINE_INT_VECTOR (guint16, uint16, 16, 16)
171 |
172 | DEFINE_INT_VECTOR (gint32, int32, 32, 4)
173 | DEFINE_INT_VECTOR (gint32, int32, 32, 8)
174 | DEFINE_INT_VECTOR (gint32, int32, 32, 16)
175 |
176 | DEFINE_INT_VECTOR (guint32, uint32, 32, 4)
177 | DEFINE_INT_VECTOR (guint32, uint32, 32, 8)
178 | DEFINE_INT_VECTOR (guint32, uint32, 32, 16)
179 |
180 | DEFINE_INT_VECTOR (gint64, int64, 64, 8)
181 | DEFINE_INT_VECTOR (gint64, int64, 64, 16)
182 |
183 | DEFINE_INT_VECTOR (guint64, uint64, 64, 8)
184 | DEFINE_INT_VECTOR (guint64, uint64, 64, 16)
185 |
186 | DEFINE_VECTOR (gfloat, float, 32, 4)
187 | DEFINE_VECTOR (gfloat, float, 32, 8)
188 | DEFINE_VECTOR (gfloat, float, 32, 16)
189 |
190 | DEFINE_VECTOR (gdouble, double, 64, 8)
191 | DEFINE_VECTOR (gdouble, double, 64, 16)
192 |
--------------------------------------------------------------------------------
/src/numeric-vector.h:
--------------------------------------------------------------------------------
1 | /* Copyright 2016 Guillaume Poirier-Morency
2 | *
3 | * This file is part of Numeric-GLib.
4 | *
5 | * Numeric-GLib is free software: you can redistribute it and/or modify it under
6 | * the terms of the GNU Lesser General Public License as published by the Free
7 | * Software Foundation, either version 3 of the License, or (at your option) any
8 | * later version.
9 | *
10 | * Numeric-GLib is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with Numeric-GLib. If not, see .
17 | */
18 |
19 | #if !defined (NUMERIC_INSIDE) && !defined (NUMERIC_COMPILATION)
20 | #error "Only can be included directly."
21 | #endif
22 |
23 | #ifndef NUMERIC_VECTOR_H
24 | #define NUMERIC_VECTOR_H
25 |
26 | #include
27 |
28 | G_BEGIN_DECLS
29 |
30 | #define DEFINE_VECTOR_PROTOTYPE(ctype, type, twidth, vsize) \
31 | typedef ctype numeric_##type##_v##vsize __attribute__ ((vector_size (vsize))); \
32 | GType numeric_##type##_v##vsize##_get_type (); \
33 | numeric_##type##_v##vsize numeric_##type##_v##vsize##_init (); \
34 | numeric_##type##_v##vsize *numeric_##type##_v##vsize##_copy (numeric_##type##_v##vsize *self); \
35 | void numeric_##type##_v##vsize##_free (numeric_##type##_v##vsize *self); \
36 | void numeric_##type##_v##vsize##_set (numeric_##type##_v##vsize *self, gsize offset, ctype val); \
37 | ctype numeric_##type##_v##vsize##_get (numeric_##type##_v##vsize *self, gsize offset); \
38 | void numeric_##type##_v##vsize##_add (const numeric_##type##_v##vsize *x, const numeric_##type##_v##vsize *y, numeric_##type##_v##vsize *z); \
39 | void numeric_##type##_v##vsize##_sub (const numeric_##type##_v##vsize *x, const numeric_##type##_v##vsize *y, numeric_##type##_v##vsize *z); \
40 | void numeric_##type##_v##vsize##_mul (const numeric_##type##_v##vsize *x, const numeric_##type##_v##vsize *y, numeric_##type##_v##vsize *z); \
41 | void numeric_##type##_v##vsize##_div (const numeric_##type##_v##vsize *x, const numeric_##type##_v##vsize *y, numeric_##type##_v##vsize *z); \
42 | void numeric_##type##_v##vsize##_neg (const numeric_##type##_v##vsize *x, numeric_##type##_v##vsize *z); \
43 | void numeric_##type##_v##vsize##_eq (const numeric_##type##_v##vsize *x, const numeric_##type##_v##vsize *y, numeric_##type##_v##vsize *z); \
44 | void numeric_##type##_v##vsize##_ne (const numeric_##type##_v##vsize *x, const numeric_##type##_v##vsize *y, numeric_##type##_v##vsize *z); \
45 | void numeric_##type##_v##vsize##_lt (const numeric_##type##_v##vsize *x, const numeric_##type##_v##vsize *y, numeric_##type##_v##vsize *z); \
46 | void numeric_##type##_v##vsize##_le (const numeric_##type##_v##vsize *x, const numeric_##type##_v##vsize *y, numeric_##type##_v##vsize *z); \
47 | void numeric_##type##_v##vsize##_gt (const numeric_##type##_v##vsize *x, const numeric_##type##_v##vsize *y, numeric_##type##_v##vsize *z); \
48 | void numeric_##type##_v##vsize##_ge (const numeric_##type##_v##vsize *x, const numeric_##type##_v##vsize *y, numeric_##type##_v##vsize *z); \
49 | void numeric_##type##_v##vsize##_shuffle (const numeric_##type##_v##vsize *x, const numeric_int##twidth##_v##vsize *mask, numeric_##type##_v##vsize *z); \
50 | void numeric_##type##_v##vsize##_shuffle2 (const numeric_##type##_v##vsize *x, const numeric_##type##_v##vsize *y, const numeric_int##twidth##_v##vsize *mask, numeric_##type##_v##vsize *z);
51 |
52 | #define DEFINE_INT_VECTOR_PROTOTYPE(ctype, type, twidth, vsize) \
53 | DEFINE_VECTOR_PROTOTYPE (ctype, type, twidth, vsize) \
54 | void numeric_##type##_v##vsize##_xor (const numeric_##type##_v##vsize *x, const numeric_##type##_v##vsize *y, numeric_##type##_v##vsize *z); \
55 | void numeric_##type##_v##vsize##_or (const numeric_##type##_v##vsize *x, const numeric_##type##_v##vsize *y, numeric_##type##_v##vsize *z); \
56 | void numeric_##type##_v##vsize##_and (const numeric_##type##_v##vsize *x, const numeric_##type##_v##vsize *y, numeric_##type##_v##vsize *z); \
57 | void numeric_##type##_v##vsize##_not (const numeric_##type##_v##vsize *x, numeric_##type##_v##vsize *z); \
58 | void numeric_##type##_v##vsize##_mod (const numeric_##type##_v##vsize *x, const numeric_##type##_v##vsize *y, numeric_##type##_v##vsize *z); \
59 | void numeric_##type##_v##vsize##_lshift (const numeric_##type##_v##vsize *x, const numeric_##type##_v##vsize *y, numeric_##type##_v##vsize *z); \
60 | void numeric_##type##_v##vsize##_rshift (const numeric_##type##_v##vsize *x, const numeric_##type##_v##vsize *y, numeric_##type##_v##vsize *z); \
61 | void numeric_##type##_v##vsize##_rshift (const numeric_##type##_v##vsize *x, const numeric_##type##_v##vsize *y, numeric_##type##_v##vsize *z); \
62 |
63 | DEFINE_INT_VECTOR_PROTOTYPE (gint8, int8, 8, 2);
64 | DEFINE_INT_VECTOR_PROTOTYPE (gint8, int8, 8, 4);
65 | DEFINE_INT_VECTOR_PROTOTYPE (gint8, int8, 8, 8);
66 | DEFINE_INT_VECTOR_PROTOTYPE (gint8, int8, 8, 16);
67 |
68 | DEFINE_INT_VECTOR_PROTOTYPE (guint8, uint8, 8, 2);
69 | DEFINE_INT_VECTOR_PROTOTYPE (guint8, uint8, 8, 4);
70 | DEFINE_INT_VECTOR_PROTOTYPE (guint8, uint8, 8, 8);
71 | DEFINE_INT_VECTOR_PROTOTYPE (guint8, uint8, 8, 16);
72 |
73 | DEFINE_INT_VECTOR_PROTOTYPE (gint16, int16, 16, 4);
74 | DEFINE_INT_VECTOR_PROTOTYPE (gint16, int16, 16, 8);
75 | DEFINE_INT_VECTOR_PROTOTYPE (gint16, int16, 16, 16);
76 |
77 | DEFINE_INT_VECTOR_PROTOTYPE (guint16, uint16, 16, 4);
78 | DEFINE_INT_VECTOR_PROTOTYPE (guint16, uint16, 16, 8);
79 | DEFINE_INT_VECTOR_PROTOTYPE (guint16, uint16, 16, 16);
80 |
81 | DEFINE_INT_VECTOR_PROTOTYPE (gint32, int32, 32, 4);
82 | DEFINE_INT_VECTOR_PROTOTYPE (gint32, int32, 32, 8);
83 | DEFINE_INT_VECTOR_PROTOTYPE (gint32, int32, 32, 16);
84 |
85 | DEFINE_INT_VECTOR_PROTOTYPE (guint32, uint32, 32, 4);
86 | DEFINE_INT_VECTOR_PROTOTYPE (guint32, uint32, 32, 8);
87 | DEFINE_INT_VECTOR_PROTOTYPE (guint32, uint32, 32, 16);
88 |
89 | DEFINE_INT_VECTOR_PROTOTYPE (gint64, int64, 64, 8);
90 | DEFINE_INT_VECTOR_PROTOTYPE (gint64, int64, 64, 16);
91 |
92 | DEFINE_INT_VECTOR_PROTOTYPE (guint64, uint64, 64, 8);
93 | DEFINE_INT_VECTOR_PROTOTYPE (guint64, uint64, 64, 16);
94 |
95 | DEFINE_VECTOR_PROTOTYPE (gfloat, float, 32, 4);
96 | DEFINE_VECTOR_PROTOTYPE (gfloat, float, 32, 8);
97 | DEFINE_VECTOR_PROTOTYPE (gfloat, float, 32, 16);
98 |
99 | DEFINE_VECTOR_PROTOTYPE (gdouble, double, 64, 8);
100 | DEFINE_VECTOR_PROTOTYPE (gdouble, double, 64, 16);
101 |
102 | #define NUMERIC_TYPE_INT32_V16 numeric_int32_v16_get_type ()
103 |
104 | G_END_DECLS
105 |
106 | #endif
107 |
--------------------------------------------------------------------------------
/src/numeric.c:
--------------------------------------------------------------------------------
1 | /* Copyright 2016 Guillaume Poirier-Morency
2 | *
3 | * This file is part of Numeric-GLib.
4 | *
5 | * Numeric-GLib is free software: you can redistribute it and/or modify it under
6 | * the terms of the GNU Lesser General Public License as published by the Free
7 | * Software Foundation, either version 3 of the License, or (at your option) any
8 | * later version.
9 | *
10 | * Numeric-GLib is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with Numeric-GLib. If not, see .
17 | */
18 |
19 | #include "numeric.h"
20 |
--------------------------------------------------------------------------------
/src/numeric.h:
--------------------------------------------------------------------------------
1 | /* Copyright 2016 Guillaume Poirier-Morency
2 | *
3 | * This file is part of Numeric-GLib.
4 | *
5 | * Numeric-GLib is free software: you can redistribute it and/or modify it under
6 | * the terms of the GNU Lesser General Public License as published by the Free
7 | * Software Foundation, either version 3 of the License, or (at your option) any
8 | * later version.
9 | *
10 | * Numeric-GLib is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with Numeric-GLib. If not, see .
17 | */
18 |
19 | #ifndef NUMERIC_H
20 | #define NUMERIC_H
21 |
22 | #define NUMERIC_INSIDE
23 | #include "numeric-types.h"
24 | #include "numeric-vector.h"
25 | #undef NUMERIC_INSIDE
26 |
27 | #endif
28 |
--------------------------------------------------------------------------------
/tests/decimal-c-test.c:
--------------------------------------------------------------------------------
1 | /* Copyright 2016 Guillaume Poirier-Morency
2 | *
3 | * This file is part of Numeric-GLib.
4 | *
5 | * Numeric-GLib is free software: you can redistribute it and/or modify it under
6 | * the terms of the GNU Lesser General Public License as published by the Free
7 | * Software Foundation, either version 3 of the License, or (at your option) any
8 | * later version.
9 | *
10 | * Numeric-GLib is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with Numeric-GLib. If not, see .
17 | */
18 |
19 | #include
20 | #include
21 |
22 | #include
23 |
24 | #include
25 | #include
26 |
27 | #include
28 |
29 | void
30 | test_decimal128 (void)
31 | {
32 | numeric_decimal128 a;
33 |
34 | #if HAVE_LIBDFP
35 | a = strtod128 ("0.1", NULL);
36 | #else
37 | a = 0.1DL;
38 | #endif
39 |
40 | g_assert (a == 0.1DL);
41 | g_assert_cmpfloat (a + a, ==, 0.2DL);
42 |
43 | #if HAVE_LIBDFP
44 | g_autofree gchar *buffer = g_strdup_printf ("%DDf", a);
45 | g_assert_cmpstr (buffer, ==, "0.100000");
46 |
47 | g_assert_cmpfloat (fabsd128 (a), ==, 0.1DL);
48 | #endif
49 | }
50 |
51 | int
52 | main (int argc, char **argv)
53 | {
54 | g_test_init (&argc, &argv, NULL);
55 |
56 | g_test_add_func ("/decimal128", test_decimal128);
57 |
58 | return g_test_run ();
59 | }
60 |
--------------------------------------------------------------------------------
/tests/decimal-test.vala:
--------------------------------------------------------------------------------
1 | /* Copyright 2016 Guillaume Poirier-Morency
2 | *
3 | * This file is part of Numeric-GLib.
4 | *
5 | * Numeric-GLib is free software: you can redistribute it and/or modify it under
6 | * the terms of the GNU Lesser General Public License as published by the Free
7 | * Software Foundation, either version 3 of the License, or (at your option) any
8 | * later version.
9 | *
10 | * Numeric-GLib is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with Numeric-GLib. If not, see .
17 | */
18 |
19 | using GLib;
20 | using Numeric;
21 |
22 | public int main (string[] args)
23 | {
24 | Test.init (ref args);
25 |
26 | Test.add_func ("/decimal32", () => {
27 | var a = decimal32.parse ("0.1");
28 | var b = decimal32.parse ("0.1");
29 | var c = decimal32.parse ("0.1");
30 | var d = decimal32.parse ("-0.3");
31 |
32 | var expected = decimal32.parse ("0.0");
33 |
34 | assert (a + b + c + d == expected);
35 |
36 | assert (decimal32.FORMAT_MODIFIER == "H");
37 | assert (a.to_string () == "0.100000");
38 | assert (expected.to_string () == "0.000000");
39 |
40 | var a_value = GLib.Value (typeof (decimal32));
41 | a_value.set_boxed (&a);
42 | var a_unboxed = (decimal32*) a_value.get_boxed ();
43 | assert (*a_unboxed == decimal32.parse ("0.1"));
44 |
45 | assert (decimal32.INFINITY > 0);
46 | assert (decimal32.NAN != decimal32.NAN);
47 | });
48 |
49 | Test.add_func ("/decimal64", () => {
50 | var a = decimal64.parse ("0.1");
51 | var b = decimal64.parse ("0.1");
52 | var c = decimal64.parse ("0.1");
53 | var d = decimal64.parse ("-0.3");
54 |
55 | var expected = decimal64.parse ("0.0");
56 |
57 | assert (a + b + c + d == expected);
58 |
59 | assert (decimal64.FORMAT_MODIFIER == "D");
60 | assert (a.to_string () == "0.100000");
61 | assert (expected.to_string () == "0.000000");
62 | });
63 |
64 | Test.add_func ("/decimal128", () => {
65 | var a = decimal128.parse ("0.1");
66 | var b = decimal128.parse ("0.1");
67 | var c = decimal128.parse ("0.1");
68 | var d = decimal128.parse ("-0.3");
69 |
70 | var expected = decimal128.parse ("0.0");
71 |
72 | assert (a + b + c + d == expected);
73 |
74 | assert (decimal128.FORMAT_MODIFIER == "DD");
75 | assert (a.to_string () == "0.100000");
76 | assert (expected.to_string () == "0.000000");
77 |
78 | Numeric.Math.expd128 (a);
79 | });
80 |
81 | Test.add_func ("/setround", () => {
82 | assert (Libdfp.getround () == Libdfp.RoundingDirection.TONEAREST);
83 | var orig = Libdfp.setround (Libdfp.RoundingDirection.UPWARD);
84 | assert (Libdfp.getround () == Libdfp.RoundingDirection.UPWARD);
85 | Libdfp.setround (orig);
86 | });
87 |
88 | return Test.run ();
89 | }
90 |
--------------------------------------------------------------------------------
/tests/meson.build:
--------------------------------------------------------------------------------
1 | test('numeric', executable('numeric-test', 'numeric-test.vala',
2 | dependencies: [glib_dep, gobject_dep, numeric_glib_vala_dep, quadmath_dep]))
3 |
4 | if dfp_dep.found()
5 | test('decimal', executable('decimal-test', 'decimal-test.vala',
6 | dependencies: [glib_dep, gobject_dep, numeric_glib_vala_dep, quadmath_dep, dfp_dep]))
7 | test('decimal-c', executable('decimal-c-test', 'decimal-c-test.c',
8 | dependencies: [glib_dep, gobject_dep, numeric_glib_dep, quadmath_dep, dfp_dep]))
9 | endif
10 |
--------------------------------------------------------------------------------
/tests/numeric-test.vala:
--------------------------------------------------------------------------------
1 | /* Copyright 2016 Guillaume Poirier-Morency
2 | *
3 | * This file is part of Numeric-GLib.
4 | *
5 | * Numeric-GLib is free software: you can redistribute it and/or modify it under
6 | * the terms of the GNU Lesser General Public License as published by the Free
7 | * Software Foundation, either version 3 of the License, or (at your option) any
8 | * later version.
9 | *
10 | * Numeric-GLib is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with Numeric-GLib. If not, see .
17 | */
18 |
19 | using GLib;
20 | using Numeric;
21 |
22 | class Foo : Object
23 | {
24 | public float128 bar { get; set; default = float128.parse ("0.1"); }
25 | }
26 |
27 | public int main (string[] args)
28 | {
29 | Test.init (ref args);
30 |
31 | Test.add_func ("/size", () => {
32 | assert (sizeof (int128) == 16);
33 | assert (sizeof (uint128) == 16);
34 |
35 | assert (sizeof (float) == 4);
36 | assert (sizeof (double) == 8);
37 | assert (sizeof (float80) == 16);
38 | assert (sizeof (float128) == 16);
39 |
40 | assert (sizeof (decimal32) == 4);
41 | assert (sizeof (decimal64) == 8);
42 | assert (sizeof (decimal128) == 16);
43 |
44 | assert (sizeof (complex64) == 16);
45 | assert (sizeof (complex80) == 32);
46 | assert (sizeof (complex128) == 32);
47 | });
48 |
49 | Test.add_func ("/float_be", () => {
50 | var a = Value (typeof (float));
51 | a.set_float (5.0f);
52 |
53 | var b = Value (typeof (float_be));
54 | assert (a.transform (ref b));
55 | assert (*(float*) b.get_boxed () != a.get_float ());
56 | var b_val = *(float_be*) b.get_boxed ();
57 | assert (5.0f != b_val);
58 | assert (5.0f == b_val.to_float ());
59 |
60 | var c = Value (typeof (float));
61 | assert (b.transform (ref c));
62 | assert (a.get_float () == c.get_float ());
63 |
64 | var d = float_be.from_float (5.0f);
65 | assert (5.0f != d);
66 | assert (5.0f == d.to_float ());
67 | });
68 |
69 | Test.add_func ("/complex32", () => {
70 | complex32 c = 5.0f + 2.0f * Numeric.Math.I;
71 | assert (c.real () == 5.0f);
72 | assert (c.image () == 2.0f);
73 | });
74 |
75 | Test.add_func ("/complex64", () => {
76 | complex64 c = 5.0 + 2 * Numeric.Math.I;
77 | assert (c.real () == 5.0);
78 | assert (c.image () == 2.0);
79 | });
80 |
81 | Test.add_func ("/complex80", () => {
82 | complex80 c = float80.parse ("5.0") + float80.parse ("2.0") * Numeric.Math.I;
83 | assert (c.real () == float80.parse ("5.0"));
84 | assert (c.image () == float80.parse ("2.0"));
85 | });
86 |
87 | Test.add_func ("/complex128", () => {
88 | complex128 c = float128.parse ("5.0") + float128.parse ("2.0") * Numeric.Math.I;
89 | assert (c.real () == float128.parse ("5.0"));
90 | assert (c.image () == float128.parse ("2.0"));
91 | });
92 |
93 | Test.add_func ("/float128", () => {
94 | float128 f = 12.5;
95 | float128 g = 13.5;
96 | assert (26 == (double) (f + g));
97 | assert (12.5 == (double) f);
98 | assert ("1.096910e+00" == Numeric.Math.log10q (f).to_string ("%Qe"));
99 | assert ("1.189731e+4932" == float128.MAX.to_string ("%Qe"));
100 | assert (12.5 == float128.parse ("12.5"));
101 | });
102 |
103 | Test.add_func ("/transform/identity", () => {
104 | var src_value = Value (typeof (int128));
105 | var dest_value = Value (typeof (int128));
106 |
107 | int128 val = 12;
108 | src_value.set_boxed (&val);
109 |
110 | src_value.transform (ref dest_value);
111 |
112 | assert (src_value.get_boxed () != dest_value.get_boxed ());
113 | assert (12 == *(int128*) dest_value.get_boxed ());
114 | });
115 |
116 | Test.add_func ("/vector", () => {
117 | int32_v16 x = int32_v16 ();
118 | int32_v16 y = int32_v16 ();
119 |
120 | x[0] = 1;
121 | x[1] = 2;
122 | x[2] = 3;
123 | x[3] = 4;
124 |
125 | assert (1 == x[0]);
126 | assert (2 == x[1]);
127 | assert (3 == x[2]);
128 | assert (4 == x[3]);
129 |
130 | y[0] = 1;
131 | y[1] = 2;
132 | y[2] = 3;
133 | y[3] = 4;
134 |
135 | var z = int32_v16.add (x, y);
136 |
137 | assert (2 == z[0]);
138 | assert (4 == z[1]);
139 | assert (6 == z[2]);
140 | assert (8 == z[3]);
141 | });
142 |
143 | Test.add_func ("/vector/boxed", () => {
144 | int32_v16 x = int32_v16 ();
145 |
146 | x[0] = 1;
147 | x[1] = 2;
148 | x[2] = 3;
149 | x[3] = 4;
150 |
151 | var val = Value (typeof (int32_v16));
152 | val.set_boxed (&x);
153 |
154 | int32_v16 y = *(int32_v16*) val.get_boxed ();
155 |
156 | assert (1 == y[0]);
157 | assert (2 == y[1]);
158 | assert (3 == y[2]);
159 | assert (4 == y[3]);
160 | });
161 |
162 | Test.add_func ("/gobject", () => {
163 | var foo = new Foo ();
164 | assert (foo.bar == float128.parse ("0.1"));
165 | foo.bar = 12;
166 | assert (foo.bar == 12);
167 | print (foo.bar.to_string ());
168 | assert (foo.bar.to_string () == "12.000000");
169 | foo.set_property ("bar", float128.parse ("0.2"));
170 | assert (foo.bar == float128.parse ("0.2"));
171 | var ret = Value (typeof (float128));
172 | foo.get_property ("bar", ref ret);
173 | assert ((float128) ret == float128.parse ("0.2"));
174 | });
175 |
176 | return Test.run ();
177 | }
178 |
--------------------------------------------------------------------------------
/vapi/libdfp.vapi:
--------------------------------------------------------------------------------
1 | namespace Libdfp
2 | {
3 | [CCode (cname = "int", cprefix = "FE_DEC_", cheader_filename = "fenv.h")]
4 | public enum RoundingDirection
5 | {
6 | TONEAREST,
7 | TOWARDZERO,
8 | UPWARD,
9 | DOWNWARD,
10 | TONEARESTFROMZERO
11 | }
12 | [CCode (cname = "fe_dec_setround", cheader_filename = "fenv.h")]
13 | public RoundingDirection setround (RoundingDirection rounding_direction);
14 | [CCode (cname = "fe_dec_getround", cheader_filename = "fenv.h")]
15 | public RoundingDirection getround ();
16 | }
17 |
--------------------------------------------------------------------------------