|
|
От: | sergii.p | |
| Дата: | 01.09.23 18:20 | ||
| Оценка: | |||
#include <iostream>
constexpr size_t pow(size_t base, size_t exp, size_t res = 1) {
return exp > 0 ? pow(base, exp - 1, res * base) : res;
}
template<typename T, unsigned N>
class Q {
T value;
public:
Q(T value): value(value) {}
T integral() const { return value >> N; }
T fractional() const { return pow(5, N) * (value & ((1 << N) - 1)); }
};
constexpr size_t leading_zeros(auto v, size_t num) {
return v == 0 ? num : leading_zeros(v / 10, num - 1);
}
template<typename T>
constexpr T remove_trailing_zeros(T v) {
return v % 10 == 0 ? remove_trailing_zeros(v / 10) : v;
}
std::ostream& print_leading_zeros(std::ostream& os, size_t n) {
if(n != 0) {
os << "0";
print_leading_zeros(os, n - 1);
}
return os;
}
template<typename T, unsigned N>
std::ostream& operator<< (std::ostream& os, const Q<T, N>& q)
{
os << static_cast<int>(q.integral()) << ".";
print_leading_zeros(os, leading_zeros(q.fractional(), N));
return os << static_cast<int>(remove_trailing_zeros(q.fractional()));
}
void println(auto v) {
std::cout << v << std::endl;
}
int main(int argc, char *argv[]) {
println(Q<int, 4>(0b101101));
println(Q<int, 4>(0b101000)); // trailng zeros
println(Q<int, 3>(0b101101));
println(Q<int, 4>(0b100001)); // leading zeros
}2.8125
2.5
5.625
2.0625