├── 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 | --------------------------------------------------------------------------------