dynamiC  0.1
Macros | Functions
dynamic_op.c File Reference

Implementation of dynamiC operations module. More...

#include "dynamic.h"

Go to the source code of this file.

Macros

#define max_type(A, B)   (DYN_TYPE(A) > DYN_TYPE(B)) ? DYN_TYPE(A) : DYN_TYPE(B)
 
#define CHECK_COPY_REFERENCE(X1)
 
#define CHECK_NOCOPY_REFERENCE(X2)
 
#define CHECK_REFERENCE(X1, X2)
 

Functions

trilean dyn_op_neg (dyn_c *dyn)
 Negate dynamic value in param dyn. More...
 
trilean dyn_op_add (dyn_c *dyn1, dyn_c *dyn2)
 Add dyn2 to dyn1. More...
 
trilean dyn_op_sub (dyn_c *dyn1, dyn_c *dyn2)
 Subtract dyn2 from dyn1. More...
 
trilean dyn_op_mul (dyn_c *dyn1, dyn_c *dyn2)
 Multiply dyn1 with dyn2. More...
 
trilean dyn_op_div (dyn_c *dyn1, dyn_c *dyn2)
 Divide dyn1 by dyn2. More...
 
trilean dyn_op_mod (dyn_c *dyn1, dyn_c *dyn2)
 dyn1 Modulo dyn2 More...
 
float fast_approx_pow (float x, float p)
 Power function approximation x^y. More...
 
trilean dyn_op_pow (dyn_c *dyn1, dyn_c *dyn2)
 dyn1 to the power of dyn2 More...
 
trilean dyn_get_bool_3 (const dyn_c *dyn)
 Returns the trinary truth value (DYN_TRUE|DYN_FALSE|DYN_NONE) of an element. More...
 
trilean dyn_op_and (dyn_c *dyn1, dyn_c *dyn2)
 Logical (trinary) AND operation. More...
 
trilean dyn_op_or (dyn_c *dyn1, dyn_c *dyn2)
 Logical (trinary) OR operation. More...
 
trilean dyn_op_xor (dyn_c *dyn1, dyn_c *dyn2)
 Logical (trinary) XOR operation. More...
 
trilean dyn_op_not (dyn_c *dyn)
 Logical (trinary) Negation. More...
 
dyn_char dyn_op_cmp (dyn_c *dyn1, dyn_c *dyn2)
 Common compare function for dynamic elements. More...
 
trilean dyn_op_id (dyn_c *dyn1, dyn_c *dyn2)
 Type and Value Equality. More...
 
trilean dyn_op_eq (dyn_c *dyn1, dyn_c *dyn2)
 Relational Equality. More...
 
trilean dyn_op_ne (dyn_c *dyn1, dyn_c *dyn2)
 Relational Not Equal. More...
 
trilean dyn_op_lt (dyn_c *dyn1, dyn_c *dyn2)
 Relational Less Than. More...
 
trilean dyn_op_ge (dyn_c *dyn1, dyn_c *dyn2)
 Relational Greater Than or Equal. More...
 
trilean dyn_op_gt (dyn_c *dyn1, dyn_c *dyn2)
 Relational Greater Than. More...
 
trilean dyn_op_le (dyn_c *dyn1, dyn_c *dyn2)
 Relational Less Than or Equal. More...
 
trilean dyn_op_in (dyn_c *element, dyn_c *container)
 Check if dyn2 is element of dyn1. More...
 
trilean dyn_op_b_not (dyn_c *dyn)
 Binary complement.
 
trilean dyn_op_b_and (dyn_c *dyn1, dyn_c *dyn2)
 Binary AND.
 
trilean dyn_op_b_or (dyn_c *dyn1, dyn_c *dyn2)
 Binary OR.
 
trilean dyn_op_b_xor (dyn_c *dyn1, dyn_c *dyn2)
 Binary XOR.
 
trilean dyn_op_b_shift_l (dyn_c *dyn1, dyn_c *dyn2)
 Binary shift left.
 
