-
Notifications
You must be signed in to change notification settings - Fork 0
/
truncate.cpp
111 lines (100 loc) · 1.66 KB
/
truncate.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#include "truncate.h"
#include <cassert>
#include <cmath>
/**
* @brief integrale part of a float (floor)
*
* @param x
* @return double
*/
double ipart(double x)
{
return std::floor(x);
}
/**
* @brief Decimal part of a float
*
* @param x
* @return double
*/
double dpart(double x)
{
return x - ipart(x);
}
// tronc un nombre après le bit 2^l
/**
* @brief truncate bits after bit 2^l
*
* @param x number to truncate
* @param l power of lsb to keep
* @return truncated number
*/
double truncinf(double x, int l)
{
double p = pow(2, l);
double y = floor(x / p) * p;
assert(y <= x);
return y;
}
/**
* @brief truncate bits after bit 2^l and add 2^l
*
* @param x number to truncate
* @param l power of lsb to keep
* @return truncated number
*/
double truncsup(double x, int l)
{
return truncinf(x, l) + pow(2, l);
}
I truncInterval(const I& i, int l)
{
return {truncinf(i.lower(), l), truncsup(i.upper(), l)};
}
/**
* @brief Least Common Bit between x and y
*
* @param x
* @param y
* @return int
*/
int lcb(double x, double y)
{
int dn = 0;
while ((ipart(x) == ipart(y)) && (dn > -53)) {
x = dpart(x) * 2;
y = dpart(y) * 2;
dn--;
}
return dn;
}
/**
* @brief Least Common Bit betwwen the boundaries of i
*
* @param i interval
* @return int
*/
int lcb(const I& i)
{
return lcb(i.lower(), i.upper());
}
/**
* @brief Most Significant Bit of abs(x)
*
* @param x
* @return int
*/
int msb(double x)
{
return int(log2(fabs(x))) + 1;
}
/**
* @brief Most Significant Bit
*
* @param i interval
* @return int
*/
int msb(const I& i)
{
return std::max(msb(i.lower()), msb(i.upper()));
}