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
#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.
#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.
#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.
#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.
#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.
#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.
#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.