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