trilean dyn_op_b_shift_r (dyn_c *dyn1, dyn_c *dyn2)
 Binary shift right.
 

Detailed Description

Implementation of dynamiC operations module.

Author
André Dietrich
Date
14 December 2016

This project is released under the MIT-License.

Definition in file dynamic_op.c.

Macro Definition Documentation

◆ CHECK_COPY_REFERENCE

#define CHECK_COPY_REFERENCE (   X1)
Value:
if (DYN_TYPE(X1) == REFERENCE2) \
DYN_TYPE(X1) = REFERENCE; \
if(DYN_TYPE(X1) == REFERENCE) \
dyn_copy(X1->data.ref, X1); \
dyn_c* for internal usage only
Definition: dynamic_types.h:73
#define DYN_TYPE(dyn)
Return type value of a dynamic element.
Definition: dynamic.h:40
dyn_c*, explicite reference
Definition: dynamic_types.h:74

Definition at line 19 of file dynamic_op.c.

◆ CHECK_NOCOPY_REFERENCE

#define CHECK_NOCOPY_REFERENCE (   X2)
Value:
X2=X2->data.ref; \
#define DYN_IS_REFERENCE(dyn)
Check if dynamic element is of type REFERENCE.
Definition: dynamic.h:46

Definition at line 25 of file dynamic_op.c.

◆ CHECK_REFERENCE

#define CHECK_REFERENCE (   X1,
  X2 
)
Value:
CHECK_COPY_REFERENCE(X1) \
CHECK_NOCOPY_REFERENCE(X2)

Definition at line 30 of file dynamic_op.c.

Function Documentation

◆ dyn_op_cmp()

dyn_char dyn_op_cmp ( dyn_c dyn1,
dyn_c dyn2 
)

Common compare function for dynamic elements.

Basic compare function for dynamic data dypes, based on the relation between the input parameters, different values are returned, see the list below.

Parameters
dyn1first dynamic parameter
dyn2second dynamic parameter
Return values
0if dyn1 == dyn2
1if dyn1 < dyn2
2if dyn1 > dyn2
3if dyn1 != dyn2
4if not comparable due to different data types (STRING <= SET)

Definition at line 683 of file dynamic_op.c.

Referenced by dyn_op_eq(), dyn_op_gt(), dyn_op_lt(), and dyn_op_ne().

