Stukje code wat ik niet helemaal begrijp

JoWi

Golden Member

Op donderdag 14 november 2024 14:30:16 schreef Hensz:
[...]
Ik verbaas me al meer dan 40 jaar over al die mensen die denken dat als je minder tekst gebruikt voor je source-code je dan ook compactere object-code krijgt.

Helemaal niet, ik prefix variabelen vaak met een n,d of sz om aan te geven dat het een integer,double of string (zero terminated is).
Waar ik me over verbaas is dat bij elke update van de compiler de code weer een stuk groter en trager is. In de jaren 80 had je nog wat concurrentie (Borland/Lattice/Oasys/Microsoft/Zortech) in de compilers zodat bij een compiler update je programma in een keer een stuk kleiner en sneller was. Maar dat waren dan wel optimized compilers voor een specifieke architectuur (zoals voor de MC68020)

Ignorance is bliss
Hoeben

Golden Member

Als we dan toch met mooie code bezig zijn, uit mijn oude PLM51 tijd, wel even goed data declareren (waar in sommige talen dan ook veel kracht ligt:

DECLARE xbits STRUCTURE ((BO, B1, B2, B3, B4, BS, B6, B7) BIT);
DECLARE x BYTE AT (.xbits);

dan kan dit:

if x(teller) = 0
then ...
else...

Erg leesbaar.

Arco

Special Member

Hungarian notation is (nog steeds) erg handig... (prefix dw, sz, l, w,...)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Op woensdag 13 november 2024 22:58:11 schreef benleentje:
Stel je hebt het binaire getal
1111 0000
1111 0000 >> 1 = 0111 1000
1111 0000 >> 2 = 0011 1100

enz

Alle bitjes worden naar rechts verschoven en hoeveel keer dat gebeurt dat is de waarde van teller.

Zo kan je heel makkelijk een 32 bit getal maken uit 4 bytes

32 bit getal is x

X = X + byte1
X << 8 ?? alles bitjes 8x naar links

X = X + byte2
X << 8

Uit ((x >> teller)&1) moet een 1 of 0 uitkomen om zo een waar of niet waar over te houden.

Dit is een goede uitleg, BL.

Het klopt ook met je punt dat het een gemakkelijke manier is om van 4 bytes een 32 bits getal te maken. Dat is namelijk ook wat dat programma deed.
Ik kon dat redelijk doorgronden :-)

Maar even resumerend...
De "teller" stelt hoeveel posities "x" de virtuele bytes opzij wordt geschoven om te zien of de LSB 1 of 0 is.

Ik besef me net dat daarvoor het beoogde getal helemaal nog niet als Byte uitgevoerd hoeft te zijn.
Het betreft een getal wat in zijn virtuele Byte vorm opzij wordt geduwd, waarbij na elke verschuiving de waarde wordt gematcht met "00000001", wat natuurlijk hetzelfde is als "1", zijnde het LSB.

De rest was me al duidelijk. Is het een 1, dan print hij "1", is het een 0, dan print hij "0".

Zit ik zo goed te denken?

Ik moet hier weer vaker komen... Wat kun je zo'n forum als deze gaan missen. :-)

Op donderdag 14 november 2024 14:30:16 schreef Hensz:
Dan doet de compiler er maar 3ms langer over, ik kan er niet mee zitten. Het is ook gewoon fijn dat je de compiler kunt starten, koffie kunt halen en dat ie dan nog nét niet klaar is. :+

Het kan me niet boeien hoe lang de compiler erover doet om een stukje software te compileren. Veel belangrijker is dat de gecompileerde code in een zo kort mogelijke tijd door de processor afgewikkeld wordt.
Doet mij aan goede oude tijden denken.
Ik schreef 'grote' programma's (wel kleiner dan 64kB). Die moest dan gecompileerd, geassembleerd en gelinkt worden. Bij afname vond de klant uiteraard daarin een foutje (of meerdere). Dan zei ik tegen de klant: "Kom morgen maar terug. Dan heb ik een nieuw programma". Want assembleren (met de BSO-assembler) duurde toch wel een slordige vier of meer uur. Ik had dan dus genoeg tijd om koffie te drinken. Meestal gaf je de computer op het eind van de werkdag een schop en dan had je de volgende werkdag een nieuw programma.

