-
Notifications
You must be signed in to change notification settings - Fork 0
/
test.cpp
147 lines (124 loc) · 2.68 KB
/
test.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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
using namespace std;
class BigDecimal {
private:
double mThisNum;
int mDecimalPlaces;
template <typename T>
std::enable_if_t<(std::is_floating_point<T>::value), std::size_t>
countDecimals(T v)
{
std::size_t decs = 0;
v = std::abs(v);
auto floored = v - std::floor(v);
T basefactor = 10;
//epsilon=the smallest difference between 2 numbers that my CPU can 'see'
T __CPUepsilon = std::numeric_limits<T>::epsilon() * floored;
while ((floored > __CPUepsilon && floored < (1 - __CPUepsilon)) && decs < std::numeric_limits<T>::max_digits10)
{
floored = v * basefactor;
floored = floored - std::floor(floored);
basefactor *= 10;
__CPUepsilon = std::numeric_limits<T>::epsilon() * v * basefactor;
decs++;
}
return decs;
}
public:
BigDecimal() {}
BigDecimal(std::string x) {
mThisNum = std::stod(x);
}
BigDecimal(double x) {
mThisNum = x;
}
inline double get() { return mThisNum; }
inline void print() {
cout.precision(countDecimals(mThisNum));
cout << std::fixed << mThisNum << endl;
}
inline std::string toString() {
std::stringstream ss;
cout << std::setprecision(countDecimals(mThisNum)) << std::fixed << mThisNum << endl;
return ss.str();
}
inline BigDecimal operator* (BigDecimal x) {
BigDecimal z(this->mThisNum * x.get());
return z;
}
inline BigDecimal operator+ (BigDecimal x) {
BigDecimal z(this->mThisNum + x.get());
return z;
/*
double c = x.get();
double _atomicDigit;
double _baseDigit = this->mThisNum;
__asm {
mov eax, _baseDigit
mov ecx, c
add eax, ecx
mov _atomicDigit, eax
}*/
/* i bet for linux it would be
__asm__ __volatile__( {
)}
i may need "=r" for GCC and ROS builds
or maybe a shit like
extern "C" int func();
asm(R"(
.globl func
.type func, @function
func:
.cfi_startproc
movl $7, %eax
ret
.cfi_endproc
)");
*/
}
inline BigDecimal operator- (BigDecimal x) {
BigDecimal z(this->mThisNum - x.get());
return z;
}
inline BigDecimal operator/ (BigDecimal x) {
BigDecimal z(this->mThisNum / x.get());
return z;
}
inline bool operator< (BigDecimal x) {
return (mThisNum < x.get());
}
inline bool operator> (BigDecimal x) {
return (mThisNum > x.get());
}
template <typename T>
BigDecimal increaseBy(T v) {
mThisNum += v;
return *this;
}
template <typename T>
BigDecimal decreaseBy(T v) {
mThisNum -= v;
return *this;
}
};
int main()
{
BigDecimal x(34.000000000001);
x = x.increaseBy(2);
x = x.increaseBy(1);
x.print();
cout << x.toString() << endl;
/*
int xx=0;
__asm {
lea ebx, xx
mov ecx, 1
add xx, ecx
}
cout << xx << endl;
*/
return 0;
}