684 {
685  enum{EQ,LT,GT,NEQ,TYPE,MARK};//0,1,2,3,4
686 
687  dyn_c *tmp = DYN_IS_REFERENCE(dyn1) ? dyn1->data.ref : dyn1;
688  dyn_char ret;
689  dyn_c tmp2;
690  DYN_INIT(&tmp2);
691  dyn_ushort i;
692 
693  if(DYN_IS_REFERENCE(dyn2))
694  dyn2=dyn2->data.ref;
695 
696  if (DYN_IS_NONE(tmp) && DYN_IS_NONE(dyn2))
697  goto GOTO_EQ;
698 
699  if (DYN_IS_NONE(tmp) && DYN_NOT_NONE(dyn2))
700  goto GOTO_LT;
701 
702  if (DYN_NOT_NONE(tmp) && DYN_IS_NONE(dyn2))
703  goto GOTO_GT;
704 
705  //this switch has no breaks goto is used to leave to desired return
706  switch (max_type(tmp, dyn2)) {
707  case BOOL:
708  if (dyn_get_bool(tmp) < dyn_get_bool(dyn2))
709  goto GOTO_LT;
710  if (dyn_get_bool(tmp) > dyn_get_bool(dyn2))
711  goto GOTO_GT;
712  goto GOTO_EQ;
713  case INTEGER:
714  if (dyn_get_int(tmp) < dyn_get_int(dyn2))
715  goto GOTO_LT;
716  if (dyn_get_int(tmp) > dyn_get_int(dyn2))
717  goto GOTO_GT;
718  goto GOTO_EQ;
719  case FLOAT:
720  if (dyn_get_float(tmp) < dyn_get_float(dyn2))
721  goto GOTO_LT;
722  if (dyn_get_float(tmp) > dyn_get_float(dyn2))
723  goto GOTO_GT;
724  goto GOTO_EQ;
725  case STRING: {
726  if (DYN_TYPE(tmp) != DYN_TYPE(dyn2))
727  goto GOTO_TYPE;
728  //i = dyn_strcmp(tmp->data.str, dyn2->data.str);
729  //if (i < 0)
730  ret = dyn_strcmp(tmp->data.str, dyn2->data.str);
731  if (ret < 0)
732  goto GOTO_LT;
733  //if (i > 0)
734  if (ret > 0)
735  goto GOTO_GT;
736  goto GOTO_EQ;
737  }
738  case SET: {
739  if (DYN_TYPE(tmp) != DYN_TYPE(dyn2))
740  goto GOTO_TYPE;
741  {
742  dyn_c * lset = NULL;
743  dyn_c * rset;
744  if (DYN_LIST_LEN(tmp) == DYN_LIST_LEN(dyn2)){
745  // list might be EQ
746  ret = EQ;
747  lset = tmp;
748  rset = dyn2;
749  } else if (DYN_LIST_LEN(tmp) < DYN_LIST_LEN(dyn2)) {
750  // list might be EQ
751  ret = LT;
752  lset = tmp;
753  rset = dyn2;
754  } else /*if (DYN_LIST_LEN(tmp) > DYN_LIST_LEN(dyn2)) */{
755  // list might be GT
756  ret = GT;
757  lset = dyn2;
758  rset = tmp;
759  }
760  //check if all elements of lset are in rset
761  //break to NEQ or complete to confirm
762  for (i=0; i<DYN_LIST_LEN(lset); ++i) {
763  dyn_set_ref(&tmp2, DYN_LIST_GET_REF(lset, i));
764  dyn_op_in(&tmp2, rset);
765  if (!dyn_get_bool(&tmp2)){
766  ret = NEQ;
767  break;
768  }
769 
770  }
771  goto GOTO_RET;
772 
773  }
774  //unreachable
775  }
776  case LIST: {
777  if (DYN_TYPE(tmp) != DYN_TYPE(dyn2))
778  goto GOTO_TYPE;
779  if (DYN_LIST_LEN(tmp) < DYN_LIST_LEN(dyn2))
780  goto GOTO_LT;
781  if (DYN_LIST_LEN(tmp) > DYN_LIST_LEN(dyn2))
782  goto GOTO_GT;
783  if (DYN_LIST_LEN(tmp) == DYN_LIST_LEN(dyn2)) {
784  if (DYN_LIST_LEN(tmp) == 0)
785  goto GOTO_EQ;
786 
787  //put marker into return value
788  ret = MARK;
789  for (i=0; i<DYN_LIST_LEN(tmp); ++i) {
790  dyn_set_ref(&tmp2, DYN_LIST_GET_REF(tmp, i));
791  ret = dyn_op_cmp(&tmp2, DYN_LIST_GET_REF(dyn2, i));
792  if (ret != EQ)
793  break;
794  }
795  //reached the end of the for loop
796  goto GOTO_RET;
797  }
798  //unreachable
799  }
800  }
801  //unreachable
802  // break with diffent type (string, list and set)
803  goto GOTO_TYPE;
804 GOTO_TYPE:
805  ret = TYPE;
806  goto GOTO_RET;
807 
808 GOTO_EQ:
809  ret = EQ;
810  goto GOTO_RET;
811 GOTO_LT:
812  ret = LT;
813  goto GOTO_RET;
814 GOTO_GT:
815  ret = GT;
816  goto GOTO_RET;
817 /*
818 GOTO_NEQ:
819  ret = NEQ;
820  goto GOTO_RET;
821 */
822 GOTO_RET:
823  //dyn_set_int(dyn1, ret);
824  return ret;
825 
826 }
dyn_c * ref
reference pointer to dynamic elements
float 32 bit
Definition: dynamic_types.h:65
dyn_float dyn_get_float(const dyn_c *dyn)
Return float value of a dynamic element.
#define DYN_IS_REFERENCE(dyn)
Check if dynamic element is of type REFERENCE.
Definition: dynamic.h:46
#define DYN_LIST_LEN(dyn)
Return list length.
Definition: dynamic.h:123
dyn_int dyn_get_int(const dyn_c *dyn)
Return integer value of a dynamic element.
#define DYN_IS_NONE(dyn)
Check if dynamic element is of type NONE.
Definition: dynamic.h:42
dyn_int i
basic integer
Definition: dynamic_types.h:59
trilean dyn_op_in(dyn_c *element, dyn_c *container)
Check if dyn2 is element of dyn1.
Definition: dynamic_op.c:949
set of type dyn_list
Definition: dynamic_types.h:68
#define DYN_NOT_NONE(dyn)
Check if dynamic element is not of type NONE.
Definition: dynamic.h:44
#define DYN_INIT(dyn)
Mandatory initialization for dynamic elements (NONE)
Definition: dynamic.h:38
#define DYN_LIST_GET_REF(dyn, i)
Return the reference to the ith element within a dynamic list.
Definition: dynamic.h:125
Boolean 0==False, 1==True.
Definition: dynamic_types.h:62
trilean dyn_get_bool(const dyn_c *dyn)
Return boolean value of an dynamic element.
Definition: dynamic.c:241
list of type dyn_list
Definition: dynamic_types.h:67
char dyn_char
Basic 8bit signed integer.
Definition: dynamic_types.h:30
#define DYN_TYPE(dyn)
Return type value of a dynamic element.
Definition: dynamic.h:40
signed integer 32 bit
Definition: dynamic_types.h:64
char*
Definition: dynamic_types.h:66
uint16_t dyn_ushort
16bit unsigned integer
Definition: dynamic_types.h:43
TYPE
Basic data type definitions.
Definition: dynamic_types.h:60
dyn_char dyn_strcmp(dyn_const_str a, dyn_const_str b)
Compares the string a to the string b.
void dyn_set_ref(dyn_c *ref, dyn_c *orig)
Set dynamic element as reference to another dynamic element.
Definition: dynamic.c:149
dyn_char dyn_op_cmp(dyn_c *dyn1, dyn_c *dyn2)
Common compare function for dynamic elements.
Definition: dynamic_op.c:683
dyn_str str
pointer to character-array
Basic container for dynamic data types.
Definition: dynamic_types.h:98

