LINUX.ORG.RU

Сообщения aleksey_tulinov

 

Математика с фиксированной запятой для C++20

Посоны,

Мы тут сделали библиотеку для математики с фиксированной запятой на С++. Вот так работает:

const auto x = fixed::make::p<2>(1, 11);

Это число с двумя десятичными знаками после запятой представляющее 1.11.

const auto y = fixed::make::p<1>(1, 0);

Это число с одним десятичным знаком после запятой, представляющее 1.0.

const auto z = x + y;

Это сумма двух чисел.

А вот это ошибка компиляции:

fixed::make::p<3, uint8_t>((uint8_t)0, 0);

Компилятор видит, что в uint8_t нельзя представить три десятичных знака и выдаёт ошибку.

Если сделать операцию которая увеличивает точность результата, например умножение, так что требуемая точность не может быть представлена, то это тоже будет ошибка компиляции.

Во время выполнения, переполнение тоже контролируется, все операции возвращают std::optional который при переполнении будет пустым.

Библиотека спроектирована так чтобы ни один бит информации ни при каких манипуляциях не терялся бы, либо если бит надо потерять, то это надо сделать явно и число станет неточным, на что тоже есть признак, который можно проверить вызвав fixed::is_accurate(x), и если какие-то биты были потеряны, то функция вернёт false.

Можете посмотреть и покритиковать, всё ли по феншую, может чего-то не хватает или что-то лишнее? Пока что финальная версия на сегодняшний день, но было бы интересно узнать какое-нибудь мнение, или даже полезно. Довольно много строк кода, больше тысячи, но не очень много всего, только четыре операции + две трансформации + утилиты.

Ссылка: https://bitbucket.org/alekseyt/fixed

Более полный пример использования: https://bitbucket.org/alekseyt/fixed/src/master/examples/basic.cpp

Заранее спасибо.

 

aleksey_tulinov
()

Pattern matching для С++20

Посоны, что-то я упоролся по хардкору и стал писать паттерн матчинг для С++20. Пример:

variant<int, string> v = 1+2+3+5+7+11;
const auto pattern = pm::any_of(29, "42");

cout << *match(v,
  // match with pattern although pass (fall through). also create side effect in the middle of matching
  pass(pattern,            [&v] { cout << "How does this work?\n"; v = "42"; })
| pass(pattern,            [&v] { v = R"(I wonder ¯\_(ツ)_/¯)"; }) // match with pattern again, also pass
| with(pm::type(string{}), [&v] { return get<string>(v); }) // match with stored type
| with(__,                 []   { return R"(('・ω・'))"s; })) // catch-all condition (default)
<< endl;

Потом я начал писать концепции и понял, что я ещё даже не начинал упарываться. Но вроде что-то получается и довольно просто реализуется, что меня и смущает. Может я чего-то не понимаю или упустил что-то важное и сделал где-то ошибку которую я не вижу.

Я так почитал пропозал для паттерн матчинга, вроде много чего из фичей есть кроме некоторых вещей, хотя я не до конца понимаю всё, что там написано и зачем оно там.

Я это отложу пока что потому мне это надо осмыслить, но может кто-то из многоуважаемых регистрантов или не менее многоуважаемых анонимусов посмотрит пока на это барахло и что-то посоветует? В код может кто-то глянет, всё ли по феншую? Там не много, меньше 700 строк кода пока что и очень простой дизайн.

Ссылка: https://bitbucket.org/alekseyt/pm

Более полный пример использования: https://bitbucket.org/alekseyt/pm/src/master/examples/example.cpp

И там в тестах всякие guard(), within(), maybe() и т.д. Заранее спасибо.

 

aleksey_tulinov
()

RSS подписка на новые темы