Fórum témák
» Több friss téma |
Sziasztok!
Mi a véleményetek, hogyan lehetne kettes számrendszerben (majdan PIC segítségével) szorozni, osztani tetszőleges nem egész számokkal. Olyasmi kellene mint pl: 759*2,47 vagy 897/5,29. A paraméterek a program futása során képződnének. Nyilván több byte ot kell majd használni a feladatra. Lényeg most a számábrázolás és a matematikai háttér megalkotása volna.
Hogyan keletkezik a tört érték?
Kettes számrendszerben, úgy érted Assembler nyelven akarod programozni?
Ha fix tizedes kell, akkor a legegyszerübb ha egészként ábrázolod a számokat, két tizedesnél a 100-szorosukat tárolod és megjelenitésnél kiteszed a tizedesvesszőt. Egész osztó és szorzó rutinokat találni, pl: szorzás osztás
Arra figyelj, hogy a 100-as szorzót osztáskor és szorzáskor korrigálni kell és a korrigált értéteknek is bele kell férni az ábrázolási tartományba(n bit). Tehát: A * B -t úgy számolod, hogy A * B / 100 A / B -t úgy, hogy (A * 100) / B itt A és B az eredeti két tizedesjeggyel ábrázolt számok 100 szorosai. Kiiráskor fixen az utolsó két számjegy átt a vessző után. Ha nem fix tizedes kell akkor lebegőpontos ábrázolás kell, googlellel könnyen találsz hozzá kész osztó és szorzó rutinokat, de lassab, meg nem mindig pontos.
Szia!
Jól dokumentált, kipróbált assembly rutinok gyűjteménye, sokat sikerült nagyon kis energia befektetéssel működésre bírnom, átírnom. (32 bites előjel nélküli szám osztása 16 bites előjel nélküli számmal: 34 utasítás és 8 ram, 24 bites bináris szám -> 32 biten tárolt 8 digites bcd kódra: 33 utasítás és 8 ram, stb) Szia
Ez a téma hajdan a számítástechnika őskorában (60-as évek) komoly probléma volt még, és részletes irodalommal rendelkezett. Ma már a processzorgyártó cégek fönntartják maguknak az a vélt jogot, hogy ezek az algoritmusok (a jobbak) a fiókjaiban porosodjanak, és ne legyenek olymódon közkincsek, mint akkoriban voltak. Ezért nehéz jó irodalmat találni ma róluk.
Sokféle megoldás létezik. Az egyik (gege997-é) valóban a fixpontos mód egyike amely megtalálható a mai programnyelvek CURRENCY adattípusainál, csak ott a 10000-szeresét tárolják az értéknek. A fixpontos ábrázolásnál - általánosan - több bájtot használunk a szám tárolásához, és a kettedes-pontot (kettes számrendszer!) fixen meghatározzuk, hogy hol foglal helyet. Azaz nem csak a szám legvégére tehetjük (ez az egész számként értelmezés), hanem bármelyik két bit pozíció közé. Szokás pl. az előjel bit után helyezni, akkor a számokat 0 és 1 között tudjuk csak értelmezni, és az egyes bitek a 2-nek negatív hatványaihoz kötődnek (mint tízesben a tizedestörtek). Ha valahova középre tesszük, akkor lehet egész részünk is és kettedes törtrész is. A fixpontos ábrázolásnál azt, hogy melyik pozícióban van a kettedes pont - skálaszámnak nevezzük. Összeadásnál, kivonásnál arra kell ügyelni, hogy az egyik operandust toló műveletekkel (rol,ror) a másik skálaszámába toljuk (ugyanott legyen a kettedes pont), majd így végezzük el a műveletet. Ez a tolás csak akkor kell, ha az operandusok skálaszámai különböznek. Szorzásnál nem kell tolás, de a skálaszámok az eredmény esetében összeadódnak! Osztásnál pedig értelemszerűen kivonódnak, tehát nem ott lesz a kettedes pont ahol az operandusok (A hagyományos egész ábrázolásnál a skálaszámok mind 0-ák, így az eredmény is 0 skálában marad). A lebegőpontos ábrázolásnál külön tároljuk a számnak az u.n. mantisszáját, amelyet tolással a 0.5 és 1 közötti értékbe hozunk úgy, hogy a kettedes pont az előjel után van. Külön tároljuk az u.n. karakterisztikát, amely az az érték, amennyivel a tolást elvégeztük (lehet negatív is). Pl. az első 3 bájt a mantissza, a negyedik a karakterisztika (ez utóbbit egésznek képzeljük). A lebegőpontos ábrázolással a műveletek meglehetősen bonyolultak, és sok buktatót rejtenek. Figyelni kell a túl- ill. alulcsordulásra, illetve a műveletvégzés végén el kell végezni az u.n. normalizálást. Ez utóbbi azt jelenti, hogy az eredmény mantisszája lehet, hogy nem esik a 0.5 és 1 érték közé, és oda vissza kell hozni tolással, és a karakterisztika módosításával. A normalizálást azért kell elvégezni, mert ha nem tesszük, akkor redundáns módon, de nem a legpontosabb formájába kerül tárolásra a szám, és a műveletek során ez a pontatlanság felhalmozódhat. Külön részprobléma a kerekítés, mivel általa a normalizált számból normalizálatlan (sőt túlcsordult) szám válhat. Ezért létezik pl. a logikai kerekítés, ahol az eldobott kettedes jegyek legmagasabb pozícióján lévő bitjével csupán logikai vagy műveletet és nem összeadást végzünk el. Jó szokás, a lebegőpontos ábrázolásnál, hogy a műveletek realizálása során több bittel dolgozunk, mint a tárolt mantissza. Pl. a fönti 3 bájtos mantissza esetén a belsőleg fixpontosan végrehajtott műveleteket 4 bájtosan végezzük el, majd kerekítünk. Szokás pl. a karakterisztikát eltolt nullpontúan tárolni a kettes komplemens helyett. Ekkor az értékének az előjel bitje negáltan jelentkezik (pl a 00000000 bináris érték helyett 10000000). Ez előnyös, mivel a legkisebb ábrázolt számra (0-ra) tároláskor tiszta 0 jön ki, tehát nem a 2-es komplemensbeli legkisebb negatív érték lesz a karakterisztikában (10000000). Amit itt leírtam az csak a vázlatos töredéke a téma terjedelmes irodalmának. De ebbe a beszélgetzős topikba még sokminden belefér a későbbiekben... Én úgy gondolom, hogy érdemes ezekről a kérdésekről eszmecserét folytatni, mert rengeteg dolog "feledésbe" merült, és előfordulhat, hogy a gyári rutinok nem mindíg megfelelőek, pl. azért mert az ábrázolási pontosság, vagy a tárolható legnagyobb érték nincs összhangban az általunk kívánttal, illetve a rendelkezésünkre álló memóriaterülettel.
Köszönöm az eddigi válaszokat.
Idézet: „Amit itt leírtam az csak a vázlatos töredéke a téma terjedelmes irodalmának. De ebbe a beszélgetzős topikba még sokminden belefér a későbbiekben... Én úgy gondolom, hogy érdemes ezekről a kérdésekről eszmecserét folytatni, mert rengeteg dolog "feledésbe" merült, és előfordulhat, hogy a gyári rutinok nem mindíg megfelelőek, pl. azért mert az ábrázolási pontosság, vagy a tárolható legnagyobb érték nincs összhangban az általunk kívánttal, illetve a rendelkezésünkre álló memóriaterülettel. ” Igaza van "tcs52" nek is, a kérdés tovább gondolható.
Én is belemehettem volna hosszas boncolgatásba, de inkább kérdeztem, amire nem válaszoltál!
Hogyan keletkezik neked a tört szám? (nem mindegy, hogy valaminek az eredménye, vagy egy konstans) Egyébiránt az oldalamon találsz matematikai alapműveleteket kicsit másképp megmutatva, lépésről lépésre.
Osszeadsz es kivonsz ,"sokszor" nagy sebessegel .
759 es 247 -szer hozzaadod a 759-et majd a tizedes vesszot kettovel balra "tolod" .Szoval egy algoritmus .valahogy igy kell elkepzelni.Mar reg nem foglalkoztam ilyesmivel mag a Z80 idejebol.
Én úgy gondolom, hogy a témanyitó nem konkrét feladat megoldása iránt érdeklődik, és ezért nyitott inkább beszélgetős - nem pontra menő - témát...
Sziasztok!
Az előző hozzászólásomban belinkelt lapon olyan rutinik találhatók, amik sokkal hatékonyabban működnek. két n bites szám szorzása megoldható egy n-szer lefutó ciklusban, ugyanígy az m bites szám osztása m bites számmal is megoldható egy m -szer lefutó ciklusban. Érdemes nézegetni, mert nem mindegy, hogy a program 759-szer, 247-szer vagy 16 -szor futtat le egy ciklust (még akkor sem, ha a ciklus egy-két utasítással többet tartalmaz). Sziasztok
Attól még válaszolhatna, ha kérdezik... Na mindegy, jó csevegést...
Hali!
saját magam úgy oldom meg az osztás és szorzás problémáját a PIC-ben, hogy a gondolkodásmódomat egyszerűen "átállítom" 16-os (2) számrendszerbe. Mivel a proci beolvasott adatai is kettes számrendszerben vannak, így könnyen megoldható a tized század fogalma, csak ugye 2.56 szor pontosabb az érték. Maradjunk a példádnál ! A 759* 2.47 nél. A kicsi szám nyílván egy állandó, amivel kellene a beolvasott értéket megszorozni, hogy kijöjjön egy adott eredmény késleltetés stb. a 2.47-et feszorzod 256-al azaz 8 bittel eltolod (h 02 78 ) és ezt kell megszorozni a 759-cel ( h 2 f7 ) az eredmény( h 07 51 c8) ebből el kell hagyni az utolsó 8 bitet.Az eredmény ( h 07 51 ) 1873 tehát igy sem pontos az eredmény, de picnél szerintem jó. Tehát ne az adott tizedestörttel osszál szorozzál, hanem annak 8 bittel eltolt (*256) étrékével. példa 8x8 bit: ;SZORZÁS 8X8 BIT W(szorzandó) ÉS MLO(szorzó) EREDMÉNY M1LO ÉS M1HI ; SZOROZ8: CLRF M1LO ;eredmény alsó nullázás CLRF M1HI ;eredmény felső nullázás MOVWF W1 ;szorzó elmentése MOVLW 0X8 ;8 ciklus MOVWF SZ ;számlálóba MOVFW W1 ;szorzó a w-be SZ03:CLC ;c flag törlése RLF M1LO ;eredmény *2 (16 bit) RLF M1HI RLF MLO ;szorzó eltolása 1 bittel JNC SZ04 ;ha a kilépő bit magas, szorzandót ADDWF M1LO,F ;hozzáadjuk az eredményhez JNC SZ04 ;túlcsordulás korrigálása INCF M1HI SZ04 DECF SZ ;számláló csökkentése JNZ SZ03 ;ha nincs vége vissza RETURN ;eredmény m1lo és m1hi regiszterben. ez könnyen kibővíthető 16 bitesre is .(te is dolgozzál) osztás: ; 16 bit osztása 8 bittel ;osztandó mlo és mhi ;osztó = w ;eredmény M1LO ÉS M1 HI ; OSZT: CLRF M1LO CLRF M1HI ;ELŐZŐ EREDMÉNY NULLÁZÁSA XORLW 0X00 ;HA AZ OSZTÓ NULLA,AKKOR VÉGE JNZ O01 ;ugrás ha nem zero RETURN O01 MOVWF W1 ;OSZTANDÓ ELMENTÉSE MOVLW 0X10 ;CIKLUSSZÁM SZÁMLÁLÓBA MOVWF SZ ;számláló CLRF MSR ;segédregiszter nullázás O04 MOVFW W1 CLC RLF MLO ;1 BIT ELTOLÁS RLF MHI RLF MSR JNC O02 ;ha túlcsordulás történtakkor SUBWF MSR,F ;biztosan kivonható az osztó SEC O03 RLF M1LO ;és eltároljuk az eredményben RLF M1HI DECFSZ SZ ;számláló csökkentése GOTO O04 RETURN O02 SEC SUBWF MSR,W JC O05 ;MÁR MEGVAN az osztó az osztandóban GOTO O03 O05 MOVWF MSR ;maradék a sgédregiszterbe. GOTO O03 A két szubrutint magam készítettem, és lehet más matekot tanult emberke egyszerűbben megoldotta volna, de egy vill. szerelőtől ennyi telik. Minden esetre ez működik.Könnyen bővíthető 24bitre vagy bármire. vegyél elő egy papírt és ceruzát. Írd le egy szorzást kettes számrendszerben, pl.: 11001111 * 10001101 és egyből rájössz a szozás lényegére csak ezt kell leprogramozni. Ha lcd kijelzőn kell kiiratni a számot. akkor ugye ígyis úgyis át kell alakítani bcd számmá. Erre is van rutin. Ha nem akarsz olyan nagyon pontos értékeket, akkor bináris eltolással egyszerűen osztható egy szám pl 1\8-ára 1/32 stb. Remélem segítettem. Üdv. Foxi
A témanyitóban ez áll:
"Lényeg most a számábrázolás és a matematikai háttér megalkotása volna..." Én megértem az aggályokat, és azt is, hogy egy pontos feladatmegfogalmazás nagyon jól előre tud vinni egy konkrét esetben. Sőt, ilyenkor az általánosságok helyett - melyeket az utóbbi hozzászólások javasolnak - gyakran olyan feladatspecifikus megoldások is születhetnek, amiknek gyakran már semmi közük sincs az eredeti - vélt - feladathoz. Én is így szoktam tenni, és ezért nem is itélem el, hogy pontosító kérdést tettél föl. Ám a lentiekben most nem neked, hanem MINDENKINEK írom a véleményemet, ami talán nem csak süket fülekre talál: (OFFTOPIC) Az, hogy egy témanyitó tájékozatlan (ami gyakran csupán a fiatal voltából ered), könnyen megbocsájtható, mindenki így kezdte valamikor. Az azonban, hogy a tájékozatlanság egy adott témában abból ered, hogy az ismereteket dugdossák az emberek elöl, és ami még néhány évtizede tudományos közkincs volt, azt most csak kemény pénzekért lehet megszerezni - gyakran csak a kiváltságosaknak - már nem megbocsájtható. Akár bűncselekménynek is nevezhetjük, de ma törvény biztosítja, hogy ilyet bárki megtehet. Ennek tudatában erősen megkérdőjelezhetők azok, a nap mint nap előforduló reakciók, amikor egy feladat esetében nem megoldásokon gondolkodunk, hanem csípőből kész lehetőségekkel (esetleg fizetős is) kedveskedünk. Sokaknak nagyon fájdalmas lehet az, hogy egyesek gondolkodni is képesek, nem pedig csak prakticista módon alkalmazni a bevált és megvásárolható módszereket. Fájdalmas, hogy újra napvilágra kerülnek az elfeledett algoritmusok, gyakran kínkeservesen újra kitalálva és újra közkinccsé válva. Szerintem a HE fóruma nagyszerű hely arra, hogy megtanítson gondolkozni is, tehát teret kell nyújtani ezen kiváló - és kizárólag emberi - érték számára. Én tehát azt javaslom, hogy mindenki nézzen magába, és bátran írja le okos gondolatait, ötleteit, vagy rejtegetve őrizgetett tudását. És minél több helyen ossza meg társaival! Ha valamit már az utcaseprő is a sarkon fütyörész, azt nem tudja már senki sem titokban tartani, vagy ne adj isten, jó pénzért eladni. Aki meg nem ezt teszi az vagy: 1. Tudását félti mások elöl, hogy csak egydül ő legyen olyan helyzetben, akire számítani lehet vagy: 2. Anyagi hasznot akar olyan dologból húzni amely minden emberé (közkincs), és ingyen kellene bárkinek hozzáférnie. Mindkét féle hozzáállásnak van rendes neve is, és mégha az egész világon is törvényeket hoznának mellettük, akkor is lényegében erkölcstelenek. Tényleg: mikor hoznak már törvényt arra, hogy tilos az iskolában ingyen megtanítani a szorzótáblát?... (ONTOPIC)
Látom aktívvá vált a fórum, köszönöm minden hozzászólónak.
Watt dorgálását elfogadom, és kérdésére meg is adnám most a válszt. Idézet: „Hogyan keletkezik a tört érték? Kettes számrendszerben, úgy érted Assembler nyelven akarod programozni?” Idézet: „Én is belemehettem volna hosszas boncolgatásba, de inkább kérdeztem, amire nem válaszoltál! ” Tört értékem úgy keletkezik, hogy lesz egy fix számom (1000), azt kell majd elosztanom egy számláló álltal megszámolt értékkkel, majd a kapott hányadost szorozgatni a resetelt számláló aktuális értékével. Igen Assembler nyelvű programot szeretnék hozzá gyártani. tcs52 nek is igaza van, igaz én mérsékeltebb vagyok ezen a téren. Vagyok, mert sok esetben a megoldáson gondolkodás és a kész lehetőségek felmutatása nehezek különíthető el egymástól. Nem szeretnék ezekkel a gondolatokkal további inkább filozófikus hozzászólásra sarkallni senkit, de az ilyen (HE) jellegű fórumok pont abba az irányba hatnak, hogy a tudás anyagi haszon nélkül is megszerezhető legyen, azt eltikolni, visszatartani egyre nehezebbé váljon. Biztos vagyok benne, hogy ennek szellemében született már megannyi hozászólás.
Megemlítek egy nagyon érdekes algoritmust, melyet már más fórumban is ismertettem.
Ez nem szorzás/osztás ugyan, hanem logaritmus és hatványfüggvény, ám ezekkel végrehajtható az ismert logaritmikus azonosságok szerint a szorzás ill. az osztás is! Az algoritmusok nem használnak szorzást és osztást, hanem minden csak összeadással, kivonással történik. Ott ahol szükség van ezekre a függvényekre is, és nem számít a szorzás/osztás sebessége (mely így lassabb lesz mint a függvények) jól hasznáható. Az ismertető 10-es alappal dolgozik, de könnyen átértelmezhető 2-es, 8-as vagy 16-os számrendszerbe (ugyanilyen alapú logaritmushoz ill. hatványhoz), így PIC-eken könnyen programozható. Ezt az algoritmust több évtizeddel ezelőtt, másodkézből hallottam (azóta se láttam sehol), és csak azért ragadt meg bennem, mert egy szinte zseniális ötleten alapult. Valószínűleg ez az ötlet is ott porosodik valamilyen cég titkos irattárában, régen elfelejtve, hogy egyáltalán létezik is ilyesmi.
Szia!
Sokszor kell egy 0..15 közötti értéket hexadecimális számjegy karakterré konvertálni.
Sajnos a PIC16 családban csak a legújabb tagjaiban van addwfc, de még ezekben sincs daw...
Ez már lényegében csak 4 utasítás és nincs benne ugrás. Szia
Sziasztok!
Olvastam a témát, tetszett a logaritmusos cucc is... Atmel vonalon programozgatok, és a programjaimhoz saját magam programoztam le az aritmetikai algoritmusokat. Szívesen megosztanám a forráskódjaimat, azonban ezzel az lesz a baj h. bármit szeretnél változtatni, nem fog menni, ahogy pl. PIC-re átültetés is nehézkes lenne. Meghagyom a gondolkodás jogát mindenkinek. Nekem kb. 20 órányi munkával sikerült leprogramoznom az egészet, szóvel nem nagy cucc... Aki mikrokontrollerrel akar szorozni/osztani, nem ártana először elővenni a kis általános iskolai füzetet. Igen, azt. Mi is a szorzás és osztás? Ismételt összeadás ill. kivonás! Előbb nézzük az összeadást/kivonást, ezek az alapműveletek amelyek a leggagyibb mikrokontrollerben is megtalálhatóak. Mondanom se kell, ugyanúgy kell elvégezni: 0-s és 1-es összead, ha 1+1 akkor 0 lesz és maradék:1; Kivonásnál ugyanaz... Na most nem bitenként kell összeadni/kivonni, hanem egyenesen 8(v. 16) biten kedvenc kontrollerünk elvégzi a műveletet. Én először 32 bites aritmetikával dolgoztam, amit kb. 20 perc alatt átírtam 64-esre. A megoldás: össze kell adni a legkisebb helyiértéken, majd a carry-t hozzá kell adni a következő helyiértékű összeadás eredményéhez. Ez egy egyszerű ciklus. Kivonásra tökugyanazt kell elvégezni, alacsonyabb helyiértékről indulni. Fontos művelet a ROTÁCIÓ, vagyis a 8*n bites szám körbeforgatása jobbra vagy balra. Ez egy egyszerű SHR vagy SHL művelet ciklusban végezve, és a carry-t mindig becsurgatjuk vagy a felső, vagy az alsó bit helyére, attól függően hogy jobbra vagy balra tolunk. Illetve a TOLÁS-ra is szükség lesz. Itt az a különbség, hogy továbbra is át kell vinni a carry-t a köv. helyiértékre, de a legutolsó carry már nem kerül át az átellenes oldalra, azaz pl. 64 bites szám és jobbra tolás esetén alegkisebb helyiérték korábban 0. bitje nem kerül át a legnagyobb helyiérték 7. bitjének helyére. A szorzást/osztást úgy végeztem el, hogy a teljes művelet mindössze 3 szám ábrázolására szükséges tárhelyet igényeljen. Éltem az igénytelenség azon esetével, hogy bármely művelet első tényezője a művelet kimenete is lesz egyben, míg a második tényező sértetlen marad. Összeadásnál és kivonásnál is ugyanez a helyzet. Szorzás: Van 3 számunk: SZORZANDÓ, SZORZÓ, EREDMÉNY. Az EREDMÉNYt le kell nullázni. A SZORZÓt jobbra fogjuk körbeforgatni, ciklusban. Annyiszor, ahány bites a szám. A ciklus így néz ki: ha a SZORZÓ legkisebb bitje 1, akkor a SZORZANDÓt hozzáadjuk az eredményhez, egyébként nem adjuk hozzá. Ezután a SZORZÓT jobbra ROTÁLJUK, a SZORZANDÓt pedig balra TOLJUK. A legvégén az eredményt átmásolom a SZORZANDÓ-ba. Mivel a SZORZÓt annyiszor ROTÁLtuk ahány bites, sértetlen maradt! Osztás: Kicsit bonyolultabbnak tűnik, de trükkösebb ha tényleg csak 3 számnyi tárat akarunk használni. Szükség lesz az összehasonlítás műveletére(nagyobbegyenlő) is, ezt előtte külön le kell programozni. Tényezők: OSZTANDÓ, OSZTÓ, MARADÉK. A kimenet az OSZTANDÓba kerül. Ha érdekel valakit, előkeresem a kis füzetkémet, mert nem emlékszem rá tiszán. Amúgy itt is az általános iskolai osztást kell elvégezni, csak éppen 2-es számrendszerben...
Hali!
előző oldalon pont ezt találod meg "pic"-ben megírva...
Oké hogy megtalálom, de egy PIC-hez frászt sem konyító emberke biztosan nem fogja megérteni, márcsak a dokumentálás adott szintje miatt sem.
Én a saját magam által kitalált algoritmussorozat lépéseit közöltem le, mellyel BÁRMELY mikroprocesszorra megírható egy egyszerű kód. Én arra megyek hogy más is megértse amit lepötyögök a billentyűzeten, végülis arról szól ez a topik, nemdebár? Forráskódot bárhol lehet találni, értelmes leírást(magyarul) már annál nehezebb... |
Bejelentkezés
Hirdetés |