benleentje

Golden Member

Ik besef me net dat daarvoor het beoogde getal helemaal nog niet als Byte uitgevoerd hoeft te zijn.

Uiteraard hoeft dat geen byte te zijn. Dat kan ook 16, 32 of 64 bit zijn afhankelijk met welk platform je mee bezig bent.

Op donderdag 14 november 2024 21:50:51 schreef benleentje:
[...]

Uiteraard hoeft dat geen byte te zijn. Dat kan ook 16, 32 of 64 bit zijn afhankelijk met welk platform je mee bezig bent.

Uiteraard.

Maar ik kan gewoon 3>> loslaten op het decimale getal 8, om daar "1" uit te krijgen.
Zonder dat ik die 3>> op 1000(binair) moet loslaten.
Ik beelde het mij in dat het een 8 binair moest zijn, maar dat is puur iets visueels.

Ik moet hier weer vaker komen... Wat kun je zo'n forum als deze gaan missen. :-)

Het is >>3, maar goed.
Binnen een computer zijn alle getallen (en strings) binair opgeslagen.

Je kan ook doen alsof >>x gewoon betekent: "Deel door 2x "

Het is vergelijkbaar met "optellen" ook dan doet de computer iets "raars" met de bitjes zodat het lijkt dat a+b er uitkomt.... :-)

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/

Op donderdag 14 november 2024 22:48:19 schreef Fantomaz:
[...]

Uiteraard.

Maar ik kan gewoon 3>> loslaten op het decimale getal 8, om daar "1" uit te krijgen.
Zonder dat ik die 3>> op 1000(binair) moet loslaten.
Ik beelde het mij in dat het een 8 binair moest zijn, maar dat is puur iets visueels.

Jouw computer (of programmeertaal) is zo aardig om jou decimale getallen te laten typen, maar intern is alles natuurlijk altijd binair.

Dus 8 decimaal is 1000 binair, ze zijn 100% identiek.
Dus ja, als je

putchar((8>>3) + '0'); // of
printf((8>>3)?"1":"0");

schrijft dan wordt er dus '1' (of "1". '1' is een letter, "1" is een string) geprint.

Meep! Meep!
benleentje

Golden Member

Dus 8 decimaal is 1000 binair, ze zijn 100% identiek.

Voor ons wel maar voor een computer schijnt dat begrip een stuk lastiger te zijn.

https://www.youtube.com/watch?v=v3-a-zqKfgA

Op vrijdag 15 november 2024 09:40:49 schreef rew:
Het is >>3, maar goed.
Binnen een computer zijn alle getallen (en strings) binair opgeslagen.

Je kan ook doen alsof >>x gewoon betekent: "Deel door 2x "

Het is vergelijkbaar met "optellen" ook dan doet de computer iets "raars" met de bitjes zodat het lijkt dat a+b er uitkomt.... :-)

Oh verrek... Dat is nog een goeie eyeopener, Rew.
Want ik dacht dat "teller" X plaatsen verschoof.
Maar het was X, die "teller" plaatsen verchoof!

Ik moet hier weer vaker komen... Wat kun je zo'n forum als deze gaan missen. :-)
Hoeben

Golden Member

Als je eenmaal in hogere talen hebt gewerkt ziet C er nogal kreupel uit met al die $%^& symbolen.

Hoe een taal er uit hoort te zien voor leesbaarheid:
for teller = 0 to 7 print x(teller)

of
for teller = 7 downto 0

of object oriented
for teller = 0 to 7 x(teller).print
of x.print(teller)

Arco

Special Member

Op vrijdag 15 november 2024 22:20:09 schreef Hoeben:
Hoe een taal er uit hoort te zien voor leesbaarheid:
for teller = 0 to 7 print x(teller)

of
for teller = 7 downto 0

Je beschrijft Basic... :+
for teller = 7 downto 0 in Basic wordt for teller = 7 to 0 step -1

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Op donderdag 14 november 2024 18:20:50 schreef Arco:
Hungarian notation is (nog steeds) erg handig... (prefix dw, sz, l, w,...)

