Число в формате Q — обычное целое со знаком, у которого младшие n бит считаются дробной частью. По руководству TI IQmathLib значение Qn хранится как целое xi с подразумеваемым множителем 2−n:
Калькулятор переводит в обе стороны для слов 8, 16 и 32 бита и любого числа дробных бит. Что такое фиксированная точка и как с ней считать — в статье о фиксированной точке и в словаре на странице «Формат Q».
Как считает калькулятор
Число → целое. Число умножается на 2n и приводится к целому — так, как это делает функция arm_float_to_q15 и соседние в CMSIS-DSP:
- отбросить дробь — приведение типа в C, к нулю. Так CMSIS-DSP работает по умолчанию, и так же устроены макросы TI
_QN()и_IQN(); - до ближайшего — CMSIS-DSP, собранная с макросом
ARM_MATH_ROUNDING: перед приведением прибавляется 0,5 для положительного числа и −0,5 для отрицательного.
Если результат не помещается в слово, CMSIS-DSP его насыщает — для Q15 до диапазона [0x8000, 0x7FFF]. Калькулятор делает так же и предупреждает: макросы TI по их руководству не насыщают, и значение вне диапазона переполняется.
Целое → число. Целое делится на 2n. Вводить можно десятичное со знаком или hex в дополнительном коде: 0x8000 в 16 битах — это −32 768. Результат калькулятор показывает точно: двоичная дробь всегда заканчивается не дальше n-го знака после запятой.
Диапазон и шаг
У слова из b бит с n дробными наименьшее значение −2b−1−n, наибольшее 2b−1−n − 2−n, шаг 2−n. Целых бит b − n, считая знаковый, — так их считают таблицы TI.
| Формат | Слово | Где встречается | Диапазон | Шаг |
|---|---|---|---|---|
| Q7 | 8 бит | CMSIS-DSP q7_t | −1 … 0,9921875 | 0,0078125 |
| Q15 | 16 бит | CMSIS-DSP q15_t, TI _q15 | −1 … 0,999969482 | 3,05 · 10−5 |
| Q12 | 16 бит | TI _q12 | −8 … 7,999755859 | 2,44 · 10−4 |
| Q31 | 32 бита | CMSIS-DSP q31_t | −1 … 0,9999999995 | 4,66 · 10−10 |
| Q24 | 32 бита | TI _iq24, GLOBAL_Q по умолчанию | −128 … 127,99999994 | 5,96 · 10−8 |
| Q16 | 32 бита | TI _iq16 | −32 768 … 32 767,9999847 | 1,53 · 10−5 |
Чем больше дробных бит, тем мельче шаг и тем уже диапазон — TI в руководстве SPRUGG9 прямо называет это компромиссом, который выбирают под задачу. Значения в таблицах TI округлены, а в таблице 2-1 SPRUGG9 есть две опечатки: для _iq23 напечатано 255,999 999 981 вместо 255,999 999 881 (верное значение — в таблице 2.2 руководства IQmathLib), а для _iq0 — 2 147 483 648 вместо 2 147 483 647.
Примеры
- 3,625 в Q12 и IQ24 — пример из руководства TI: 3,625 · 212 = 14 848 в 16-битном слове и 3,625 · 224 = 60 817 408 в 32-битном. Число представимо точно, ошибка квантования — ноль.
- 0,1 в Q15. 0,1 · 32 768 = 3276,8: с отбрасыванием дроби — 3276 = 0x0CCC, что на самом деле 0,0999755859375; с округлением — 3277 = 0x0CCD, то есть 0,100006103515625. Десятичная 0,1 в двоичной дроби бесконечна, и ошибка квантования неизбежна.
- 1,0 в Q15 не помещается: 32 768 больше наибольшего 16-битного 32 767. CMSIS-DSP запишет 0x7FFF.
- −0,25 в Q7 — −32, в 8-битном слове 0xE0.
Умножение и сложение
Сложение и вычитание чисел одного формата — обычные целые операции, но сумма может выйти за диапазон. Произведение двух чисел Qn имеет 2n дробных бит: умножают в удвоенной разрядности и сдвигают вправо на n бит. Функция _QNmpy из TI IQmathLib делает именно это и по руководству не округляет и не насыщает результат, а _QNrsmpy — округляет и насыщает. Подробности и код — в статье «Фиксированная точка», перевод между системами счисления — в конвертере систем счисления.
Частые вопросы
Как перевести число в формат Q15?
Умножить на 2^15 = 32 768 и взять целую часть. Например, 0,5 · 32 768 = 16 384 = 0x4000. Так делает функция arm_float_to_q15 из CMSIS-DSP: по умолчанию она отбрасывает дробную часть, а 0,1 даёт 3276, и только при сборке с макросом ARM_MATH_ROUNDING округляет до ближайшего, 3277. Обратно — делить на 32 768.
Почему 1,0 нельзя записать в Q15?
Наибольшее 16-битное целое со знаком — 32 767, а 1,0 · 32 768 = 32 768. Поэтому диапазон Q15 — от −1 до 32 767 / 32 768 ≈ 0,99997. CMSIS-DSP насыщает 1,0 до 0x7FFF, а макросы TI _Q15() и _IQ15() не насыщают — по руководству TI значение вне диапазона переполняется и даёт неверный результат.
Что такое IQ24 и GLOBAL_Q в библиотеке TI IQmath?
IQ24 — 32-битное число, у которого 24 бита дробные: 8 целых бит со знаковым дают диапазон от −128 до 127,99999994 с шагом около 6 · 10^−8. GLOBAL_Q — формат, с которым работают функции без номера в имени, например _IQsin(). В IQmath для C64x+ его можно выбрать от 0 до 31, по умолчанию — 24 (TI SPRUGG9).
Как записать отрицательное число в hex в формате Q?
В дополнительном коде, как обычное целое со знаком той же разрядности. −0,25 в Q7 — это −0,25 · 128 = −32, в 8-битном слове 0xE0; −1 в Q15 — 0x8000. Калькулятор принимает hex в дополнительном коде и сам учитывает знаковый бит.
Источники
- Texas Instruments. MSP MCU IQmathLib Users Guide, version 01.12.01.03 — формулы 2.1 и 2.3 — Qn(x) = xi · 2^−n, n — число дробных бит; формулы 2.2 и 2.4 — 3,625 хранится как 14848 в Q12 и как 60817408 в IQ24 (эталоны тестов); таблица 2.1 — 16-битные Q1…Q15, таблица 2.2 — 32-битные IQ1…IQ30: целые биты со знаковым, наименьшее и наибольшее значение, шаг; _QN() и _IQN() не округляют и не насыщают — значение вне диапазона переполняется
- Texas Instruments. TMS320C64x+ IQmath Library User's Guide (SPRUGG9, December 2008) — разд. 2.2 и таблица 2-1 — диапазон и шаг 32-битных Q0…Q31 (второй источник тестов; в строках _iq23 и _iq0 опечатки); разд. 2.4 — GLOBAL_Q от 0 до 31, по умолчанию 24
- Arm. CMSIS-DSP 1.16.2: arm_float_to_q7.c, arm_float_to_q15.c, arm_float_to_q31.c, arm_q15_to_float.c — преобразование: умножение на 128, 32768 или 2147483648 и приведение типа (отбрасывание дробной части); с макросом ARM_MATH_ROUNDING перед приведением прибавляется ±0,5; насыщение до диапазона слова, для Q15 — [0x8000 0x7FFF]; обратно — деление на 2^N; лицензия Apache-2.0
Встроить калькулятор на свой сайт
Скопируйте код и вставьте его в HTML страницы, статьи или вики. Виджет бесплатный, без рекламы, счётчиков и cookie. Условие одно — ссылка на GAW под рамкой остаётся на месте. Подробнее о виджетах
<iframe src="https://gaw.ru/embed/q-format/" title="Конвертер чисел с фиксированной точкой (формат Q)" width="100%" height="640" style="border:1px solid #e3e5e9;border-radius:8px" loading="lazy" allow="clipboard-write"></iframe>
<p style="margin:6px 0 0;font-size:14px">Калькулятор: <a href="https://gaw.ru/tools/q-format/">Конвертер чисел с фиксированной точкой (формат Q)</a> — GAW.ru</p>Автоподстройка высоты рамки
Если сайт разрешает скрипты, добавьте этот код один раз в любом месте страницы: рамка будет менять высоту вместе с результатом расчёта.
<script>window.addEventListener("message",function(e){if(e.origin!=="https://gaw.ru"||!e.data||e.data.type!=="gaw:embed-height")return;var f=document.querySelectorAll('iframe[src^="https://gaw.ru/embed/"]');for(var i=0;i<f.length;i++)if(f[i].contentWindow===e.source)f[i].style.height=e.data.height+"px"})</script>Обновлено .
Нашли ошибку в расчёте?