====== Типы данных ====== ===== Целочисленные типы ===== * long или int - 32-битное целочисленное со знаком; * unsigned long или unsigned int (или просто unsigned) - 32-битное целочисленное без знака; * short - 16-битное целочисленное со знаком. В документации иногда называется half-word; * unsigned short - 16-битное целочисленное без знака. ===== Fixed-point типы ===== PlayStation не имеет FPU (только программная эмуляция), поэтому все вычисления с вещественными числами рекомендуется делать в fixed-point. Это также важно для совместимости с [[GTE]]. Представление вещественного числа с фиксированной запятой по сути представляет собой целочисленное, которое неявно умножается на фиксированный коэффициент масштаба (scaling factor). Например, число 1.23 можно хранить в виде целого 1230, неявно умноженного на коэффициент масштаба 1/1000. Отсюда понятие фиксированной запятой - после запятой такое число всегда имеет одно и то же количество цифр. На практике коэффициент масштаба зависит от количества бит, выделяемых под дробную часть, поэтому он кратен степени двойки. Например, если дробная часть занимает 12 бит, то коэффициент масштаба равен 1/2^12. Соответственно, число 1.0 в таком представлении соответствует целому 65536. На первый взгляд, неудобно, но если записывать в шестнадцатеричном виде, то все просто: 1.0 = 0x1000, 2.0 = 0x2000 и т.д. Знак числа всегда записывается как старший бит. 1 = отрицательное число, 0 = положительное число. Затем всегда идут биты целой части, за ними - биты дробной части. Благодаря такому представлению fixed-point числа можно складывать и вычитать как обычные целые. На PlayStation наиболее распространенные форматы чисел следующие: * 16-битный Q3.12 - 1 бит знак, 3 бит целая часть, 12 бит дробная часть. Коэффициент масштаба 1/2^12 (1.0 = 2^12 = 0x1000). Предназначен для представления наиболее маленьких чисел. Например, в этом формате задаются элементы матриц GTE; * 16-битный Q7.8 - 1 бит знак, 7 бит целая часть, 8 бит дробная часть. Коэффициент масштаба 1/2^8 (1.0 = 2^8 = 0x100); * 32-битный Q15.16 - 1 бит знак, 15 бит целая часть, 16 бит дробная часть. Коэффициент масштаба 1/2^16 (1.0 = 2^16 = 0x10000). В этом формате чаще всего задаются координаты в экранном пространстве. ==== Сложение и вычитание ==== Как уже было отмечено, сложение и вычитание чисел с фиксированной запятой - это обычные целочисленные сложение и вычитание. ==== Умножение ==== Если форматы множителей совпадают, то умножение делается по следующему правилу: (X/2^n) * (Y/2^n) = (X * Y)/(2^2n) Как следует из формулы, при умножении формат числа меняется. Чтобы вернуться обратно в формат множителей, нужно результат сдвинуть вправо на число бит дробной части. Например: X/2^16 * Y/2^16 = (X * Y)/2^32 Чтобы результат снова привести к масштабу 1/2^16, нужно домножить на 2^16, т.е. сдвинуть на 16 бит вправо: R = (X * Y) >> n Программы для PlayStation в основном оперируют 16-битными числами. Это связано с тем, что за одну операцию можно загрузить в регистр только 16-битную константу. Поэтому наиболее эффективным является формат Q3.12. Пример кода на C для умножения Q3.12: short x = 0x0800; // 0.5 short y = 0x2000; // 2.0 short r = (short)(((int)x * (int)y) >> 12); // 0x1000 = 1.0 ==== Деление ==== При делении fixed-point чисел коэффициенты масштаба сокращаются: X/2^n / Y/2^n = X/Y Но если мы просто вычислим целочисленное деление X/Y, то получим значение без дробной части. Чтобы сохранить дробную часть, нужно сначала сдвинуть делимое влево на число бит дробной части: R = (X << n) / Y Пример кода на C для деления Q3.12: short a = 0x2000; // 2.0 short b = 0x4000; // 4.0 short r = (short)(((int)x << 12) / (int)y); // 0x0800 = 0.5