Отговори на тема  [ 7 мнения ] 
long вместо float 
Автор Съобщение
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Вто Дек 14, 2004 1:31 pm
Мнения: 3849
Мнение 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.
Компилаторьт би трябвало да си свьрши работата коректно и в двата примера.
Няма никакви подводни камьни?


Съб Мар 10, 2007 1:00 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Чет Окт 07, 2004 1:22 pm
Мнения: 1949
Местоположение: София
Мнение 
Зависи доста от компилатора, единственото дето ми хрумва е, че може да се окаже така, че кода компилиран от това дето си написал да е близко по размер до този на float библиотеката (може и да го задминеш ако имаш няколко такива сметки) и в случая да ти е по-удобно да ползваш float.


Съб Мар 10, 2007 6:09 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

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


Нед Мар 11, 2007 2:25 pm
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Вто Дек 14, 2004 1:31 pm
Мнения: 3849
Мнение 
Благодаря и на двама ви за коментарите! 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 няма как да се избегне. Как се презапасява човек в такива ситуации? Ако е малка формулата ясно, следя променливата да не прехвьрли дадена граница, ами ако са повече от една променливи.


Нед Мар 11, 2007 3:01 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Сеп 26, 2004 9:21 pm
Мнения: 30686
Местоположение: София
Мнение 
HCL относно нагледноста, за да не се губи съвсем пиши си сметките със знаци, имам в прдвид делене на две и стпени, както и умножение, повечето читави компилатори го правят с шифтване, така че няма нужда да го мениш с >>, иначе няма как, челчислните сметки са по практични от запетайките


Нед Мар 11, 2007 7:39 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Вто Дек 14, 2004 1:31 pm
Мнения: 3849
Мнение 
Затова не се бях сетил. Засега карам по мьрзеливия начин, пиша сорс и зареждам хекса, без много да се интересувам какво прави компилаторьт. Ако погледна как изглежда кода на асемблер предполагам ще ми се изяснят някои от вьпросите.


Нед Мар 11, 2007 9:25 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

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


Чет Мар 22, 2007 12:14 am
Профил WWW
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 7 мнения ] 

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 2 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни