Skip to content

irkvital/s21_decimal

Repository files navigation

s21_decimal

При старте работы над проектом просим вас постараться хронометрировать время работы над проектом. По завершении работы над проектом просим вас ответить на два вопроса в этом опросе

Реализация собственной библиотеки s21_decimal.h.

Contents

  1. Chapter I
    1.1. Introduction
  2. Chapter II
    2.1. Information
  3. Chapter III
    3.1. Part 1

Chapter I

s21_decimal

Планета Земля, 90 годы

Мировая экономика растёт экспоненциально, биржа увеличивается многократно из года в год, все больше и больше компаний выходят на IPO и их акции начинают котироваться. Число пользователей, количество транзакций, цена, комиссия, проценты, расчёт финансовых технических индикаторов... Важность точности всех этих данных сложно переоценить, а с текущими устаревшими типами данных, которые используются в финансовом секторе, возникают серьёзные проблемы.

Из-за погрешности вычисления в обычном IEEE 754 (float) за год теряются миллионы долларов, которые просто абсорбируются из системы, пропадая навсегда.

Вместе с разрабатываемым протоколом FIX (Financial Information eXchange), который используется для обработки данных при передаче между брокером и биржей, нужен ещё 1 инструмент для передачи и хранения данных.
На очередном собрании:

-- И так, господа, прошу внимания, нашей группе специалистов, которая уже зарекомендовала себя по многим успешным проектам, выдана от правительства задача разработать абсолютно новый тип данных, кодовое название - Decimal. Его задача заключается в том, чтобы позволить на несколько десятилетий на порядки уменьшить погрешность, а в некоторых случаях и убрать ее полностью в финансовых мировых операциях. Нужно описать все необходимые логические и арифметические операции, которые позволили бы быстро и удобно производить нужные вычисления.

- Надо же, неплохой такой у нас заказ появился, и сразу от такого заказчика! Мы должны сохранить этого клиента, это сулит нам в дальнейшем большие контракты, если мы справимся!

-- Да, вы правы, поэтому сразу же надо понять, какие функции нам надо реализовывать... Предложения?

-- Сумма и разность....

-- Умножение и деление...

-- Согласен, но нужно ещё!

- Взятие остатка, операции сравнения и конвертации!

-- Математические округления во все стороны!

-- Да, думаю список уже вполне подходящий, за работу! На все у нас пару дней, не больше, не подведите!

Introduction

В этом проекте Вам предстоит реализовать библиотеку s21_decimal.h на языке программирования Си. Эта библиотека должна добавить возможность работы с типом "decimal", который отсутствует в стандарте языка. Тем не менее, этот тип критически важен для, например, финансовых расчетов, где недопустимы погрешности вычислений, свойственные типам с плавающей точкой. В рамках этого проекта предполагается знакомство с задачами обработки финансовой информации, погружение в вопросы внутреннего представления различных типов данных и закрепление структурного подхода.

Chapter II

Information

Тип Decimal представляет десятичные числа в диапазоне от положительных 79,228,162,514,264,337,593,543,950,335 до отрицательных 79,228,162,514,264,337,593,543,950,335. Значение Decimal по умолчанию равно 0. Decimal подходит для финансовых расчетов, которые требуют большого количества значимых целых и дробных цифр и отсутствия ошибок округления. Этот тип не устраняет необходимость округления. Скорее, сводит к минимуму количество ошибок из-за округления.

Когда результат деления и умножения передается методу округления, результат не страдает от потери точности.

Decimal число - это значение с плавающей точкой, состоящее из знака, числового значения, где каждая цифра находится в диапазоне от 0 до 9, и коэффициента масштабирования, который указывает положение десятичной точки, разделяющей целые и дробные части числового значения.

Двоичное представление Decimal состоит из 1-разрядного знака, 96-разрядного целого числа и коэффициента масштабирования, используемого для деления 96-разрядного целого числа и указания того, какая его часть является десятичной дробью. Коэффициент масштабирования неявно равен числу 10, возведенному в степень в диапазоне от 0 до 28. Следовательно, двоичное представление Decimal имеет вид ((от -2^96 до 2^96) / 10^(от 0 до 28)), где -(2^96-1) равно минимальному значению, а 2^96-1 равно максимальному значению.

Коэффициент масштабирования также может сохранять любые конечные нули в Decimal. Эти конечные нули не влияют на значение в арифметических операциях или операциях сравнения.

Двоичное представление

Двоичное представление Decimal состоит из 1-разрядного знака, 96-разрядного целого числа и коэффициента масштабирования, используемого для деления целого числа и указания того, какая его часть является десятичной дробью. Коэффициент масштабирования неявно равен числу 10, возведенному в степень в диапазоне от 0 до 28.

Decimal число может быть реализовано в виде четырехэлементного массива 32-разрядных целых чисел со знаком (int bits[4];).

bits[0], bits[1], и bits[2] содержат младшие, средние и старшие 32 бита 96-разрядного целого числа соответственно.

bits[3] содержит коэффициент масштабирования и знак, и состоит из следующих частей:

  • Биты от 0 до 15, младшее слово, не используются и должны быть равны нулю.
  • Биты с 16 по 23 должны содержать показатель степени от 0 до 28, который указывает степень 10 для разделения целого числа.
  • Биты с 24 по 30 не используются и должны быть равны нулю.
  • Бит 31 содержит знак; 0 означает положительный, а 1 означает отрицательный.

