Как добавить фиксированную точку с двумя дополнительными фиксированными точками? - PullRequest
0 голосов
/ 17 января 2019

Я хочу умножить целое число без знака 5432 на 0,01, а затем добавить / вычесть 0,3. Вместо использования чисел с плавающей точкой я хочу использовать арифметику с фиксированной точкой. Вот мои шаги:

1) ((1 << 16) * 0,01) = 655 => Фиксированная точка Q0.16

2) 655 * 5432 = 3557960 => Фиксированная точка Q16.16

3) ((1 << 16) * 0,3) = 19660 => Фиксированная точка Q0.16

4) Добавить 0.3: 3557960 + 19660 = 3577620 => Преобразовать в число с плавающей точкой = 54.59, что очень похоже на использование плавающих вычислений: 5432 * 0.01 + 0.3 = 54.62

5) Вычтите 0,3: найдите дополнение двух 19660 => 45876, теперь 3577620 + 45876 = 3623496 => 55,29, что не соответствует ожидаемому 5432 * 0,01 - 0,3 = 54,02

Может ли кто-нибудь подтвердить, что я прав в пункте 1-4 и чего мне не хватает в пункте 5?

1 Ответ

0 голосов
/ 17 января 2019

Ваша ошибка в том, что вы предполагаете, что представление из 2-х дополнений не зависит от размера слова. Это не. От 16-битного до 2-го дополнения для 19660 - это 2^16 - 19660 или 45876, но поскольку вы работаете с 32-разрядным числом, вам необходимо соответствующее 2-дополнение, равное 2^32 - 19960 или 4294947636. Другими словами, когда вы расширяете 2-дополнение с 16-битных на 32-битные, вы должны заполнять старшие байты знаковым битом, т.е. 1 для отрицательных значений. Вы можете видеть, что в двоичном коде оба значения фактически одинаковы при таком расширении:

45876      =                   10110011_00110100 (16-bit binary)
4294947636 = 11111111_11111111_10110011_00110100 (32-bit binary)

Если вы добавите 3557960 + 4294947636, вы получите 4298505596 или урежете его до 32-битного значения - 3538300, которое представляет собой представление с фиксированной точкой 53,99

...