Neeeeeee help, dat is precies hoe de hungarian notation NIET bedoeld is en verkwanseld is door een paar prutsers die het niet begrepen bij M$ (en veel andere niet M$ developers). Als je een uitleg hierover wilt hebben waarom, reply maar....

1-st law of Henri: De wet van behoud van ellende. 2-nd law of Henri: Ellende komt nooit alleen.
JoWi

Golden Member

Op vrijdag 15 november 2024 23:50:57 schreef henri62:
[...] Neeeeeee help, dat is precies hoe de hungarian notation NIET bedoeld is en verkwanseld is door een paar prutsers die het niet begrepen bij M$ (en veel andere niet M$ developers). Als je een uitleg hierover wilt hebben waarom, reply maar....

Gaan we een apps versus systems Hungarian discussie krijgen? De sz prefix mag dan weer wel volgens Simony, en ik gebruik geen BCPL. Bij typeless talen is het irrelevant, maar in C af en toe toch wel handig.

Ignorance is bliss

De hongaar die hongaarse notatie bedacht... screef "type" waar hij in het nederlands de SOORT data bedoelde. Niet het datatype.

het zou dan teller_i en binaire_te_printen_getal_x worden in het onderhavige geval.

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Hoeben

Golden Member

Op vrijdag 15 november 2024 22:42:41 schreef Arco:
[...]
Je beschrijft Basic... :+
for teller = 7 downto 0 in Basic wordt for teller = 7 to 0 step -1

Ik dacht meer aan PLM en Delphi. Basic is leesbaar maar op hoger niveau niet zo gestructureerd. Gelukkig heb ik nooiot in Basic geprogrammeerd, al in de studietijd zwaar verboden. En zodoende heb ik ook nooit een GOTO gebruikt. Ik heb zelfs een hekel aan BREAK.

Arco

Special Member

Goto en Break worden allang niet meer gebruikt in een fatsoenlijk programma.
(in geen enkele taal behalve assembly wordt dat nog gebruikt)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Tja, geen switch zonder break.. Ik gebruik die heel vaak. En ook voor loops trouwens.

Arco

Special Member

Wat dat betreft is de switch (select case) statement in Basic wat meer practisch:
Na uitvoering van een select case match wordt de select case statement automatisch verlaten.

'there can only be one'... (Highlander... :+ )

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
benleentje

Golden Member

Er was ooit iemand die zei:

"alles heeft zijn voor en nadelen".

Ieder moet voor zichzelf weten wat zijn of haar favoriete programmeertaal is. Volgens mij is er nog geen software of taal wat helemaal perfect is.

Op zaterdag 16 november 2024 13:44:14 schreef Arco:
Goto en Break worden allang niet meer gebruikt in een fatsoenlijk programma.

Moet je naar de linux kernel kijken, daar zaten volgens mijn laaste telling een paar jaar geleden > 120.000 goto's in (is geen typefout!).
Met het 'devm' framework is het wel een stuk beter geworden maar nog steeds gigantisch.

Op zaterdag 16 november 2024 11:34:35 schreef rew:
De hongaar die hongaarse notatie bedacht... screef "type" waar hij in het nederlands de SOORT data bedoelde. Niet het datatype.

Ja dat bedoelde ik ook precies.

1-st law of Henri: De wet van behoud van ellende. 2-nd law of Henri: Ellende komt nooit alleen.
Hoeben

Golden Member

Op zaterdag 16 november 2024 14:13:19 schreef deKees:
Tja, geen switch zonder break.. Ik gebruik die heel vaak. En ook voor loops trouwens.

Ik dus nooit. Maar ik ben wel wel (ver)gewend aan Delphi:

Case colour of
       Red : ShowMessage('The colour is Red');
     Green : ShowMessage('The colour is Green');
      Blue : ShowMessage('The colour is Blue');
    Yellow : ShowMessage('The colour is Yellow');
  else ShowMessage('The colour is Unknown!');
end;

PLM:

