Перейти к содержанию

Конвертер чисел с фиксированной точкой (формат Q)

Задайте разрядность слова и число дробных бит — калькулятор переведёт дробное число в целое формата Q или целое и hex обратно в число, покажет, что хранится на самом деле, ошибку квантования, диапазон и шаг формата и выдаст код на C для CMSIS-DSP и TI IQmath.

Исходные данные

Направление

Результат

Целое в слове
3276 = 0x0CCC
Хранится на самом деле
0,09997558593753276 · 2^−15, точно
Ошибка квантования
−0,00002441хранимое минус заданное
Двоичное с точкой
0.000110011001100
Диапазон
−1 … 0,9999694824целых бит — 1, считая знаковый, дробных — 15; точный максимум 0,999969482421875
Шаг (разрешение)
0,00003051762^−15 = 0,000030517578125

Код на C

/* Q15 in a 16-bit word: value = raw / 2^15 */
q15_t x = 3276;   /* 0x0CCC, stands for 0.0999755859375 */
float f = x / 32768.0f;
q15_t y = (q15_t)(f * 32768.0f);   /* the C cast truncates toward zero */

/* CMSIS-DSP, with saturation: */
arm_float_to_q15(&f, &y, 1);

Расчёт выполнен по формулам и данным из источников, приведённых на этой странице, и не заменяет проверку: параметры компонентов у разных производителей и даже партий различаются. Перед применением сверяйте результат с документацией на конкретные детали.

Число в формате Q — обычное целое со знаком, у которого младшие n бит считаются дробной частью. По руководству TI IQmathLib значение Qn хранится как целое xi с подразумеваемым множителем 2−n:

x=xi⋅2−n,xi=x⋅2n.x = x_i \cdot 2^{-n}, \qquad x_i = x \cdot 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.

ФорматСловоГде встречаетсяДиапазонШаг
Q78 битCMSIS-DSP q7_t−1 … 0,99218750,0078125
Q1516 битCMSIS-DSP q15_t, TI _q15−1 … 0,9999694823,05 · 10−5
Q1216 битTI _q12−8 … 7,9997558592,44 · 10−4
Q3132 битаCMSIS-DSP q31_t−1 … 0,99999999954,66 · 10−10
Q2432 битаTI _iq24, GLOBAL_Q по умолчанию−128 … 127,999999945,96 · 10−8
Q1632 битаTI _iq16−32 768 … 32 767,99998471,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 в дополнительном коде и сам учитывает знаковый бит.

Источники

  1. 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() не округляют и не насыщают — значение вне диапазона переполняется
  2. 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
  3. 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>

Обновлено .

Нашли ошибку в расчёте?