double

Overview

Module with functions and types to work with float values.

Types and Definitions

cDoubleInfo

struct cDoubleInfo
{
   uint8_t sign;
   uint16_t exponent;
   uint64_t mantissa;
};
typedef struct cDoubleInfo cDoubleInfo;

cDoubleInfo represents the three sections of a double value.

Generated

cDoubleSlice

struct cDoubleSlice
{
   int64_t s;
   double const* v;
};
typedef struct cDoubleSlice cDoubleSlice;

Via the macro SLICES_C_ generated struct.

cVarDoubleSlice

struct cVarDoubleSlice
{
   int64_t s;
   double* v;
};
typedef struct cVarDoubleSlice cVarDoubleSlice;

Via the macro SLICES_C_ generated struct.

Functions

overall

cmp_double_c

int cmp_double( double a, double b );

Compares two double values and returns the three possible results:

<0

means that a is less compared to b

0

means that a and b are equal

>0

means that a is greater compared to b

Exampl
#include "clingo/lang/expect.h"
#include "clingo/type/double.h"

int main( void )
{
   init_tap_c_();

   double dbl = 3.14;
   double les = nextafter( dbl, -DBL_MAX );
   double gre = nextafter( dbl, DBL_MAX );

   expect_eq_c_( cmp_double_c( dbl, dbl ) );
   expect_lt_c_( cmp_double_c( les, dbl ) );
   expect_gt_c_( cmp_double_c( gre, dbl ) );

   return finish_tap_c_();
}

double_c_

#define double_c_( Value )

Macro function that casts the Value as double.

double_to_float_c

bool double_to_float_c( double d, float f[static 1] );

Via the macro CONV_C_ implemented function. Returns true if the double value can be represented in a float variable, otherwise false.

Example
#include "clingo/lang/expect.h"
#include "clingo/type/double.h"

TEMP_SLICE_C_(
   test,
   {
      double d;
      bool exp;
   }
)
#define t_( ... ) ((test){__VA_ARGS__})

int main( void )
{
   init_tap_c_();

   testSlice tests = slice_c_( test,
      t_( 1.0, true ),
      t_( 0.5, true ),
      t_( 0.25, true ),
      t_( 0.2, false ),
      t_( 0.125, true ),
      t_( 0.1, false )
   );

   for_each_c_( test const*, t, tests )
   {
      float f;
      bool res = double_to_float_c( t->d, &f );

      tap_descf_c( res == t->exp, "%f", t->d );
   }

   return finish_tap_c_();
}

eq_double_c

#define eq_double_c_( D1, D2 )                                                 \
   eq_double_c( (D1), (D2), DBL_EPSILON )
bool eq_double_c( double d1, double d2, double epsilon );

Returns true if both value are equal if you allow a epsilon range.

Example
#include "clingo/lang/expect.h"
#include "clingo/type/double.h"

int main( void )
{
   init_tap_c_();

   // macro with DBL_EPSILON
   expect_c_( eq_double_c_( 0.1234567890123,
                            0.1234567890123 ) );
   expect_c_( not eq_double_c_( 0.1234567890123,
                                0.1237 ) );

   // function with custom epsilon
   expect_c_( not eq_double_c( 0.1234567890123, 
                               0.1237,
                               0.000001 ) );
   expect_c_( eq_double_c( 0.1234567890123,
                           0.1237,
                           0.1 ) );

   return finish_tap_c_();
}

info

build_double_c

double build_double_c( cDoubleInfo info );

Creates a double from a sign, exponent and mantissa value.

Example
#include "clingo/io/write.h"
#include "clingo/lang/expect.h"
#include "clingo/type/double.h"

TEMP_SLICE_C_(
   test,
   {
      uint8_t s;
      uint16_t e;
      uint64_t m;
      double exp;
   }
)
#define t_( ... ) ((test){__VA_ARGS__})

int main( void )
{
   init_tap_c_();

   testSlice tests = slice_c_( test,
      t_( 1, 0x400, 0x91eb851eb851f, -3.14 )
   );

   for_each_c_( test const*, t, tests )
   {
      cDoubleInfo info = { t->s, t->e, t->m };
      double d = build_double_c( info );

      bool res = ( d == t->exp );

      cRecorder* rec = &recorder_c_( 128 );
      {
         char const* fmt = "{u8:x} / {u16:x} / {u64:x} -> {d}";
         write_c_( rec, fmt, t->s, t->e, t->m, t->exp );
      }
      tap_desc_c( res, turn_into_cstr_c( rec ) );
   }

   return finish_tap_c_();
}

