Stránka 1 z 2

NEzobrazování mrtvývh nul ve výsledném čísle na displeji.

Napsal: 03 lis 2019, 21:39
od DavidChlup
Ahoj,

mám tu další oříšek, mám tu převod 16bit binárního čísla přímo na ASCII. Principu rozumím, ale nevímm jak se zbavit těch nepotřebných nul před hodnotou. Když tam mám např číslo, jehož převod je 300 (dec), tak mi to vyzobrazí 00300. Určitě existuje nějaká finta, jak to vyrušit, dokud budou první výsledky v REG "nulové".

Kód: Vybrat vše

d5ascii: 
   ldi reg, $2F          ;Init ASCII conversion ('0'-1)
loop10k:
   inc reg               ;count up 10k "counts"
   subi ZL, $10
   sbci ZH, $27
   brcc loop10k           ;IF >=10000 THEN subtract again
   subi ZL, $F0           ;subtract -10000 (add 10000)
   sbci ZH, $D8
   rcall senddata              ;send 10k ASCII char

d4ascii:
   ldi reg, $2F          ;Init ASCII conversion ('0'-1)
loop1k: 
   inc reg               ;count up 1k "counts"
   subi ZL, $E8
   sbci ZH, $03
   brcc loop1k            ;IF >=1000 THEN subtract again
   subi ZL, $18           ;subtract -1000 (add 1000)
   sbci ZH, $FC
   rcall senddata      

d3ascii:
   ldi reg, $2F          ;Init ASCII conversion ('0'-1)
loop100:
   inc reg               ;count up 100 "counts"
   subi ZL, $64
   sbci ZH, $00
   brcc loop100           ;IF >=100 THEN subtract again
   subi ZL, $9C           ;subtract -100 (add 100)
   sbci ZH, $FF
   rcall senddata      
                  ;(ZH==0) so ignore ZH from here

d2ascii:
   ldi reg, $2F          ;Init ASCII conversion ('0'-1)
loop10: 
   inc reg               ;count up 10 "counts"
   subi ZL, $0A
   brcc loop10            ;IF >=10 THEN subtract again
   subi ZL, $F6           ;subtract -10 (add 10)
   rcall senddata      
   mov reg, ZL
d1ascii:
   subi reg, $D0           ;convert 1's digit to ASCII
   rcall senddata      
   ldi reg, ' '
   rcall senddata              ;send out a space
   ret

Napsal: 03 lis 2019, 22:25
od samec
Myslím, že loop1M, prípadne loop10M a niečo v ňom by to mohol vyriešiť.

Napsal: 04 lis 2019, 17:02
od petrfilipi
Nemůžeš provést typovou konverzi String na Integer?
Jaký typ je výsledek? Je to Integer (=číslo) nebo String (=text)?

PF

Napsal: 04 lis 2019, 17:21
od termit256
Az to cislo budes mit prevedene do ascii proste kontroluj zleva jednotlive cislice a pokud to bude nula, nahrad ji mezerou. Pokud to bude jine cislo nez nula, ukonci kontrolu. Nevim v cem vidis problem.

Napsal: 04 lis 2019, 17:42
od petrfilipi
Ten program funguje tak, že předpokládá číslo max. 99999. A odečítá 10000 tolikrát, až se dostane do záporných čísel. Přitom počítá, kolikrát odečetl těch 10000. Když se dostane do mínusu, přičte 10000, odečte 1 z počítadla desetitisíců a má počet desetitisíců. To samé pak dělá s 1000, to samé se 100, s 10 a pak mu zbyde počet jednotek. Takže na konci každé odečítací procedury bys měl kontrolovat, zdali není výsledek 0. Pokud je, neodesílat nic (nebo mezeru), jinak odesiláš počet v počítadle odečítání.
Nebo bys mohl na začátku odečítání kontrolovat, zdali je číslo vyšší než 10000. Pokud ano, odečítá s. Pokud ne, nevracíš nic (nebo mezeru).

PF

Napsal: 04 lis 2019, 18:13
od petula
vtip je v tom, že nemáš sestavený algoritmus a projekt, ale hned kóduješ program "z hlavy". Kdyby jsi postupoval řádně, sepsal nejprve algoritmus a projekt programu, a teprve potom podle projektu zakódoval program, tak by jsi tyhle potíže neměl.
Jenže to je důsledek pofiderní rychlokvaškové výuky na českých školách. Začíná se od konce, vše se dělá "zadkem napřed", obráceně. Programy se zhotovujé bez projektu, bez algoritmů, kódováním z hlavy.

Představ si, že by jsi stejným způsobem stavěl dům, bez projektu. Skládal by jsi cihly z hlavy, tak jak tě napadne. To by byly konce, co? :D Anebo by jsi takto bez projektu tvořil auto. Prostě by jsi bez výkresů, bez projektu soustružil, frézoval díly a snažil se je sestavit a chtěl, aby vzniklo jezdící auto. Ve strojírenství a stavařině si bez projektu troufnou pracovat leda tak blázni. V elektronice a prgramování to je v Česku "normální".

Napsal: 04 lis 2019, 18:29
od termit256
Co je to za vyraz "zakodoval program" :-) ? To jsi slysel v nejakem serialu na Nove?

Ja zadne projekty ani "algoritmy programu" nezakodovavam, ale na ty nuly proste vzdycky zapomenu. Tech par radku na jejich vymazani dopisu az je uvidim na displeji.

