Я хотел бы начать с того, что речь идет не об оптимизации, поэтому, пожалуйста, воздержитесь от перетаскивания этой темы по этому пути. Моя цель использования арифметики с фиксированной запятой заключается в том, что я хочу контролировать точность своих вычислений без использования чисел с плавающей запятой.
С учетом сказанного давайте двигаться дальше. Я хотел иметь 17 бит для диапазона и 15 бит для дробной части. Дополнительный бит предназначен для значения со знаком. Вот несколько макросов ниже.
const int scl = 18;
#define Double2Fix(x) ((x) * (double)(1 << scl))
#define Float2Fix(x) ((x) * (float)(1 << scl))
#define Fix2Double(x) ((double)(x) / (1 << scl))
#define Fix2Float(x) ((float)(x) / (1 << scl))
Сложение и вычитание довольно просты, но с mul и div все становится немного сложнее.
Я видел два разных способа обработки этих двух типов операций. 1) если я использую 32 бита, используйте временную 64-битную переменную для хранения промежуточных шагов умножения, а затем масштабируйте в конце.
2) прямо на этапе умножения масштабируйте обе переменные до меньшего битового диапазона перед умножением. Например, если у вас есть 32-битный регистр с 16 битами для всего числа, вы можете сдвинуть его следующим образом:
(((a)>>8)*((b)>>6) >> 2) or some combination that makes sense for you app.
Мне кажется, что если вы разрабатываете математику с фиксированной точкой вокруг 32 бит, может быть непрактично всегда зависеть от наличия 64-битной переменной, способной хранить ваши промежуточные значения, но, с другой стороны, переход к более низкому масштабу серьезно уменьшит ваш диапазон и точность .
вопросы. Поскольку я хотел бы избежать попытки заставить процессор создавать 64-битный тип в середине моих вычислений, является ли переход на более низкие битовые значения единственной альтернативой?
Также я заметил
int b = Double2Fix(9.1234567890);
printf("double shift:%f\n",Fix2Double(b));
int c = Float2Fix(9.1234567890);
printf("float shift:%f\n",Fix2Float(c));
double shift:9.123444
float shift:9.123444
Является ли эта потеря точности частью использования чисел с фиксированной запятой?
printf
с%.10f
для отображения с плавающей запятой, тогда вы увидите все цифры. Также: docs.oracle.com/cd/E19957-01/ 806-3568 / ncg_goldberg.html - person Koshinae   schedule 26.07.2015