ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Среда
27 ноября
155712 Топик полностью
Ксения (05.05.2009 17:23, просмотров: 178) ответил POV на Не осознал насчет точности вычисления с плавучкой на Keil C51...
Я бы здесь вообще не стала прользоваться float-арифметикой, а на ассемблере вычислила в целых числах. Получилось бы абсолютно точно. Дело в том, что значение от АЦП умещается в 3 байта (у кого у 2 байт, тому еще проще). А это значит, что это число можно умножить на байтовый множитель с тем, что результат умножения уместиться в 4-х байтах (переменная long). Поэтому можно получить полный результат, перемножая байты "столбиком". Для этого дробный множитель надо привести к целому числу, умножив его либо на 2^24 или на 2^16 (в зависимости от того, какую точность надо получить в результате), а потом поочередно перемножать АЦП-значение на каждый из байтов сомножителя, а потом результаты со сдвигом сложить. При этом можно делать сдиг не в сторону старших разпядов, а в сторону младших, обрезая младшие байты числа. тут все равно последние 3 или 2 байты обречены на срез тем, что мы изначально множили на 2^24 или на 2^16. Например, пусть АЦП значение представляет собой 3 байта: A2_A1_A0, а масштабируемый множитель нужен 0.87654321. Умножаем множитель на 65536 (это и есть 2^16) получим 57445.13581, округляем его до целого 2-байтового числа 57445, где байты будут такими: M1=0xE0 и M0=0x65. Теперь займемся множением. Вычислим два 4-байтных произведения C и D: С3_С2_С1_С0 = A2_A1_A0 * M1 D3_D2_D1_D0 = A2_A1_A0 * M0 а затем складываем их со сдвигом, отбрасывая два младших байта: С3_С2_С1_С0___ ___D3_D2_D1_D0 Получим 3-байтный резултат. Точно тем же способом можно было получить еще более точный результат, только тогда множитель пришлось бы домножать на 2^24, а складывать не два частных произведения, а три. Но это все равно было бы гораздо быстрее, чем процедуры эмуляции float в библиотеке Кейла.