2015-04-14 2 views
-1

Я хотел бы узнать науку, лежащую в основе следующего. 32-битное значение сдвигается влево 32 раза в 64-битном типе, тогда выполняется деление. так как точность содержится в последних 32 битах, и для получения значения в виде числа с плавающей запятой я могу умножить на 1 по максимальному значению 32-битного беззнакового числа.битмаскировка и двоичная арифметика

phase = ((uint64) 44100 << 32)/48000; 
(phase & 0xffffffff) * (1.0f/4294967296.0f);// == 0.918749988 

же, как

(float)44100/48000;// == 0.918749988 
+1

вы уверены, что это '0xffffff' и не' 0xffffffff'? – Wintermute

+0

** - 1 ** Не настоящий код. При попытке вашего первого примера в Python выражение '(phase & 0xffffff) * (1.0/4294967296.0)' дает '0.0007812499534338713'. –

+0

Для примера, который вы где-то видели, обратите внимание, что максимальное значение 32-битного int без знака равно 2^32-1, что очень близко к множителю 2^32, который вы ввели. Таким образом, результаты (для этого оригинального примера) будут почти одинаковыми. –

ответ

0

это ответ, который я искал

немного сворачивает налево будет предусматривать, что число битов, в которых можно хранить точность юдоль от деления.

деление целого значения, представленное эти биты на 2 в степень количества сдвига бита будет возвращать значение точности

например

0000 0001 * 2^8 = 1 0000 0000 = 256 (основание 10)

1 0000 0000/2 = 1000 0000 = 128 (основание 10)

128/2^8 = 0,5

0

(...)

  1. Если вы теряете точность при делении двух целых чисел, следует помнить остаток.
  2. Напоминание в C++ можно сделать, выполнив 44100% 48000 в вашем случае.
  3. На самом деле это константы, и совершенно ясно, что 44100/48000 == 0, так что осталось все, что у вас есть.
  4. Ну, напомним, что даже будет - догадаться, что - 44100!
  5. Тип float (введенный явным литом) имеет только 6 значащих цифр. Таким образом, 4294967296.0f будет просто 429496e4 (по математике: 429496 * 10^4). Вот почему этот тип не ценен ни для чего, кроме игры.
  6. Лучший способ получить значение фиксированного целочисленного типа, в котором установлены все биты, а не пропустить правильное число 'f' в 0xfffff, - использовать значение ~ и значение 0. В вашем случае ~ uint32_t (0).

Ну, я должен был сказать это в начале: 44100.0/48000 должен дать вам результат, который вы хотите. : P

+0

мой вопрос не потому, что я теряю точность, это то, что является процессом, связанным с этим стилем деления. –

+0

Итак, каков ваш вопрос? Ваше заявление в «вопросе» слишком непонятно, чтобы угадать, что вы хотите знать. Отвечает ли точка № 5? – Ethouris

Смежные вопросы