Обратите внимание, что битовое представление различает отрицательные и положительные нули. Эти значения могут считаться эквивалентными во всех операциях.

Пример:

typedef struct 
{
    int bits[4];
} s21_decimal;

Арифметические операторы

Название оператора Оператор Функция
Сложение + int s21_add(s21_decimal value_1, s21_decimal value_2, s21_decimal *result)
Вычитание - int s21_sub(s21_decimal value_1, s21_decimal value_2, s21_decimal *result)
Умножение * int s21_mul(s21_decimal value_1, s21_decimal value_2, s21_decimal *result)
Деление / int s21_div(s21_decimal value_1, s21_decimal value_2, s21_decimal *result)
Остаток от деления Mod int s21_mod(s21_decimal value_1, s21_decimal value_2, s21_decimal *result)

Функции возвращают код ошибки:

  • 0 - OK
  • 1 - число слишком велико или равно бесконечности
  • 2 - число слишком мало или равно отрицательной бесконечности
  • 3 - деление на 0

Уточнение про числа, не вмещающиеся в мантиссу:

  • При получении чисел, не вмещающихся в мантиссу при арифметических операциях, использовать банковское округление (например, 79,228,162,514,264,337,593,543,950,335 - 0.6 = 79,228,162,514,264,337,593,543,950,334)

Уточнение про операцию mod:

  • Если в результате операции произошло переполнение, то необходимо отбросить дробную часть (например, 70,000,000,000,000,000,000,000,000,000 % 0.001 = 0.000)

Операторы сравнение

Название оператора Оператор Функция
Меньше < int s21_is_less(s21_decimal, s21_decimal)
Меньше или равно <= int s21_is_less_or_equal(s21_decimal, s21_decimal)
Больше > int s21_is_greater(s21_decimal, s21_decimal)
Больше или равно >= int s21_is_greater_or_equal(s21_decimal, s21_decimal)
Равно == int s21_is_equal(s21_decimal, s21_decimal)
Не равно != int s21_is_not_equal(s21_decimal, s21_decimal)

Возвращаемое значение:

  • 0 - FALSE
  • 1 - TRUE

Преобразователи

Преобразователь Функция
Из int int s21_from_int_to_decimal(int src, s21_decimal *dst)
Из float int s21_from_float_to_decimal(float src, s21_decimal *dst)
В int int s21_from_decimal_to_int(s21_decimal src, int *dst)
В float int s21_from_decimal_to_float(s21_decimal src, float *dst)

Возвращаемое значение - код ошибки:

  • 0 - OK
  • 1 - ошибка конвертации

Уточнение про преобразование числа типа float:

  • Если числа слишком малы (0 < |x| < 1e-28), вернуть ошибку и значение, равное 0
  • Если числа слишком велики (|x| > 79,228,162,514,264,337,593,543,950,335) или равны бесконечности, вернуть ошибку
  • При обработке числа с типом float преобразовывать все содержащиеся в нём цифры

Уточнение про преобразование из числа типа decimal в тип int:

  • Если в числе типа decimal есть дробная часть, то её следует отбросить (например, 0.9 преобразуется 0)

Другие функции

Описание Функция
Округляет указанное Decimal число до ближайшего целого числа в сторону отрицательной бесконечности. int s21_floor(s21_decimal value, s21_decimal *result)
Округляет Decimal до ближайшего целого числа. int s21_round(s21_decimal value, s21_decimal *result)
Возвращает целые цифры указанного Decimal числа; любые дробные цифры отбрасываются, включая конечные нули. int s21_truncate(s21_decimal value, s21_decimal *result)
Возвращает результат умножения указанного Decimal на -1. int s21_negate(s21_decimal value, s21_decimal *result)

Возвращаемое значение - код ошибки:

  • 0 - OK
  • 1 - ошибка вычисления

Chapter III

Part 1. Реализация функции библиотеки decimal.h

Необходимо реализовать описанные выше функции библиотеки:

  • Библиотека должна быть разработана на языке Си стандарта C11 с использованием компиятора gcc
  • Код библиотеки должен находиться в папке src в ветке develop
  • Не использовать устаревшие и выведенные из употребления конструкции языка и библиотечные функции. Обращать внимания на пометки legacy и obsolete в официальной документации по языку и используемым библиотекам. Ориентироваться на стандарт POSIX.1-2017
  • Оформить решение как статическую библиотеку (с заголовочным файлом s21_decimal.h)
  • Библиотека должна быть разработана в соответствии с принципами структурного программирования
  • Перед каждой функцией использовать префикс s21_
  • Подготовить полное покрытие unit-тестами функций библиотеки c помощью библиотеки Check
  • Unit-тесты должны покрывать не менее 80% каждой функции
  • Предусмотреть Makefile для сборки библиотеки и тестов (с целями all, clean, test, s21_decimal.a, gcov_report)
  • В цели gcov_report должен формироваться отчёт gcov в виде html страницы. Для этого unit-тесты должны запускаться с флагами gcov
  • При реализации decimal ориентироваться на двоичное представление с целочисленным массивом bits, как указано в примере выше. Соблюсти положение разрядов числа в массиве bits
  • Запрещено использование типа __int128
  • Конечные нули можно как оставлять, так и удалять (за исключением функции s21_truncate)
  • Определяемый тип должен поддерживать числа от -79,228,162,514,264,337,593,543,950,335 до +79,228,162,514,264,337,593,543,950,335.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published