Napsal: 04 lis 2019, 19:50
od lesana87
Když se použije pro převod/zobrazování čísel algoritmus dělení deseti (obecně základem č. soustavy) dokud není podíl 0, problém s nevýznamnými nulami nevzniká.

Napsal: 04 lis 2019, 22:05
od Osmdesat
Jak píše lesana, v cyklu děl číslo deseti, podíl schovej pro další dělení, zbytek vždy vem a přičti k němu ASCII hodnotu znaku "0" a "předpoj" k výstupnímu řetězci. Jakmile je podíl 0, skonči. Pokud chceš zarovnávat napravo, vpisuj číslice do předpřipraveného řetězce pevné délky vyplněného mezerami.

Napsal: 04 lis 2019, 22:12
od rnbw
No ak ten procesor nema instrukciu delenia...
Vkladanie znakov na zaciatok retazca nie je uplne jednoducha operacia.

Pridal by som tam nejaky flag - na zaciatku vynulovat. Pokym nie je nastaveny, namiesto nuly generovat medzery. Pri nenulovom cisle ho nastavit.

Napsal: 04 lis 2019, 22:39
od ZdenekHQ
Ovšem pokud procesor má instrukci dělení, je dělení 10 pro n-bytové číslo víceméně triviální záležitost na pár řádků. Zbytek po dělení se přes push uloží do stacku, načež se pozpátku vyzvedne a dokud jsou nuly, zobrazuje se mezera. První nenulové číslo nastaví flag a pak už se nuly zobrazují, nesmí se ale zapomenout na poslední místo, kde už se nula musí zobrazit, pokud je číslo nulové.

Dá se tam i přihodit desetinná tečka (fakt nemám rád čárku) a podobné operace...

Napsal: 05 lis 2019, 09:21
od petula
tady jsou dva podprogramy, které normálně používám. První je pro integer 16-místné číslo a druhý pro real 16-místné číslo. V real číslu se musí detekovat desetinná tečka, aby se nemazaly nuly v případě hodnoty 0.00.
Princip dekodování vychází z hardwarového řazení obvodů 7447, které zháší nevýznamné nuly hardwarově.

pro 16 mistny integer:

sub leadzero [P]
for i=15 to 1 step -1; if P[i]=0; sf[i]; ascii(127)->P[i]; ret[P];
cf[i]; next; ret[P];
endsub;

pro 16 mistny real:

sub leadzero [P]
for i=15 to 1 step -1; if P[i]="."; ret[P];
if P[i]=0; sf[i]; ascii(127)->P[i]; ret[P];
cf[i]; next; ret[P];
endsub;


v assembleru p-proměnných 1 podprogram vypadá takto:

cyci{0f};dec i;eqz{P[i]};1->f{i};00h->{P[i]};rtn{P[i]};
0->f{i};rtcy-1;rtn{P[i]};


2. podprogram se liší pouze tím, že se detekuje desetinná tečka, tedy příkazy

....
eq{P[i]}=00101110b;0->f[i];00h->{P[i]};rtn{P[i]};
0->f{i};rtcy-1;rtn{P[i]};

Napsal: 05 lis 2019, 15:35
od Mahoney
termit256 píše:Az to cislo budes mit prevedene do ascii proste kontroluj zleva jednotlive cislice a pokud to bude nula, nahrad ji mezerou. Pokud to bude jine cislo nez nula, ukonci kontrolu. Nevim v cem vidis problem.


Jde to ještě jednodušeji, není potřeba žádných kontrol ani jiných algoritmů. Prostě při úvodní inicializaci naplní proměnné pro displej (kromě řádu jednotek) místo nulami prázdným znakem, to je celé (tedy za předpokladu, že začíná od nul, tedy pokud např. nenačítá poslední použitou hodnotu z EEPROM a podobně, a taky za předpokladu, že s proměnnými pro displej neprovádí výpočty, např. inkrementaci, ale jen do nich zapisuje hodnotu).

V jednom programu jsem to řešil ještě jinak - prostě jsem nespínal tranzistory pro ovládání segmentovek, a to za podmínky "dokud není poprvé použito", tedy zařídil jsem si na to flag registr (což lze, protože první číslo "k použití" nikdy není nula, a to i když se s těmi registry provádí nějaká operace typu INC apod - tedy samozřejmě zase kromě řádu jednotek, na něj jsem tu podmínku prostě neuplaňoval vůbec).

Napsal: 05 lis 2019, 16:37
od termit256
Pokud to tak udelas, bude ti cislo pri obnovovani blikat. Ten algoritmus neni nijak slozity, je to par radku kodu.
Ja mam napsane podprogramy pro prevod do bcd, ascii a vymazani tech nul a jednoduse pouziju bez vetsiho premejsleni ty ktere zrovna potrebuju pro danou aplikaci. Ctrl+c, ctrl+v je mnohem rychlejsi nez to psat pro kazdou znovu jako soucast jedineho procesu zobrazovani.

Napsal: 05 lis 2019, 18:21
od lesana87
ZdenekHQ píše:Ovšem pokud procesor má instrukci dělení, je dělení 10 pro n-bytové číslo víceméně trviální záležitost na pár řádků.

To by mě docela zajímalo, nikdy mě žádné triviální řešení nenapadlo.