33#include "dccl/logger.h"
35#include "../../numeric.h"
39template <
typename Float,
typename Int>
void check_special_values()
41 using FloatLimits = std::numeric_limits<Float>;
42 using IntLimits = std::numeric_limits<Int>;
44 int16_t exponent = 12345;
49 IntLimits::lowest() + 1);
53 assert(exponent == 0);
57 assert(exponent == 0);
66template <
typename Float>
void check_round_trip(Float val)
72 dccl::dlog.
is(dccl::logger::INFO) && dccl::dlog <<
"round trip " << val <<
" -> " << significand
73 <<
" * 2^" << exponent <<
" -> " << out
79template <
typename Float>
void check_finite_values()
81 using FloatLimits = std::numeric_limits<Float>;
83 check_round_trip<Float>(1.0);
84 check_round_trip<Float>(-1.0);
85 check_round_trip<Float>(0.5);
86 check_round_trip<Float>(-0.5);
87 check_round_trip<Float>(2.0);
88 check_round_trip<Float>(1234.5);
89 check_round_trip<Float>(-1234.5);
91 check_round_trip(FloatLimits::max());
92 check_round_trip(FloatLimits::lowest());
93 check_round_trip(FloatLimits::min());
94 check_round_trip(-FloatLimits::min());
95 check_round_trip(FloatLimits::denorm_min());
96 check_round_trip(-FloatLimits::denorm_min());
97 check_round_trip(FloatLimits::epsilon());
100 int16_t denorm_exp = 0;
101 int16_t denorm_exp2 = 0;
105 assert(neg_denorm == -1);
106 assert(denorm_exp == denorm_exp2);
112 assert(std::ldexp(
static_cast<Float
>(one), one_exp) ==
static_cast<Float
>(1.0));
120 assert(pos_exp == neg_exp);
123template <std::
size_t N> std::bitset<N> bits_of(
unsigned long long value)
125 return std::bitset<N>(value);
128void check_bitset_arithmetic()
130 constexpr std::size_t N = 16;
132 auto one = bits_of<N>(1);
133 dccl::increment(one);
134 assert(one.to_ulong() == 2);
137 auto all_ones = bits_of<N>(0xFFFF);
138 dccl::increment(all_ones);
139 assert(all_ones.to_ulong() == 0);
141 assert(!dccl::is_negative(bits_of<N>(0x7FFF)));
142 assert(dccl::is_negative(bits_of<N>(0x8000)));
144 auto five = bits_of<N>(5);
146 assert(five.to_ulong() == 0xFFFB);
147 assert(dccl::negated(bits_of<N>(0)).to_ulong() == 0);
149 auto acc = bits_of<N>(7);
150 dccl::add_to(acc, bits_of<N>(9));
151 assert(acc.to_ulong() == 16);
153 assert(dccl::sum(bits_of<N>(1000), bits_of<N>(2345)).to_ulong() == 3345);
154 assert(dccl::sum(bits_of<N>(0xFFFF), bits_of<N>(1)).to_ulong() == 0);
155 assert(dccl::difference(bits_of<N>(100), bits_of<N>(58)).to_ulong() == 42);
157 assert(dccl::unsigned_geq(bits_of<N>(5), bits_of<N>(5)));
158 assert(dccl::unsigned_geq(bits_of<N>(6), bits_of<N>(5)));
159 assert(!dccl::unsigned_geq(bits_of<N>(4), bits_of<N>(5)));
161 assert(dccl::unsigned_quotient(bits_of<N>(100), bits_of<N>(10)).to_ulong() == 10);
162 assert(dccl::unsigned_quotient(bits_of<N>(0), bits_of<N>(7)).to_ulong() == 0);
164 assert(dccl::unsigned_quotient(bits_of<N>(7), bits_of<N>(2)).to_ulong() == 4);
165 assert(dccl::unsigned_quotient(bits_of<N>(5), bits_of<N>(2)).to_ulong() == 3);
167 assert(dccl::unsigned_product(bits_of<N>(12), bits_of<N>(12)).to_ulong() == 144);
168 assert(dccl::unsigned_product(bits_of<N>(0), bits_of<N>(9999)).to_ulong() == 0);
170 assert(dccl::unsigned_product(bits_of<N>(0xFFFF), bits_of<N>(0xFFFF)).to_ullong() ==
173 auto shift = bits_of<N>(8);
174 dccl::rounding_shift_right(shift, 2);
175 assert(shift.to_ulong() == 2);
178 auto shift_round = bits_of<N>(6);
179 dccl::rounding_shift_right(shift_round, 2);
180 assert(shift_round.to_ulong() == 2);
182 auto shift_round_up = bits_of<N>(7);
183 dccl::rounding_shift_right(shift_round_up, 2);
184 assert(shift_round_up.to_ulong() == 2);
186 auto shift_round_half = bits_of<N>(3);
187 dccl::rounding_shift_right(shift_round_half, 1);
188 assert(shift_round_half.to_ulong() == 2);
192int main(
int argc,
char* argv[])
194 bool verbose =
false;
195 for (
int i = 1; i < argc; ++i)
197 if (argv[i] && argv[i][0] ==
'-' && argv[i][1] ==
'v' && argv[i][2] ==
'\0')
201 dccl::dlog.
connect(verbose ? dccl::logger::ALL :
dccl::logger::WARN_PLUS, &std::cerr);
203 check_special_values<float, int32_t>();
204 check_special_values<double, int64_t>();
206 check_finite_values<float>();
207 check_finite_values<double>();
209 check_bitset_arithmetic();
211 std::cout <<
"all tests passed" << std::endl;
bool is(logger::Verbosity verbosity, logger::Group group=logger::GENERAL)
Indicates the verbosity of the Logger until the next std::flush or std::endl. The boolean return is u...
void connect(int verbosity_mask, Slot slot)
Connect the output of one or more given verbosities to a slot (function pointer or similar)
Dynamic Compact Control Language namespace.
int32_t decompose_float_format(float val, int16_t &exponent)
float compose_float_format(int32_t significand, int16_t exponent)