Целые числа

Эффективные методы реализации моделей ИИ

Constantine Korikov
Константин Кориков
PhD, AI Research Engineer
Домашнее задание 15 мин
Целые числа 45 мин
Дробные числа 20 мин

Домашнее задание

Занятие 02

Целые числа

Как считает CPU

Как использовать отрицательные числа?

1) Как кодировать знак: 1 и 0?

2) Как выполнять вычитание?

3) Как представлять нуль?

Прямой код

В прямом коде знак хранится отдельно: старший бит отвечает за знак, а остальные биты — за модуль. Поэтому ноль получается в двух вариантах: 0000 = +0 и 1000 = -0.

Из-за раздельной обработки знака и модуля одного стандартного сумматора мало — обычно нужен дополнительный блок логики.

  0011 = 3
+ 1001 = -1
------
  0010 = 2

Обратный код

В обратном коде отрицательное число получается простой инверсией битов, поэтому арифметика выглядит почти как обычное сложение. Но у нуля снова два состояния: 0000 = +0 и 1111 = -0.

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

  0011 = 3
+ 1110 = -1
------
1 0001 = 1
+    1
------
  0010 = 2

Дополнительный код

В дополнительном коде отрицательные числа задаются как инверсия плюс единица, и это даёт единое представление нуля: только 0000 = +0.

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

  0011 = 3
+ 1111 = -1
------
1 0010 = 2
  0010 = 2

Дробные числа

От целого числа к фиксированной точке

Операция Формула Пример
Кодирование $p, q \in \mathbb{Z},\; q > 0,\; \text{НОД}(|p|,q)=1$ 3/4
↳ Бинарно 2 целых числа 0000 0011 / 0000 0100
Сложение $\dfrac{a}{b} + \dfrac{c}{d} = \dfrac{ad + bc}{bd}$, сократить 1/2 + 1/3 = 5/6
Вычитание $\dfrac{a}{b} - \dfrac{c}{d} = \dfrac{ad - bc}{bd}$, сократить 3/4 − 1/4 = 1/2
Умножение $\dfrac{a}{b} \times \dfrac{c}{d} = \dfrac{ac}{bd}$, сократить 2/3 × 3/4 = 1/2
Деление $\dfrac{a}{b} \div \dfrac{c}{d} = \dfrac{ad}{bc}$, сократить 2/3 ÷ 4/3 = 1/2

$\mathbb{Z} \subset \mathbb{Q} \subset \mathbb{R}$

Операция Формула Пример (Q4.4)
Кодирование $\text{Q}m.n:\; \mathrm{int} = \lfloor x \times 2^n \rfloor,\; x = \mathrm{int} \times 2^{-n}$ ⌊6.75 × 2⁴⌋ = 108 (6.75)
⌊6.7 × 2⁴⌋ = 107 (6.6875)
↳ Бинарно одно целое число 0110 1100 (6.75)
Сложение $\mathrm{int}_a + \mathrm{int}_b$ 24 (1.5) + 12 (0.75) = 36 (2.25)
Вычитание $\mathrm{int}_a - \mathrm{int}_b$ 24 (1.5) − 12 (0.75) = 12 (0.75)
Умножение $(\mathrm{int}_a \times \mathrm{int}_b) / 2^n$ [24 (1.5) × 12 (0.75)] / 2⁴ = 18 (1.125)
Деление $(\mathrm{int}_a \times 2^n) / \mathrm{int}_b$ [24 (1.5) × 2⁴] / 12 (0.75) = 32 (2.0)

$\text{Q}m.n \subset \mathbb{Q} \subset \mathbb{R}$

min: 0 · max: 3.75
шаг: 0.25 · значений: 16
min: 0 · max: 15
шаг: 1 · значений: 16
min: -2 · max: 1.75
шаг: 0.25 · значений: 16
=
min: −2 · max: 1.75
шаг: 0.25 · значений: 16

Закодируем фиксированную точку на ассемблере

Формат: Q4.4, 1 байт на число.

Реализуйте сложение и вычитание двух Q4.4 чисел в регистрах.

Умножение в фиксированной точке

Формат: Q2.2. Реализуйте умножение двух чисел.

А как сделать деление?

Расширение симулятора под float

Предложите архитектуру расширения симулятора для поддержки чисел с плавающей точкой. Опишите формат данных (знак, экспонента, мантисса) и минимальный набор операций.