Csd 1.1.4; VERSION ${PROJECT_VERSION}
Loading...
Searching...
No Matches
csd.hpp
Go to the documentation of this file.
1
16#pragma once
17
18#include <stdexcept> // for invalid_argument
19#include <string> // for basic_string, operator==, operator<<
20
21#if __cpp_constexpr >= 201304
22# define CONSTEXPR14 constexpr
23#else
24# define CONSTEXPR14 inline
25#endif
26
27namespace csd {
28
32
34 constexpr int MAX_DECIMAL_PLACES = 20;
35
37 constexpr unsigned int MIN_NONZERO_DIGITS = 1;
38
42 class invalid_csd_format : public std::invalid_argument {
43 public:
46 explicit invalid_csd_format(const std::string& message) : std::invalid_argument(message) {}
47 };
48
102 extern auto to_csd(double decimal_value, int places) -> std::string;
103
151 extern auto to_csd_i(int decimal_value) -> std::string;
152
188 extern auto to_csdnnz(double decimal_value, unsigned int nnz) -> std::string;
189
224 extern auto to_csdnnz_i(int decimal_value, unsigned int nnz) -> std::string;
225
241 CONSTEXPR14 auto to_decimal_using_switch(const char* csd) -> double {
242 // Handle integral part using int (bit shifts are faster than FP ops)
243 auto integral = 0;
244 for (; *csd != '.' && *csd != '\0'; ++csd) {
245 switch (*csd) {
246 case '0':
247 integral *= 2;
248 break;
249 case '+':
250 integral = integral * 2 + 1;
251 break;
252 case '-':
253 integral = integral * 2 - 1;
254 break;
255 default:
256 throw std::invalid_argument("Work with 0, +, -, and . only");
257 }
258 }
259 if (*csd == '\0') {
260 return double(integral);
261 }
262 // Handle fractional part
263 auto decimal_value = double(integral);
264 auto scale = 0.5;
265 for (++csd; *csd != '\0'; ++csd) {
266 switch (*csd) {
267 case '0':
268 break;
269 case '+':
270 decimal_value += scale;
271 break;
272 case '-':
273 decimal_value -= scale;
274 break;
275 default:
276 throw std::invalid_argument("Fractional part work with 0, +, and - only");
277 }
278 scale /= 2;
279 }
280 return decimal_value;
281 }
282
307 CONSTEXPR14 auto to_decimal_integral(const char*& csd) -> int {
308 auto decimal_value = 0;
309
310 for (;; ++csd) {
311 auto digit = *csd;
312 if (digit == '0') {
313 decimal_value <<= 1;
314 } else if (digit == '+') {
315 decimal_value = (decimal_value << 1) + 1;
316 } else if (digit == '-') {
317 decimal_value = (decimal_value << 1) - 1;
318 } else if (digit == '.' || digit == '\0') {
319 break;
320 } else {
321 throw std::invalid_argument("Work with 0, +, -, and . only");
322 }
323 }
324
325 return decimal_value;
326 }
327
341 CONSTEXPR14 auto to_decimal_fractional(const char* csd) -> double {
342 auto decimal_value = 0.0;
343 auto scale = 0.5;
344
345 for (++csd;; ++csd) {
346 auto digit = *csd;
347 if (digit == '0') {
348 } else if (digit == '+') {
349 decimal_value += scale;
350 } else if (digit == '-') {
351 decimal_value -= scale;
352 } else if (digit == '\0') {
353 break;
354 } else {
355 throw std::invalid_argument("Fractional part work with 0, +, and - only");
356 }
357 scale /= 2.0;
358 }
359
360 return decimal_value;
361 }
362
401 CONSTEXPR14 auto to_decimal(const char* csd) -> double {
402 auto integral = to_decimal_integral(csd);
403
404 if (*csd == '\0') {
405 return double(integral);
406 }
407
408 auto fractional = to_decimal_fractional(csd);
409 return double(integral) + fractional;
410 }
411
444 CONSTEXPR14 auto to_decimal_i(const char* csd) -> int { return to_decimal_integral(csd); }
446
447} // namespace csd
Exception thrown when invalid CSD characters are encountered.
Definition csd.hpp:42
invalid_csd_format(const std::string &message)
Construct invalid CSD format exception.
Definition csd.hpp:46
#define CONSTEXPR14
Definition csd.hpp:24
CONSTEXPR14 auto to_decimal_i(const char *csd) -> int
Convert CSD string to integer.
Definition csd.hpp:444
constexpr int MAX_DECIMAL_PLACES
Maximum number of decimal places supported by CSD conversion.
Definition csd.hpp:34
CONSTEXPR14 auto to_decimal_using_switch(const char *csd) -> double
Definition csd.hpp:241
CONSTEXPR14 auto to_decimal_integral(const char *&csd) -> int
Convert the integral part of a CSD string to a decimal.
Definition csd.hpp:307
CONSTEXPR14 auto to_decimal(const char *csd) -> double
Convert the CSD string to a decimal.
Definition csd.hpp:401
auto to_csd_i(int decimal_value) -> std::string
auto to_csdnnz_i(int decimal_value, unsigned int nnz) -> std::string
Convert an integer to CSD with limited non-zero digits.
auto to_csdnnz(double decimal_value, unsigned int nnz) -> std::string
Convert a floating-point number to CSD with limited non-zero digits.
auto to_csd(double decimal_value, int places) -> std::string
CONSTEXPR14 auto to_decimal_fractional(const char *csd) -> double
Convert the fractional part of a CSD string to a decimal.
Definition csd.hpp:341
constexpr unsigned int MIN_NONZERO_DIGITS
Minimum value for non-zero digit count in CSDNNZ functions.
Definition csd.hpp:37
Definition csd.hpp:27