<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pl-pl">
<link rel="self" type="application/atom+xml" href="https://forum.atnel.pl/feed.php?f=4&amp;t=22189&amp;mode" />

<title>ATNEL tech-forum</title>
<link href="https://forum.atnel.pl/index.php" />
<updated>2019-04-26T18:41:38+01:00</updated>

<author><name><![CDATA[ATNEL tech-forum]]></name></author>
<id>https://forum.atnel.pl/feed.php?f=4&amp;t=22189&amp;mode</id>
<entry>
<author><name><![CDATA[Alef2]]></name></author>
<updated>2019-04-26T18:41:38+01:00</updated>
<published>2019-04-26T18:41:38+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=22189&amp;p=218482#p218482</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=22189&amp;p=218482#p218482"/>
<title type="html"><![CDATA[Re: Mnożenie zmiennoprzecinkowe, optymalizacja.]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=22189&amp;p=218482#p218482"><![CDATA[
Jak rozumiem zadanie polega na przemnożeniu liczby z zakresu  0-4095 (12 bit) przez współczynnik z zakresu 0-2,00 (dwie cyfry znaczące po przecinku), a wynik ma być liczba całkowitą z zakresu 0-8192 (13 bit). By się nie myliło liczba 0-4095 niech nazywa się pomiar, liczba 0-2,00 nazywa się współczynnik, a wynik ich mnożenia to wynik. I wynik ma być typu uint16.<br />Najpierw przedstawmy współczynnik w postaci liczby całkowitej 8 bit  z zakresu 0-255. Zrobimy to po prostu mnożąc współczynnik przez 128 i pomijając część po przecinku. Uzyskujemy liczbę całkowitą typu uint8. Teraz wystarczy pomnożyć liczbę uint16 przez uint8, a wynik podzielić przez 128.<br />Dzielenie przez 128 to przesuniecie o 7 bitów w prawo. Więc 7 najmniej znaczących bitów wyniku zostanie zignorowane. Te 7 bitów to część ułamkowa wyniku, którą mamy zaokrąglić. Należałoby też dodać 1 na 7 bicie by zaokrąglanie było i w górę i w dół.<br />Ponieważ i tak pozbywamy się 7 bitów po mnożeniu w wyniku, to nie popełnimy dużego błędu gdy części z tych 7 bitów pozbędziemy się przed mnożeniem w pomiarze np 3 bity i współczynniku np 2bity. Wtedy mnożymy liczbę 10bit przez 6bit i uzyskujemy 16bit, która to mieści się w 16 bitach typu uint16. Pozbyliśmy się 3+2=5bitów pozostały jeszcze 2, których to pozbędziemy się już w wyniku. Taka byłaby moja idea rozwiązania tego problemu.<br />Alternatywnie można spróbować wykorzystać matematykę liczb stałoprzecinkowych, lub samemu napisać algorytm mnożenia, co wbrew pozorom nie jest takie trudne<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=14998">Alef2</a> — 26 kwi 2019, o 18:41</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[lamik]]></name></author>
<updated>2019-04-25T14:29:30+01:00</updated>
<published>2019-04-25T14:29:30+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=22189&amp;p=218462#p218462</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=22189&amp;p=218462#p218462"/>
<title type="html"><![CDATA[Re: Mnożenie zmiennoprzecinkowe, optymalizacja.]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=22189&amp;p=218462#p218462"><![CDATA[
Nie używaj floatów <img src="https://forum.atnel.pl/images/smilies/icon_e_sad.gif" alt=":(" title="Smutny" /> To jest zło. Ostatnio czytam takiego chłopaka i on napisał fajny artykuł o floatach. CO prawda na STM32, ale float to float <img src="https://forum.atnel.pl/images/smilies/icon_e_biggrin.gif" alt=":D" title="Bardzo szczęśliwy" /> <!-- m --><a class="postlink" href="https://msalamon.pl/ile-kosztuje-uzywanie-float-i-co-daje-fpu/" >https://msalamon.pl/ile-kosztuje-uzywan ... -daje-fpu/</a><!-- m --><p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1630">lamik</a> — 25 kwi 2019, o 14:29</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[mirekk36]]></name></author>
<updated>2019-04-24T22:04:47+01:00</updated>
<published>2019-04-24T22:04:47+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=22189&amp;p=218448#p218448</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=22189&amp;p=218448#p218448"/>
<title type="html"><![CDATA[Re: Mnożenie zmiennoprzecinkowe, optymalizacja.]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=22189&amp;p=218448#p218448"><![CDATA[
<div class="quotetitle">sir_auron napisał(a):</div><div class="quotecontent"><br />bo bez tego miałem przepełnienie zmiennej przy mnożeniu przez &gt;16, tak jakby iloczyn był uint16.<br /></div><br />Bo pewnie nie słyszałeś o domyślnej promocji do INT w języku C<br /><br /><!-- m --><a class="postlink" href="https://atnel.pl/domyslna-promocja-do-typu-int.html" >https://atnel.pl/domyslna-promocja-do-typu-int.html</a><!-- m --><br /><br />jak to przeczytasz to zrozumiesz dlaczego w takich wypadkach jest wymagane jawne rzutowanie<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=54">mirekk36</a> — 24 kwi 2019, o 22:04</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[sir_auron]]></name></author>
<updated>2019-04-24T21:33:57+01:00</updated>
<published>2019-04-24T21:33:57+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=22189&amp;p=218446#p218446</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=22189&amp;p=218446#p218446"/>
<title type="html"><![CDATA[Mnożenie zmiennoprzecinkowe, optymalizacja.]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=22189&amp;p=218446#p218446"><![CDATA[
Mam problem do rozwiązania. Potrzebuję w mojej aplikacji przemnożyć wartość z zakresu 0-4095 przez wartość zmiennoprzecinkową z zakresu 0-2,00 wprowadzaną przez użytkownika. Wymyśliłem sobie, że wartość zmiennoprzecinkową będę reprezentował za pomocą trzech zmiennych uint8_t odpowiadającym trzem cyfrom (setki, dziesiątki, jedności), następnie zsumuję cyfry, przemnożę przez wartość 0-4095, a następnie podzielę przez 100. Zmienna wynik jest typu uint16 i przechowuje wartość z ADC z zakresu 0-4095. Po przemnożeniu chciałbym aby zmienna wynik była nadal typu uint16.<br />Przykładowy kod:<br />[syntax=c]uint8_t s, d, j, suma;<br />uint32_t iloczyn;<br />s*=100; d*=10;<br />suma = s+d+j;<br /><br />//poniżej część kodu która ma być wykonywana jak najszybciej<br />iloczyn = (uint32_t)wynik * (uint32_t)suma; //rzutowanie robię dlatego, bo bez tego miałem przepełnienie zmiennej przy mnożeniu przez &gt;16, tak jakby iloczyn był uint16.<br />wynik = iloczyn/100;<br />(uint16_t) wynik;[/syntax]<br />Istotne jest dla mnie, żeby uzyskać możliwie najkrótszy czas mnożenia i dzielenia. Na ile da się ten przykład zoptymalizować? Jak na razie jestem daleki od założonych ram czasowych wykonywania tego fragmentu kodu. Te trzy linijki kodu wprowadzają ok 40 us opóźnienia. Natomiast zapasu na to mam ok 7 us. Procesor pracuje na 16 MHz.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=19865">sir_auron</a> — 24 kwi 2019, o 21:33</p><hr />
]]></content>
</entry>
</feed>