double_info_c

cDoubleInfo double_info_c( double d );

Splits a double into a sign, exponent and mantissa value.

Example
#include "clingo/io/write.h"
#include "clingo/lang/expect.h"
#include "clingo/type/double.h"

TEMP_SLICE_C_(
   test,
   {
      double val;
      uint8_t s;
      uint16_t e;
      uint64_t m;
   }
)
#define t_( ... ) ((test){__VA_ARGS__})

int main( void )
{
   init_tap_c_();

   testSlice tests = slice_c_( test,
      t_( 3.14, 0, 0x400, 0x91eb851eb851f )
   );

   for_each_c_( test const*, t, tests )
   {
      cDoubleInfo info = double_info_c( t->val );

      bool res = true;
      res &= ( info.sign == t->s );
      res &= ( info.exponent == t->e );
      res &= ( info.mantissa == t->m );

      cRecorder* rec = &recorder_c_( 256 );
      {
         char const* fmt = "{d} -> {u8:x} / {u16:x} / {u64:x}";
         write_c_( rec, fmt, t->val, t->s, t->e, t->m );
      }
      tap_descf_c( res, "%s", turn_into_cstr_c( rec ) );
   }

   return finish_tap_c_();
}

swap

swap_double_c

double swap_double_c( double val );

Returns val with a changed byte order.

swap_double_from_c

double swap_double_from_c( double val, c_ByteOrder order );

Changes the byte order of val from a known order to the system order if necessary.

swap_double_to_c

double swap_double_to_c( double val, c_ByteOrder order );

Changes the byte order of val from the system order to a known order if necessary.

pack

pack_double_c

uint64_t pack_double_c( double d );

Packs the bytes of a double in a uint64_t value.

Example
#include "clingo/lang/expect.h"
#include "clingo/type/double.h"
#include "clingo/type/uint64.h" // for build_uint64_c_

int main( void )
{
   init_tap_c_();

   double ordered = 3512700564088504e-318;
   uint64_t expOrdered = build_uint64_c_( 0x01234567, 0x89ABCDEF );
   expect_c_( pack_double_c( ordered ) == expOrdered );

   double min = 5e-324;
   uint64_t expMin = build_uint64_c_( 0x00000000, 0x00000001 );
   expect_c_( pack_double_c( min ) == expMin );

   double max = 1.7976931348623157e308;
   uint64_t expMax = build_uint64_c_( 0x7fefffff, 0xffffffff );
   expect_c_( pack_double_c( max ) == expMax );

   return finish_tap_c_();;
}

unpack_double_c

double unpack_double_c( uint64_t u );

Unpacks a float from the bytes in a uint64_t value.

Example
#include "clingo/lang/expect.h"
#include "clingo/type/double.h"
#include "clingo/type/uint64.h" // for build_uint64_c_

int main( void )
{
   init_tap_c_();

   uint64_t ordered = build_uint64_c_( 0x01234567, 0x89ABCDEF );
   expect_c_( unpack_double_c( ordered ) == 3512700564088504e-318 );

   uint64_t min = build_uint64_c_( 0x00000000, 0x00000001 );
   expect_c_( unpack_double_c( min ) == 5e-324 );

   uint64_t max = build_uint64_c_( 0x7fefffff, 0xffffffff );
   expect_c_( unpack_double_c( max ) == 1.7976931348623157e308 );

   return finish_tap_c_();
}

algo

find_double_c

double const* find_double_c( cDoubleSlice slice, double d );

Via the macro FIND_VAL_C_ implemented function.

max_double_c

double const* max_double_c( cDoubleSlice slice );

Via the macro FIND_MAX_C_ implemented function.

min_double_c

double const* min_double_c( cDoubleSlice slice );

Via the macro FIND_MIN_C_ implemented function.

prod_double_c

bool prod_double_c( cDoubleSlice slice, double res[static 1] );

Builds the product all values in the slice and saves the result in res. Return false if a overflow occures, otherwise true.

sum_double_c

bool sum_double_c( cDoubleSlice slice, double res[static 1] );

Builds the sum of all values in the slice and saves the result in res. Returns false if a overflow occures, otherwise true.