[elektro] C aritmetika?
hg12345
hg12345 at freemail.hu
Sun Apr 4 11:20:21 CEST 2010
Hi!
A dolog igen egyszerű, ha BASIC-ból lépsz át C-be akkor valószínűleg nincs teljesítmény és fogyasztás és kód méret problémád, mert a BASIC-ben írt kódokra a fenti tulajdonságok nem jellemzők.
Mint minden magasszintű vagy macro nyelvekre (a C elvileg ez) igaz, hogy nem igazán foglalkoznak a műveletek elvégzésére. A processzorok és uC a műveletek végzésekor néhány status biten jelzik vagy különböző TRAP it-ken a müveleti eredmény hibájátt. Túlcsordulás, vagy előjel váltás stb....
Ezt a C és BASIC úgy oldottak meg gondoskodjál olyan méretről ahol a művelet eredménye elfér, akkor nem lehet ilyen hiba. (Ezzel nincs is probléma)
Hogy biztos jó legyen az eredmény C-ben...
int mul1,mul2;
long x=mul1*mul2; //nagy számok esetén hibás
a szorzás csak int méretű így az eredmény is ez, majd az eredményt bővíti 32bitre és ezt tárolja :-(((( (A BASIC-ban is ilyen hibák lehetnek)
a helyes megoldás
x= ((long)mul1)*mul2;
az egyik változót most kényszerítve van, hogy 32 bites legyen, a más
automatikusan lesz ilyen, a szorzás eredménye is 32 bites lesz, de nincs benne hiba lehetőség mer pont elfér benne, az eredmény meg egyezik a balértékkel igy most már nem kell konverziós (automatikus castolas)
Ez minden magas szintű nyelvre érvényes, csak oda kell figyelni.
((( long long << long.... double << float... esetén is )
---------------------------------------------------------
A fordító magához képest konzekvesen jár el, a kód amit generál tökéletes!!! Én a fordítot szeretném egy kicsit becsapni, hogy kitudja használni az alatta lévő uC adta tulajdonságokat.
---------------------------------------------------------
Köszönöm.
Igen, jól látod, most tanulom, most térek át rá.
Nem keltesz vele rossz érzést, de köszönöm, hogy figyelsz rá.
Ettől függetlenül kaptam választ.
De az általad leírtak alapján úgy néz ki, hogy a hw rutin hibás, az sw
rutin pedig lassú.
Bali Zoli kérdése pedig érdekes.
Vagy rosszul látom.
Ha nem akarsz most egy kezdővel foglalkozni, akkor hagyjuk, de ez egy
annyira alapvető probléma, hogy érdekes számomra is.
Ugyanis az áttérésem egyik oka pont a long változók és a
szorzás-osztás viszonya, ami a basicban nincs rendesen megcsinálva.
Nincs kedvem asm rutinokat írni, ezért (is) a váltás.
2010/4/4 hg12345 <hg12345 at freemail.hu>:
> Elnézést, nem akarok rossz érzést kelteni senkiben, de használtál már C programot? Most tanulod?
>
> Ha nem akarsz a C-ben hibás eredményt akkor az művelet méretét az eredményhez kell állítani (mondtam hogy nem figyeltek az iskolai órán).
> A castolás egy méret váltási kényszerítés ott kell használni ahol a C nem tudja eldönteni mit akarsz. Hogy HW vagy SW az a fordító program írói döntik el, ill akik a macro-kat készítették az adott implementációhoz. Ha szerencsés a fordító akkor amit ismer a HW (vagyis a kontroller ill. processzor) azt közvetlen utasításokkal végzik, amit nem lehet azt a fordító kiegészíti a sáját kódjával.
>
> Remélem valaki tudja a megoldást :-)
>
>
> Ez érdekes. Ezekszerint nem kaphatsz normális szorzási eredményt
> C-ben? Hiszen ha a két tag összesen több, mint 16 bit, akkor hibás az
> eredmény.
> Vagy maradsz a sw rutinnál.
> Másik kérdés: Mi határozza meg, hogy hw, vagy sw legyen a végrehajtás?
> Csak a castolás?
>
> 2010/4/4 hg12345 <hg12345 at freemail.hu>:
>> Nem tudom elég érhetően fogalmaztam. Ez egy tipikus C hiba, reméltem valaki ismeri a kikerülését.
>>
>> Részletesen itt van.
>>
>> A dolog nagyon egyszerű, a C program írói a következő feltételezéseket tették (az iskolában nem figyeltek) 16bit*16bit=16bit ez a legtöbb esetben így van... (náluk szorzás művelet eredménye egyezik, a tagok méretével, az iskolában az tanítják az eredmény mérete a két tag méretének összege.....:-)
>>
>> egy kompenzációs számot szeretnék generálni IT ben, itt különösen problémás a rutin hívás, mert ilyenkor a teljes általános regiszter készletet menti, ha kell ha nem kell!
>>
>> int ASETS_DAcom; /// ICBUF32 ez egy long.....
>> int x;
>> x = (((unsigned int)(Aset.ICBUF32>>12)) * ASETS_DAcom)>>4;
>>
>> Az eredmény:
>>
>> 4D6E 804F20 mov.w Aset,w0
>> 4D70 804F31 mov.w 0x09e6,w1
>> 4D72 DD0944 sl w1,#4,w2
>> 4D74 DE004C lsr w0,#12,w0
>> 4D76 710000 ior.w w2,w0,w0
>> 4D78 DE08CC lsr w1,#12,w1
>> 4D7A 8050C2 mov.w ASETS_DAcom,w2
>> 4D7C B98002 mul.ss w0,w2,w0
>> 4D7E DE0048 lsr w0,#8,w0
>> 4D80 884FC0 mov.w w0,0x09f8
>>
>> A mul.ss jó is, de itt az eredmény 32 bites és a felső 16 bitet nem (használja) csak az alsót shifteli, az eredmény hibás lesz....
>>
>> Ha long x... akkor látszik igazán a metematikai zsenialítása (szenialítása:-)
>> 4D7C B98002 mul.ss w0,w2,w0
>> 4D7E DE0044 lsr w0,#4,w0
>> 4D80 200001 mov.w #0x0,w1 ;//itt törli a felső 16 bitet
>> 4D82 DD0A4C sl w1,#12,w4
>> 4D84 DE0044 lsr w0,#4,w0
>> 4D86 720000 ior.w w4,w0,w0
>> 4D88 DE88C4 asr w1,#4,w1
>> 4D8A 884FC0 mov.w w0,0x09f8
>>
>> mivel optimalizálva van a fordítás, és később csak 16 biten használom így látja, hogy nem kell csak az alsó word-t menteni. Röviden törölte shiftelte a semmit és még nem is használta.
>>
>>
>> Ha bármelyik tényezőt cast-olom:
>>
>> x = (((unsigned int)(Aset.ICBUF32>>12)) *((unsigned long) ASETS_DAcom))>>4;
>>
>> 4D6E 804F20 mov.w Aset,w0
>> 4D70 804F31 mov.w 0x09e6,w1
>> 4D72 DD0944 sl w1,#4,w2
>> 4D74 DE004C lsr w0,#12,w0
>> 4D76 710000 ior.w w2,w0,w0
>> 4D78 DE08CC lsr w1,#12,w1
>> 4D7A 200001 mov.w #0x0,w1
>> 4D7C 8050C2 mov.w ASETS_DAcom,w2
>> 4D7E DE91CF asr w2,#15,w3
>> 4D80 07DABD rcall __mulp32eds3
>> 4D82 DD0A4C sl w1,#12,w4
>> 4D84 DE0044 lsr w0,#4,w0
>> 4D86 720000 ior.w w4,w0,w0
>> 4D88 DE08C4 lsr w1,#4,w1
>> 4D8A DE8044 asr w0,#4,w0
>> 4D8C 884FC0 mov.w w0,0x09f8
>>
>> Igy jó az eredmény, de még van egy halom PUSH és POP amit nem szeretnék..... kicsit tovább tart a másik tökéletesen kiszámítja de nem ismeri fel hogy még van az eredményben tartalék.
>>
>> -----------------------------------------------
>>
>> Nagyon nagy kár, hogy a segíteni akarnak a programozóknak minél kevesebb hibát elkövetni, ahelyett hogy megtanítanák a programozókat programozni. A C-ben a korlátok kikerülése több energiát és időt igényel mint a maga a programozás.
>>
>>
>>
>>
>>
>> Huu, ez kissé zavaros.
>> Felső 16 bit törölve?
>> Utána long-ban?
>> Castolás átteszi szoftver rutinba?
>> Vagy csak én vagyok nagyon gyenge?
>>
>> 2010/4/4 hg12345 <hg12345 at freemail.hu>:
>>> Hi C-ben kikerülhető valamilyen módon, hogy 16bit * 16bit eredmény valóban 32 bit legyen? MPLAB C (GCC 4.03) elvégzi a szorzást az eredmény tényleg 32 bites (ez HW csinálja) majd ami biztos alapon a gyorsan törli a felsö 16 bitet és az így kapott eredményt tárolja egy long változóban. A művelet elött castolom akkor jó az eredmény, nem véletlen mert 32b * 322b szorzást csinál és HW helyet szubrutin.... A fordító program írói nem ismerték a szorzás tulajdonságát?! Üdv
>>>
>>> Fuzesi Arnold <arnold.fuzesi.lista at gmail.com> írta:
>>>>Mindegymihez, c-ben kellene.
>>>>
>>>>Bsd-s tipp ugy nez ki jolesz, koszi!!
>>>>
>>>>
>>>>Arnold
>>>>
>>>>
>>>>On 2010.04.04., at 1:39, Pipi <lista at puzsar.hu> wrote:
>>>>
>>>>> 2010.04.03. 20:23 keltezéssel, Fuzesi Arnold írta:
>>>>>> Sziasztok!
>>>>>>
>>>>>> Hol talalok strcpy strcmp stb stb forrásokat!?
>>>>> mihez?
>>>>> pl c:\MCC18\src\extended\stdclib\strcpy.asm
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Pipi
>>>>> http://www.puzsar.hu
>>>>>
>>>>> -----------------------------------------
>>>>> elektro[-flame|-etc]
>>>>
>>>>-----------------------------------------
>>>> elektro[-flame|-etc]
>>> -----------------------------------------
>>> elektro[-flame|-etc]
>>>
>>
>> -----------------------------------------
>> elektro[-flame|-etc]
>>
>> -----------------------------------------
>> elektro[-flame|-etc]
>>
>
> -----------------------------------------
> elektro[-flame|-etc]
>
> -----------------------------------------
> elektro[-flame|-etc]
>
-----------------------------------------
elektro[-flame|-etc]
More information about the Elektro
mailing list