als het inderdaad op zelf uitrekenen uitkomt, dan zou deze methode die ik eerder gepost heb ook kunnen werken, of zitten daar nog nadelen aan ?
https://www.geeksforgeeks.org/program-decimal-binary-conversion/
Golden Member
als het inderdaad op zelf uitrekenen uitkomt, dan zou deze methode die ik eerder gepost heb ook kunnen werken, of zitten daar nog nadelen aan ?
https://www.geeksforgeeks.org/program-decimal-binary-conversion/
mét CE
In basis klopt die stelling. Alleen de verhoudingen liggen tegenwoordig iets anders. In de tijd dat jij nog basic deed... Was dit vast correct
Bij een x86 bijv. is aftrekken efficienter
alsoptellen...
Bij een 8086 zijn de beiden even duur...
Hoe het met modernere x86 cores zit weet ik niet. Met al die caching, pipelining, out-of-order-processing ben ik het spoor daar een beetje bijster...
[edit]trix zat er ook nog ff tussendoor...
Zolang je je realiseert dat delen door 2 feitelijk een shift is (anders doet de compiler dat wel voor je...), zou dat ook prima moeten kunnen.
Overigens... dat 'zelf uitrekenen'... Dat doe je hoe dan ook. Alleen als je het in hexadecimaal wilt hebben, dan zit de functie die dat doet bij de shitload aan libraries die je standaard mee krijgt. Functioneel werkt het niet anders hoor.
[Bericht gewijzigd door EricP op zaterdag 11 juli 2020 17:32:08 (19%)
Special Member
als het inderdaad op zelf uitrekenen uitkomt
Vier regels code stelt niet echt wat voor...
Golden Member
Op 11 juli 2020 14:10:37 schreef Arco:
Aangepaste pseudocode:...code:
Dim lChar As Char[9] MyByte As Byte Cnt As Integer For Cnt = 7 to 0 Step -1 lChar[lCnt] = "0" + (MyByte And 0x01)) Shift Right MyByte,1 Next
ligt ongetwijfeld aan mij, maar het is mij niet geheel duidelijk,
waarom b.v.:
c code:
"0" +
Special Member
Dat was een idee van @EricP... (ik vond 0x30 een stuk duidelijker...)
0x30 is de Ascii waarde voor "0". De uitkomst van (MyByte And 0x01) wordt daar bij opgeteld (dus 0 of 1). Dit geeft je een Ascii "0" (0x30) resp. Ascii "1" (0x31)
Kan gewoon in C:
code:
void WriteBinary(uint8_t x)
{
for(uint8_t Mask = 0x80; Mask != 0; Mask >>= 1)
{ Lcd4_Write_Char( (x & Mask) ? '1' : '0');
}
}
Golden Member
Ziet er mooi uit maar begrijp er helemaal niets van.
Special Member
Da's normaal met C...
Alles moet zo kort mogelijk zodat er zoveel mogelijk op 1 regel kan worden gepropt. (dat 't dan niet duidelijk meer is boeit schijnbaar niet...)
mét CE
0x30 is de Ascii waarde voor "0".
Neen. 0x30 is de ASCII waarde voor '0'. Niet voor "0".
Da's normaal met C...
Houd het maar op 'dat is normaal voor mensen die nooit fatsoenlijk assembly geschreven hebben...
Elke keer weer blijkt dat toch voorwaarde te zijn om iets fatsoenlijks te kunnen produceren. Helaas...
Maar goed... de code van deKees is niet de meest leesbare als je alleen maar basic kent. Dat trix het niet begrijpt... Tsja... Het matched min of meer naadloos op wat er in assembly uit komt.
Feitelijk een loopje waarbij 'mask' een wandelende bit heeft beginnend met 0b10000000. Alleen de Mask >>=1 zie ik ff niet. Zal wel een typo zijn...
Afijn, in het argument van de char write zit een impliciete if die afhankelijk van het resultaat een '1' of een '0' oplevert. Qua code op zich best elegant. Geen idee hoe 'duur' de Write_Char is - dat is erg afhankelijk van de implementatie.
Golden Member
ik ben nu aan het proberen om het een en ander te implementeren, maar het wil nog niet erg vlotten
kan goed iets fout zijn in het omzetten van pseudo code naar C.
ik krijg op het display alleen maar 8657 te zien.
die lcnt in:
c code:
lchar[lcnt] = (0x30 + (RAM_content & 0x01));
heb ik veranderd naar cnt.
wie ziet wat ik allemaal niet goed doe ?
alvast mijn dank.
c code:
char lchar [9];
char RAM_content;
int cnt;
// int lcnt;
// below: read the content in the ext. RAM
PORTG &= ~(1 << PING5); // make SS ext. RAM pin = 0
SPI_transfer(0b00000011); // read data from memory
address = RAM_value; // is address in ext. RAM
SPI_transfer((address>>16)); // adress
SPI_transfer((address>>8)); // adress
SPI_transfer((address)); // adress
SPI_transfer(0x00); // dummy when you want to read a byte from ext. RAM
PORTG |= (1 << PING5); // make SS ext. RAM pin = 1
_delay_ms(2); // just for testing
RAM_content = SPDR;
for (cnt = 7; cnt >= 0; cnt = cnt -1)
{
lchar[cnt] = (0x30 + (RAM_content & 0x01));
RAM_content >> 1;
}
// below: put the content on the display
sprintf(s, "content = %u", (lchar));
Lcd4_Set_Cursor(1,16);
Lcd4_Write_String(s);
mét CE
Overigens zou je dit best vaker kunnen gaan gebruiken. Ik zou er een functie van maken. Voor een POC maakt dat uiteraard niet uit.
Golden Member
die 0x30 is toch de ascii code voor het symbool 0 ?
moet je die dan anders weergeven zodat de compiler weet dat het hier om een ascii code gaat ?
die 0 terminated heb ik al vaker langs zien komen, hoe verwerk ik die in mijn code ?
%u is unsigned integer, heb ik daar %c nodig ?
Zie Paulinha_B
Op 12 juli 2020 10:20:58 schreef trix:
die 0x30 is toch de ascii code voor het symbool 0 ?
moet je die dan anders weergeven zodat de compiler weet dat het hier om een ascii code gaat ?
Je moet niks, en je moet je vooral niet laten op de kast jagen door puristen. Je kunt zowel het een als het ander, en wat je verkiest is een kwestie van smaak en van stijl. Dat het een ascii betreft leidt de compiler af uit het gebruik van quotes.
Dat een of andere code-checker het en of het ander verkiest is bijkomstig. Code-checkers zijn sowieso voor sissies**. Maar als je er eentje wilt gebruiken dan is het wel handig om overeenkomstig te schrijven, ook.
die 0 terminated heb ik al vaker langs zien komen, hoe verwerk ik die in mijn code ?
Naar keuze:
* als je van rechts naar links werkt, oftewel van LSB naar MSB: begin met een nul (ascii 0x00), en plak er voor iedere bit een 0 (ascii 0x30) of een 1 (ascii 0x31) voor
* indien omgekeerd: maak voor iedere bit een "0" of een "1", en plak er dan het nulkarakter achter als terminator
** plagertje, @EricP Jij nu ook niet de kast op!
Special Member
Zoals reeds eerder gezegd: 0x30 is 0x30. Of dat decimaal, binair, hex, of ascii is maakt niks uit...
Golden Member
maar je moet wel aangeven door middel van quotes (begrijp ik van big_fat_mama) dat het hier om een ascii gaat. quotes zijn dat " " ?
Special Member
Op 12 juli 2020 10:08:20 schreef EricP:
OK. 0x30 is een 'magic number'. Dat doe je niet als je fatsoenlijk programmeert.
Ik vind het niet netjes (en moeilijker te lezen) als je een letter bij een gewoon getal optelt (ook al mag dat wel)
Je krijgt dan "0" + 1 = "1". Ascii en 'gewone' cijfers door elkaar maakt 't niet duidelijker)
Zie Paulinha_B
quotes zijn dat " " ?
Er zijn enkele aanhalingstekens oftewel single quotes '
Er zijn ook dubbele aanhalingstekens oftewel double quotes "
In vrije tekst kan men die redelijk losjes doorelkaarheen geburiken.
In python-code zijn ze ook redelijk verwisselbaar, voorzover men konsekwent hetzelfde doet voor openen als voor sluiten.
C-compilers doen er lastiger over.
mét CE
die 0x30 is toch de ascii code voor het symbool 0 ?
moet je die dan anders weergeven zodat de compiler weet dat het hier om een ascii code gaat ?
Je moet niks. Maar als je nog zo aan het verkennen bent, doe het dan gelijk goed. Niks moeilijker dan iets wat je verkeerd aangeleerd hebt weer af te leren.
die 0 terminated heb ik al vaker langs zien komen, hoe verwerk ik die in mijn code?
Hoe het jou uit komt. En welke code standaard je hanteert. Je kunt 'm handmatig zetten op die ene locatie. Je kunt die string vullen met nullen voordat je er überhaupt iets mee doet. Of je vertelt sprintf dat-ie maar 8 tekens mag gebruiken (ja, vreselijk lomp... maar ja, het werkt ook. Net als 0x30 schrijven als je '0' bedoelt )
Ik heb een tijdje met sdcc (voor 8051) gewerkt. Als ik het mij goed herinner, deed die een set op 0 van alle mem bij init. Als je dan geen termination had, dan werkte het ook. Per ongeluk. En dan gaat diezelfde code opeens voor een heel andere core door een andere compiler (voor de mensen die 8051 niet kennen: dat ding heeft nauwelijks stack. Dus 'locals' in C hebben stiekem gewoon een best vaste locatie. En nou ga je het voor een 8086 of een AVR compileren... dan staan locals opeens echt op de stack). Het compileert wel ja
%u is unsigned integer, heb ik daar %c nodig ?
Nou ja, misschien moet je je ff in datatypen verdiepen. Je maakt een string. Waarom zou je dan een character print-f-en? Is een string dan misschien een idee??
quotes zijn dat " " ?
Die gebruik je zoals eerder gemeld voor een string. Dit is een character. Die heeft enkele quotes.
Het verschil is enorm (en niet eens subtiel...). Een '0' is de (in deze context) leesbare variant van de ASCII waarde van het teken 0, zijnde 0x30, zo je wilt 48. Een "0" is een string van 1 character, zijnde het teken 0 gevolgd door een terminator, de waarde 0.
Ik vind het niet netjes (en moeilijker te lezen) als je een letter bij een gewoon getal optelt (ook al mag dat wel)
Nou ja, dat zie je dus verkeerd. '0' is je base zeg maar. En vanaf daar tel je. Soms doe je dat (compleet andere context, dus trix: snel vergeten...) ook met letters. 'a' of 'A' is dan je base.
Je krijgt dan "0" + 1 = "1".
Neehee. Je krijgt '0' + 1. En dat levert 49, zo je wilt 0x31 op, uitgaande van een normale ASCII tabel. Zijnde niet geheel toevallig de ASCII waarde van '1'.
Op 12 juli 2020 10:50:15 schreef Arco:
Ik vind het niet netjes (en moeilijker te lezen) als je een letter bij een gewoon getal optelt (ook al mag dat wel)
Je krijgt dan "0" + 1 = "1". Ascii en 'gewone' cijfers door elkaar maakt 't niet duidelijker)
Het hele punt is juist dat het je gaat om het karakter '0'. Waarom dan 0x30 gaan schrijven? Juist als je '0' ziet staan weet je meteen wat de bedoeling was. Bij 0x30 moet je je maar net realiseren dat het ASCII is voor die '0'. Veel logischer om dan gelijk '0' te schrijven.
mét CE
Naar keuze:
* als je van rechts naar links werkt, oftewel van LSB naar MSB: begin met een nul (ascii 0x00), en plak er voor iedere bit een 0 (ascii 0x30) of een 1 (ascii 0x31) voor
* indien omgekeerd: maak voor iedere bit een "0" of een "1", en plak er dan het nulkarakter achter als terminator** plagertje, @EricP Jij nu ook niet de kast op!
Functioneel kan inderdaad beiden. Maar wel goede kandidaten voor onleesbare code.
Golden Member
'0'≠"0"
Het eerste is een char het tweede is een string met 1 char. Soms maakt het geen reet uit soms zijn dat fouten waar je wel eens kan achter zoeken.
Met char waardes kan je tellen, met strings niet.Dat wordt string concatenatie.
'5'+'4'='9'
"5"+"4"="54"
@trix:
c code:
for (cnt = 7; cnt >= 0; cnt = cnt -1)
Kan je duidelijker schrijven als
c code:
for (cnt = 7; cnt >= 0; cnt--)
of als
c code:
for (cnt = 7; cnt >= 0; cnt -= 1)
Special Member
Op 12 juli 2020 11:06:04 schreef Jochem:
[...]Het hele punt is juist dat het je gaat om het karakter '0'. Waarom dan 0x30 gaan schrijven?
Omdat 't netjes en overzichtelijk is om getallen bij getallen op te tellen.
Niet iedereen zal het zo duidelijk zijn dat als je bij de letter "0" het getal 1 optelt, je de letter "1" krijgt.
Juist als je '0' ziet staan weet je meteen wat de bedoeling was.
Minder duidelijk vind ik.
Bij 0x30 moet je je maar net realiseren dat het ASCII is voor die '0'.
Dat weet toch bijna iedereen wel. Zeker als je in assembly hebt gewerkt. (en dat heb ik héél veel... )
Zie Paulinha_B
goede kandidaten voor onleesbare code
"onleesbaar" is net zo subjectief als uw andere kreet "fatsoenlijk" - het ligt er maar aan wat men gewend is, en welke normen men hanteert. Met alle respect voor uw bekwaamheid en ervaring en inzicht, Eric, maar je bent al de hele tijd uw eigen normen en inzichten aan het propageren als de enige juiste en correcte. Er zijn echter meerdere wegen die naar Rome leiden.
mét CE
Ja. Zelfs waterwegen.
Noem het ervaring. En ja, ik ben ook gewoon begonnen met 48" schrijven ipv. '0'. In de loopt der jaren leer je dan wat werkt (en vooral... wat niet!). Ja, dat is inzicht in de materie...
Hoe was het ook alweer: je wordt niet oud genoeg om alle fouten zelf te maken. Daarom moet je vooral proberen te leren van die van anderen...
Op 12 juli 2020 11:19:20 schreef Arco:
Niet iedereen zal het zo duidelijk zijn dat als je bij de letter "0" het getal 1 optelt, je de letter "1" krijgt.
Bij 0x30 moet je je maar net realiseren dat het ASCII is voor die '0'.
Dat weet toch bijna iedereen wel. Zeker als je in assembly hebt gewerkt. (en dat heb ik héél veel... )
Dus je gaat er vanuit dat iedereen de ASCII waarde van het karakter '0' kent, maar diezelfde mensen zullen dan niet weten dat in de ASCII tabel de '1' precies na die '0' komt?
Het gaat er ook niet eens om dat je wel of niet weet dat 0x30 de '0' representeert. Het gaat er om dat je je bij 0x30 eerst moet realiseren dat er ASCII bedoeld werd. Dat is 1 stap meer bij het lezen van de code.