◆ fast_approx_pow()

float fast_approx_pow ( float  x,
float  p 
)

Power function approximation x^y.

This implementation is based on the fastapprox library of Paul Minero.

See also
https://code.google.com/archive/p/fastapprox/
http://www.machinedlearnings.com/2011/06/fast-approximate-logarithm-exponential.html
Parameters
xbase value
yexponential value

approx. float value

Definition at line 417 of file dynamic_op.c.

418 {
419  union { float f;
420  unsigned int i;
421  } vx = { x };
422 
423  union { unsigned int i;
424  float f;
425  } mx = { (vx.i & 0x007FFFFF) | 0x3f000000 };
426 
427  x = vx.i * 1.1920928955078125e-7f
428  - 124.22551499f
429  - 1.498030302f * mx.f
430  - 1.72587999f / (0.3520887068f + mx.f);
431 
432  x *= p;
433 
434  float offset = (x < 0) ? 1.0f : 0.0f;
435  float clipp = (x < -126) ? -126.0f : x;
436  float z = clipp - (int) clipp + offset;
437  mx.i = (unsigned int) ( (1 << 23) * (clipp + 121.2740575f + 27.7280233f / (4.84252568f - z) - 1.49012907f * z) );
438 
439  return mx.f;
440 }
dyn_int i
basic integer
Definition: dynamic_types.h:59
dyn_float f
float value
Definition: dynamic_types.h:60