summaryrefslogtreecommitdiffstats
path: root/libnetdata/storage_number/storage_number.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnetdata/storage_number/storage_number.c')
-rw-r--r--libnetdata/storage_number/storage_number.c71
1 files changed, 33 insertions, 38 deletions
diff --git a/libnetdata/storage_number/storage_number.c b/libnetdata/storage_number/storage_number.c
index ba7a6687..6a8b68c1 100644
--- a/libnetdata/storage_number/storage_number.c
+++ b/libnetdata/storage_number/storage_number.c
@@ -2,12 +2,7 @@
#include "../libnetdata.h"
-#define get_storage_number_flags(value) \
- ((((storage_number)(value)) & (1 << 24)) | \
- (((storage_number)(value)) & (1 << 25)) | \
- (((storage_number)(value)) & (1 << 26)))
-
-storage_number pack_storage_number(calculated_number value, uint32_t flags) {
+storage_number pack_storage_number(NETDATA_DOUBLE value, SN_FLAGS flags) {
// bit 32 = sign 0:positive, 1:negative
// bit 31 = 0:divide, 1:multiply
// bit 30, 29, 28 = (multiplier or divider) 0-7 (8 total)
@@ -16,44 +11,48 @@ storage_number pack_storage_number(calculated_number value, uint32_t flags) {
// bit 25 SN_ANOMALY_BIT = 0: anomalous, 1: not anomalous
// bit 24 to bit 1 = the value
- storage_number r = get_storage_number_flags(flags);
- if(!value)
- goto RET_SN;
+ if(unlikely(fpclassify(value) == FP_NAN || fpclassify(value) == FP_INFINITE))
+ return SN_EMPTY_SLOT;
+
+ storage_number r = flags & SN_USER_FLAGS;
+
+ if(unlikely(fpclassify(value) == FP_ZERO || fpclassify(value) == FP_SUBNORMAL))
+ return r;
int m = 0;
- calculated_number n = value, factor = 10;
+ NETDATA_DOUBLE n = value, factor = 10;
// if the value is negative
// add the sign bit and make it positive
if(n < 0) {
- r += (1 << 31); // the sign bit 32
+ r += SN_FLAG_NEGATIVE; // the sign bit 32
n = -n;
}
if(n / 10000000.0 > 0x00ffffff) {
factor = 100;
- r |= SN_EXISTS_100;
+ r |= SN_FLAG_NOT_EXISTS_MUL100;
}
// make its integer part fit in 0x00ffffff
// by dividing it by 10 up to 7 times
// and increasing the multiplier
- while(m < 7 && n > (calculated_number)0x00ffffff) {
+ while(m < 7 && n > (NETDATA_DOUBLE)0x00ffffff) {
n /= factor;
m++;
}
if(m) {
- // the value was too big and we divided it
- // so we add a multiplier to unpack it
- r += (1 << 30) + (m << 27); // the multiplier m
+ // the value was too big, and we divided it
+ // so, we add a multiplier to unpack it
+ r += SN_FLAG_MULTIPLY + (m << 27); // the multiplier m
- if(n > (calculated_number)0x00ffffff) {
+ if(n > (NETDATA_DOUBLE)0x00ffffff) {
#ifdef NETDATA_INTERNAL_CHECKS
- error("Number " CALCULATED_NUMBER_FORMAT " is too big.", value);
+ error("Number " NETDATA_DOUBLE_FORMAT " is too big.", value);
#endif
r += 0x00ffffff;
- goto RET_SN;
+ return r;
}
}
else {
@@ -62,18 +61,18 @@ storage_number pack_storage_number(calculated_number value, uint32_t flags) {
// while the value is below 0x0019999e we can
// multiply it by 10, up to 7 times, increasing
// the multiplier
- while(m < 7 && n < (calculated_number)0x0019999e) {
+ while(m < 7 && n < (NETDATA_DOUBLE)0x0019999e) {
n *= 10;
m++;
}
- if (unlikely(n > (calculated_number) (0x00ffffff))) {
+ if (unlikely(n > (NETDATA_DOUBLE)0x00ffffff)) {
n /= 10;
m--;
}
- // the value was small enough and we multiplied it
- // so we add a divider to unpack it
- r += (0 << 30) + (m << 27); // the divider m
+ // the value was small enough, and we multiplied it
+ // so, we add a divider to unpack it
+ r += (m << 27); // the divider m
}
#ifdef STORAGE_WITH_MATH
@@ -84,15 +83,11 @@ storage_number pack_storage_number(calculated_number value, uint32_t flags) {
r += (storage_number)n;
#endif
-RET_SN:
- if (r == SN_EMPTY_SLOT)
- r = SN_ANOMALOUS_ZERO;
-
return r;
}
// Lookup table to make storage number unpacking efficient.
-calculated_number unpack_storage_number_lut10x[4 * 8];
+NETDATA_DOUBLE unpack_storage_number_lut10x[4 * 8];
__attribute__((constructor)) void initialize_lut(void) {
// The lookup table is partitioned in 4 subtables based on the
@@ -109,7 +104,7 @@ __attribute__((constructor)) void initialize_lut(void) {
}
/*
-int print_calculated_number(char *str, calculated_number value)
+int print_netdata_double(char *str, NETDATA_DOUBLE value)
{
char *wstr = str;
@@ -119,9 +114,9 @@ int print_calculated_number(char *str, calculated_number value)
#ifdef STORAGE_WITH_MATH
// without llrintl() there are rounding problems
// for example 0.9 becomes 0.89
- unsigned long long uvalue = (unsigned long long int) llrintl(value * (calculated_number)100000);
+ unsigned long long uvalue = (unsigned long long int) llrintl(value * (NETDATA_DOUBLE)100000);
#else
- unsigned long long uvalue = value * (calculated_number)100000;
+ unsigned long long uvalue = value * (NETDATA_DOUBLE)100000;
#endif
wstr = print_number_llu_r_smart(str, uvalue);
@@ -165,8 +160,8 @@ int print_calculated_number(char *str, calculated_number value)
}
*/
-int print_calculated_number(char *str, calculated_number value) {
- // info("printing number " CALCULATED_NUMBER_FORMAT, value);
+int print_netdata_double(char *str, NETDATA_DOUBLE value) {
+ // info("printing number " NETDATA_DOUBLE_FORMAT, value);
char integral_str[50], fractional_str[50];
char *wstr = str;
@@ -176,22 +171,22 @@ int print_calculated_number(char *str, calculated_number value) {
value = -value;
}
- calculated_number integral, fractional;
+ NETDATA_DOUBLE integral, fractional;
#ifdef STORAGE_WITH_MATH
- fractional = calculated_number_modf(value, &integral) * 10000000.0;
+ fractional = modfndd(value, &integral) * 10000000.0;
#else
fractional = ((unsigned long long)(value * 10000000ULL) % 10000000ULL);
#endif
unsigned long long integral_int = (unsigned long long)integral;
- unsigned long long fractional_int = (unsigned long long)calculated_number_llrint(fractional);
+ unsigned long long fractional_int = (unsigned long long)llrintndd(fractional);
if(unlikely(fractional_int >= 10000000)) {
integral_int += 1;
fractional_int -= 10000000;
}
- // info("integral " CALCULATED_NUMBER_FORMAT " (%llu), fractional " CALCULATED_NUMBER_FORMAT " (%llu)", integral, integral_int, fractional, fractional_int);
+ // info("integral " NETDATA_DOUBLE_FORMAT " (%llu), fractional " NETDATA_DOUBLE_FORMAT " (%llu)", integral, integral_int, fractional, fractional_int);
char *istre;
if(unlikely(integral_int == 0)) {