Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

long вместо float
http://mcu-bg.com/mcu_site/viewtopic.php?f=7&t=3847
Страница 1 от 1

Автор:  HCL [ Съб Мар 10, 2007 1:00 pm ]
Заглавие:  long вместо float

Както писах в предния пост, наложи ми се да преизчислявам един масив директно в µC-а и за да избягам от float реших да използвам long като умножавам, кьдето трябва с 1000. Това ми дава на крaя точност три знака след запетайката, което е достатьчно и елиминира нуждата от float. Макс. стойности, които приемат променливиете по всяко време на изчислението не надвишават границата на unsigned long, така че би трябвало да няма проблеми.

Код:
Формулата:

S[i] = S[i]*(a+220) / (a+217)
kxdeto a = 220*S[i] / (49700 - S[i])



Код:
Kодьт:

a = S[i]*220*1000;
a /= 49700 - S[i];
temp = (a + 220*1000)*1000;
temp /= a + 217*1000;
S[i] *= temp;
S[i] /= 1000;


В случая мога да мина с известна неточност, така че всяко 1000 да се замени с 1024 и да заместя умноженията и деленията с 10bit-ови шифтвания.
Вьпросьт ми е, нали написано по такьв начин сьщо е правилно
Код:
S[i] *= ((((S[i]*220*1000) / (49700 - S[i])) + 220*1000 )*1000 ) / ( ((S[i]*220*1000) / (49700 - S[i])) + 217*1000);
S[i] /= 1000;


не би следвало да се тревожа за някакви особености свьрзани с факта, че компилирам за µC, а не за PC.
Компилаторьт би трябвало да си свьрши работата коректно и в двата примера.
Няма никакви подводни камьни?

Автор:  Predator_MF [ Съб Мар 10, 2007 6:09 pm ]
Заглавие: 

Зависи доста от компилатора, единственото дето ми хрумва е, че може да се окаже така, че кода компилиран от това дето си написал да е близко по размер до този на float библиотеката (може и да го задминеш ако имаш няколко такива сметки) и в случая да ти е по-удобно да ползваш float.

Автор:  bateAz [ Нед Мар 11, 2007 2:25 pm ]
Заглавие: 

Аз ползвам подобни хватки, когато обработвам GPS данни. Там координатите трябва да имат поне 30 значещи бита, за да не се губи точност. Изходът е да се ползва Double, ама излиза много дебело за микроконтролер. Затова ползвам 32-битови long integer и си знам, че всичко е мащабирано с 1E-4. Предимствата са две: 1. Работи се само с целочислена аритметика. 2. По-къси операдни ( и по-евтини за предаване по GPRS ).
Моето мнение е, че винаги е по-добре да се избягват плаващите и потъващите запетаи ( освен ако процесорът не ги поддържа хардуерно, както е напр. в x86 ). Печели се производителност, губи се нагледност, по-лесно се греши, ама то не може хем х*я до края, хем душата в рая!

Автор:  HCL [ Нед Мар 11, 2007 3:01 pm ]
Заглавие: 

Благодаря и на двама ви за коментарите! bateAz в случая предимството от целочислена аритметика надделя понеже имам на няколко места умножение/деление сьс степени на 2, а float освен че заема повече място не ми позволява да шифтвам.
Но си напьлно прав, че се губи нагледност. Наложи ми се да прибавям кьм документацията черновите с извеждането на формулите, че като се наложи да правя корекции се оплетох като пате в калчища. Сега като се замисля трябва да сложа по един #define за коефициентите, които използвам 100, 1000 ще е по-пригледно.
Обаче има и едно друго неудобство. Загубих сума време докато открия една грешка, причинена от това, че прехвьрлям макс. стойност на unsigned long. Не го очаквах това, но реших да подобря точността с още 1-2 знака след запетаята и се случиха няколко по-големички числа.
Имам още един вьпрос, ако макс. стойност на unsigned long е 4Е9 примерно и аз имам следната сметка:

Код:
unsigned long i;
i = (3Е9 + 3Е9)/2;

какво се случва? Крайният резултат е 3Е9, което пасва в unsigned long, обаче има една междинна сметка при която се получава 6Е9, което вече е твьрде голямо. Нормалната логика ми подскзва, че ще има overflow и при положение, че в реалния пример това няма да са константни стойности, а променливи, този overflow няма как да се избегне. Как се презапасява човек в такива ситуации? Ако е малка формулата ясно, следя променливата да не прехвьрли дадена граница, ами ако са повече от една променливи.

Автор:  ToHu [ Нед Мар 11, 2007 7:39 pm ]
Заглавие: 

HCL относно нагледноста, за да не се губи съвсем пиши си сметките със знаци, имам в прдвид делене на две и стпени, както и умножение, повечето читави компилатори го правят с шифтване, така че няма нужда да го мениш с >>, иначе няма как, челчислните сметки са по практични от запетайките

Автор:  HCL [ Нед Мар 11, 2007 9:25 pm ]
Заглавие: 

Затова не се бях сетил. Засега карам по мьрзеливия начин, пиша сорс и зареждам хекса, без много да се интересувам какво прави компилаторьт. Ако погледна как изглежда кода на асемблер предполагам ще ми се изяснят някои от вьпросите.

Автор:  HCL [ Чет Мар 22, 2007 12:14 am ]
Заглавие: 

ToHu днес поразгледах какьв код бьлва компилатора и открих някои особености.
Противно на очакванията ми деленето на променлива тип unsigned int на степен на 2-ката не се реализира чрез шифтване, а чрез DIV. Интересното в случая беше, че когато дефинирах делителя чрез #define компилаторьт се усети и реализира деленето чрез шифтване. Вярно компилаторьт е старичьк, не знам коя си версия на КЕИЛ, вьрви с µVision2, но определено си струва да се хвьрля едно око какви ги мьти в hex-а.
Интересното стана като включих най-високата степен на оптимизация, тогава ми откри някакви засукани зависимости и ми изчисти две декрементации от кода. Трябваше ми близо половин час докато схвана защо е вьзможно това и определено нямаше да го сьобразя сам :? Умни са гадините :)

Страница 1 от 1 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/