[elektro] C aritmetika?

hg12345 hg12345 at freemail.hu
Sun Apr 4 11:05:12 CEST 2010


Az eredmény unsigned int!!!!!! Ez teljesen mindegy milyen uC, de ez a 16 bites rendszerek korlátja. (a 8 bitesnél ez előbb jön elő). Ha 32 bites használnék, akkor a második sort mosolyogva megoldaná fordító.

Teljesen elvagyok szomorodva, hogy nem tudok értelmesen írni :-(

A számítás pontossága miatt minél nagyobb bitszámon végzem a műveletet annál pontosabb lesz. Az egész tologatás azért van, hogy ne így kell  csinálni.

  Aset.ICBUF32 *((long long)ASETS_DAcom) >> 16;   //(ez ezért durva)
 
közvetlen 16 bites méretű kontroller gépi kódja átírata C-re, de ez a C h tudatlansága miatt nem működik (ez rövidebb és gyorsabb, kicsit pontatlanabb)
  (((unsigned int)(Aset.ICBUF32>>12)) * ASETS_DAcom )>>4 ;

ha csak az iskolai matematikát nézem a két sor elvileg megegyezik egymással, a pontosságot kivéve, mivel a számok egészek.....

Ez első  64 bites aritmetikát használ, hogy véletlenűl se legyen hibás az eredmény (32bit * 16bit  az 48bit, de ilyen nincs a C-ben)
A második végig 16 bites aritmetikával számol és kihasználja a uC HW szorzás lehetőséget (ezt a C-be már nem tudták implementálni :-(

Méret és sebességben van némi különbség... (IT)  


Remélem most érthető.  Nem értem másoknak nem merűl fel ilyen probléma....









Nem nagyon értem a dolgot ( nehezen igazodok el az asm forráson), de  
azért belevau-zok .

32 bites x értékére van szükséged ? Akkor miért int az x ?

volatile long x;     nem segit ?

Üdv.  Zoli

ps. Gyanitom hogy ez egy PIC asm forrása. Hát, akkor már tudom, hogy életem
hátralevö részében már PIC-et biztos nem fogok használni :)  .



2010. 04. 04. 10:15 keltezéssel, hg12345 írta:
> 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]



More information about the Elektro mailing list