Do case IQ:
 print('Dit is het IQ van een gemiddelde tiktokker');
 print('Dit is het IQ van een gemiddelde facebooker'); 
 do print('Dit wordt het IQ van een gemiddeld CO lid'); IQ = 200; end;
end;

waarbij je in PLM nog wel even de range moet checken, en PLM vanaf 0 begint, het is een tamelijk dicht bij de processor staande taal.

Goede programmeertalen hebben gewoon de juiste flow al in zich. Een case hoort maar 1 statement tussen {} uit te voeren en geen break nodig te hebben. Die break is alleen maar nodig omdat oude programmeertalen in het begin nog niet netjes waren (daar was het geen CASE maar in feite alleen maar een JUMP) en heel die ballast nog steeds wordt meegesleept.

Ik heb nog nooit in basic gewerkt, valt me dan nog mee wat ik hier zo lees.

Op zaterdag 16 november 2024 17:43:33 schreef henri62:
[...] Ja dat bedoelde ik ook precies.

Als opschrijven in 1 regel kan, dan heeft het weinig zin om te verwijzen naar elders. Zo leert iedere voorbijganger wat er aan de hand is. En omdat we hier allemaal nederlands doen, is het makkelijk omdat je "soort" kan gebruiken terwijl het voor een engels sprekende lastiger is om het onderscheid duidelijk te maken.

Op zaterdag 16 november 2024 17:43:33 schreef henri62:
[...] Moet je naar de linux kernel kijken, daar zaten volgens mijn laaste telling een paar jaar geleden > 120.000 goto's in (is geen typefout!).

Wat in een kernel heel belangrijk is, dat is de foutafhandeling. Enerzijds, alles wat fout /kan/ gaan gaat ook fout. Anderzijds, dat moet je echt goed afhandelen, anders gaat het nog erger fout in de toekomst.

Er is veel code waarbij dus een aantal stappen goed moeten gaan voordat je aan het uiteindelijke werk toekomt. Omdat enerzijds in 99.99% van de gevallen ieder van die stappen wel goed gaat en je dat dus snel wil hebben, maar anderzijds omdat je bij een fout in stap 2 ook stap 1 ongedaan moet maken, krijg je


if (! stap2_ok() ) {
    undo stap 1 ; 
    return error;
}
do_stap3 ();
if (! stap3_ok() ) {
    undo stap 2 ; 
    undo stap 1 ; 
    return error;
}

Dat escaleert en is foutgevoelig: De "undo stap1" komt 4x voor als er 5 stappen zijn. Als de compiler niet ziet dat ie de undo 4, undo 3 undo 2 undo 1 van stap5 kan hergebruiken door daar halverwege in te springen is dat met een paar gotos geregeld. Dit is de ENIGE geldige reden om goto te gebruiken.

Dat hergebruiken is tricky omdat als je het "fout" uitschrijft zoals hierboven, dan wordt het:


if (! stap3_ok ()) {
   undo stap2;  
   undo stap1; 
   return STAP3_FAILED;
}

Door die return statement is iedere keer dat stuk anders. In de praktijk staat er dan:


if (! stap3_ok ()) {
   returncode = STAP3_FAILED;
   goto undo_2_1;
}

[Bericht gewijzigd door rew op zondag 17 november 2024 10:49:54 (64%)

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
JoWi

Golden Member

Op zondag 17 november 2024 10:36:46 schreef rew:
[...]

if (! stap2_ok() ) {
    undo stap 1 ; 
    return error;
}
do_stap3 ();
if (! stap3_ok() ) {
    undo stap 2 ; 
    undo stap 1 ; 
    return error;
}

Even een voorbeeld van bovenstaande met een switch waarbij het handig is dat je een break hebt per case, want dan kan je een rollover doen:

try
{
    stap1();
    stap2();
    stap3();
}
catch (int stapError)
{
    switch(stapError)
    {
        case STAP3ERROR: undo_stap2();
        case STAP2ERROR: undo_stap1();
    }
    return stapError;
}
return STAPOK;

De stap() functies throwen dan een error, hier een int stapError, maar je zou het nog mooier kunnen maken door een enum te gebruiken. Maar hoe doe je dit als je geen break hebt, maar slechts één case afhandeld?

Ignorance is bliss