1%% options 2 3copyright owner = Dirk Krause 4copyright year = 2016-xxxx 5SPDX-License-Identifier: BSD-3-Clause 6 7 8%% header 9 10/** @file dk4maai16.h Operations on int16_t data. 11 12 CRT on Windows: Optional. 13*/ 14 15 16#ifndef DK4CONF_H_INCLUDED 17#if DK4_BUILDING_DKTOOLS4 18#include "dk4conf.h" 19#else 20#include <dktools-4/dk4conf.h> 21#endif 22#endif 23 24#ifndef DK4ERROR_H_INCLUDED 25#if DK4_BUILDING_DKTOOLS4 26#include <libdk4base/dk4error.h> 27#else 28#include <dktools-4/dk4error.h> 29#endif 30#endif 31 32#if DK4_HAVE_STDLIB_H 33#ifndef DK4_STDLIB_H_INCLUDED 34#include <stdlib.h> 35#define DK4_STDLIB_H_INCLUDED 1 36#endif 37#endif 38 39#if DK4_HAVE_SYS_TYPES_H 40#ifndef DK4_SYS_TYPES_H_INCLUDED 41#include <sys/types.h> 42#define DK4_SYS_TYPES_H_INCLUDED 1 43#endif 44#endif 45 46#if DK4_HAVE_STDINT_H 47#ifndef DK4_STDINT_H_INCLUDED 48#include <stdint.h> 49#define DK4_STDINT_H_INCLUDED 1 50#endif 51#endif 52 53#ifndef INT16_MAX 54#define INT16_MAX ((int16_t)32767) 55#endif 56 57#ifndef INT16_MIN 58#define INT16_MIN (((int16_t)(-32767)) - ((int16_t)1)) 59#endif 60 61#ifdef __cplusplus 62extern "C" { 63#endif 64 65/** Addition of int16_t. 66 @param a Left operand. 67 @param b Right operand. 68 @param erp Error report, may be NULL. 69 @return Operation result. 70 71 Error codes: 72 - DK4_E_INVALID_ARGUMENTS<br> 73 if a or b is out of range 74 - DK4_E_MATH_OVERFLOW<br> 75 if a mathematical overfow occured. 76*/ 77int16_t 78dk4ma_int16_t_add(int16_t a, int16_t b, dk4_er_t *erp); 79 80/** Substraction of int16_t. 81 @param a Left operand. 82 @param b Right operand. 83 @param erp Error report, may be NULL. 84 @return Operation result. 85 86 Error codes: 87 - DK4_E_INVALID_ARGUMENTS<br> 88 if a or b is out of range 89 - DK4_E_MATH_OVERFLOW<br> 90 if a mathematical overfow occured. 91*/ 92int16_t 93dk4ma_int16_t_sub(int16_t a, int16_t b, dk4_er_t *erp); 94 95/** Multiplication of int16_t. 96 @param a Left operand. 97 @param b Right operand. 98 @param erp Error report, may be NULL. 99 @return Operation result. 100 101 Error codes: 102 - DK4_E_INVALID_ARGUMENTS<br> 103 if a or b is out of range 104 - DK4_E_MATH_OVERFLOW<br> 105 if a mathematical overfow occured. 106*/ 107int16_t 108dk4ma_int16_t_mul(int16_t a, int16_t b, dk4_er_t *erp); 109 110/** Division of int16_t. 111 @param a Left operand. 112 @param b Right operand. 113 @param erp Error report, may be NULL. 114 @return Operation result. 115 116 Error codes: 117 - DK4_E_INVALID_ARGUMENTS<br> 118 if a or b is out of range 119 - DK4_E_MATH_OVERFLOW<br> 120 if a mathematical overfow occured, 121 - DK4_E_MATH_DIVZERO<br> 122 if b is 0. 123*/ 124int16_t 125dk4ma_int16_t_div(int16_t a, int16_t b, dk4_er_t *erp); 126 127/** Absolute value. 128 @param a Argument. 129 @param erp Error report, may be NULL. 130 @return Absolute value of a. 131 132 Error codes: 133 - DK4_E_INVALID_ARGUMENTS<br> 134 if a or b is out of range 135 - DK4_E_MATH_OVERFLOW<br> 136 if a mathematical overfow occured. 137*/ 138int16_t 139dk4ma_int16_t_abs(int16_t a, dk4_er_t *erp); 140 141/** Convert dk4_im_t value to int16_t. 142 @param i Value to convert. 143 @param erp Error report, may be NULL. 144 @return Conversion result. 145 146 Error codes: DK4_E_MATH_OVERFLOW. 147*/ 148int16_t 149dk4ma_int16_from(dk4_im_t i, dk4_er_t *erp); 150 151/** Convert double to int16_t. 152 @param d Value to convert. 153 @param erp Error report, may be NULL. 154 @return Conversion result. 155 156 Error codes: DK4_E_OVERFLOW. 157*/ 158int16_t 159dk4ma_int16_from_double(double d, dk4_er_t *erp); 160 161#ifdef __cplusplus 162} 163#endif 164 165 166%% module 167 168#include "dk4conf.h" 169#include <libdk4ma/dk4maai16.h> 170 171 172 173$!trace-include 174 175 176 177int16_t 178dk4ma_int16_t_add(int16_t a, int16_t b, dk4_er_t *erp) 179{ 180 if ((0 < a) && (0 < b)) { 181 if ((DK4_I16_MAX - a) < b) { 182 dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW); 183 } 184 } else { 185 if ((0 > a) && (0 > b)) { 186 if (DK4_I16_MIN == a) { 187 dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW); 188 } else { 189 if ((DK4_I16_MIN - a) > b) { 190 dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW); 191 } 192 } 193 } 194 } 195 return ((int16_t)(a + b)); 196} 197 198 199 200int16_t 201dk4ma_int16_t_sub(int16_t a, int16_t b, dk4_er_t *erp) 202{ 203 if ((0 < a) && (0 > b)) { 204 if ((DK4_I16_MAX + b) < a) { 205 dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW); 206 } 207 } else { 208 if ((0 > a) && (0 < b)) { 209 if ((DK4_I16_MIN + b) > a) { 210 dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW); 211 } 212 } 213 } 214 return ((int16_t)(a - b)); 215} 216 217 218 219int16_t 220dk4ma_int16_t_mul(int16_t a, int16_t b, dk4_er_t *erp) 221{ 222 if ((0 != a) && (0 != b)) { 223 if (DK4_I16_MIN == b) { 224 if (1 != a) { 225 dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW); 226 } 227 } else { 228 if (DK4_I16_MIN == a) { 229 if (1 != b) { 230 dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW); 231 } 232 } else { 233 if (0 < a) { 234 if (0 < b) { 235 if ((DK4_I16_MAX / a) < b) { 236 dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW); 237 } 238 } else { 239 if ((DK4_I16_MIN / a) > b) { 240 dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW); 241 } 242 } 243 } else { 244 if (0 < b) { 245 if ((DK4_I16_MIN / b) > a) { 246 dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW); 247 } 248 } else { 249 if ((DK4_I16_MAX / (0 - a)) < (0 - b)) { 250 dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW); 251 } 252 } 253 } 254 } 255 } 256 } 257 return ((int16_t)(a * b)); 258} 259 260 261 262int16_t 263dk4ma_int16_t_div(int16_t a, int16_t b, dk4_er_t *erp) 264{ 265 int16_t back = 0; 266 267 if (0 != b) { 268 if ((DK4_I16_MIN == a) && (-1 == b)) { 269 back = DK4_I16_MAX; 270 dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW); 271 } else { 272 back = (int16_t)(a / b); 273 } 274 } else { 275 if (0 < a) { 276 back = DK4_I16_MAX; 277 } else { 278 if (0 > a) { 279 back = DK4_I16_MIN; 280 } 281 } 282 dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO); 283 } 284 return back; 285} 286 287 288 289int16_t 290dk4ma_int16_t_abs(int16_t a, dk4_er_t *erp) 291{ 292 if (DK4_I16_MIN != a) { 293 if ((int16_t)0 > a) { 294 return ((int16_t)(0 - a)); 295 } else { 296 return a; 297 } 298 } else { 299 dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW); 300 return (DK4_I16_MAX); 301 } 302} 303 304 305 306int16_t 307dk4ma_int16_from(dk4_im_t i, dk4_er_t *erp) 308{ 309 if (((dk4_im_t)(DK4_I16_MAX) < i) || ((dk4_im_t)(DK4_I16_MIN) > i)) { 310 dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW); 311 } 312 return ((int16_t)i); 313} 314 315 316 317int16_t 318dk4ma_int16_from_double(double d, dk4_er_t *erp) 319{ 320 int16_t back = 0; 321 if ((double)(DK4_I16_MIN) > d) { 322 dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW); 323 back = DK4_I16_MIN; 324 } 325 else { 326 if ((double)(DK4_I16_MAX) < d) { 327 dk4error_set_simple_error_code(erp,DK4_E_MATH_OVERFLOW); 328 back = DK4_I16_MAX; 329 } 330 else { 331 back = (int16_t)d; 332 } 333 } 334 return back; 335} 336 337