[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