]> arthur.barton.de Git - netdata.git/blob - src/storage_number.c
math library optional
[netdata.git] / src / storage_number.c
1 #ifdef STORAGE_WITH_MATH
2 #include <math.h>
3 #endif
4
5 #include "log.h"
6 #include "storage_number.h"
7
8 storage_number pack_storage_number(calculated_number value)
9 {
10         storage_number r = 0;
11         if(!value) return r;
12
13         // bit 32 = sign
14         // bit 31 = 0:divide, 1:multiply
15         // bit 30, 29, 28 = (multiplier or divider) 0-7
16         // bit 27 to 25 = reserved for flags
17         // bit 24 to bit 1 = the value
18
19         storage_number sign = 0, exp = 0, mul;
20         int m = 0;
21         calculated_number n = value;
22
23         if(n < 0) {
24                 sign = 1;
25                 n = -n;
26         }
27
28         while(m < 7 && n > (calculated_number)0x00ffffff) {
29                 n /= 10;
30                 m++;
31         }
32         while(m > -7 && n < (calculated_number)0x00199999) {
33                 n *= 10;
34                 m--;
35         }
36
37         if(m <= 0) {
38                 exp = 0;
39                 m = -m;
40         }
41         else exp = 1;
42
43         if(n > (calculated_number)0x00ffffff) {
44                 error("Number " CALCULATED_NUMBER_FORMAT " is too big.", value);
45                 n = (calculated_number)0x00ffffff;
46         }
47
48         mul = m;
49
50 #ifdef STORAGE_WITH_MATH
51         // without this there are rounding problems
52         // example: 0.9 becomes 0.89
53         n = lrint(n);
54 #endif
55
56         r = (sign << 31) + (exp << 30) + (mul << 27) + n;
57         // fprintf(stderr, "PACK: %08X, sign = %d, exp = %d, mul = %d, n = " CALCULATED_NUMBER_FORMAT "\n", r, sign, exp, mul, n);
58
59         return r;
60 }
61
62 calculated_number unpack_storage_number(storage_number value)
63 {
64         if(!value) return 0;
65
66         int sign = 0;
67         int exp = 0;
68
69         if(value & (1 << 31)) {
70                 sign = 1;
71                 value ^= 1 << 31;
72         }
73
74         if(value & (1 << 30)) {
75                 exp = 1;
76                 value ^= 1 << 30;
77         }
78
79         int mul = value >> 27;
80         value ^= mul << 27;
81
82         calculated_number n = value;
83
84         // fprintf(stderr, "UNPACK: %08X, sign = %d, exp = %d, mul = %d, n = " CALCULATED_NUMBER_FORMAT "\n", value, sign, exp, mul, n);
85
86         while(mul > 0) {
87                 if(exp) n *= 10;
88                 else n /= 10;
89                 mul--;
90         }
91
92         if(sign) n = -n;
93         return n;
94 }