Forum: Mikrocontroller und Digitale Elektronik Logik Fehler


von Sam .. (sam1994)


Lesenswert?

Hi

Ich komme einfach nicht weiter mein Programm tut einfach nicht was ich 
will.
Dieser Code
1
if(digit > 6)
2
   digit = 255;
3
while(!(((uint8_t)pow(2,++digit)) & mask))
4
   if(digit > 6)
5
      digit = 255;

bekommt eine Maske mask und soll dann, wenn zum nächsten Segment 
gesprungen wird, die inaktiven überspringen.
Ein Beispiel:

Die Maske ist 0b11010011.
Wenn nun digit = 0 ist, und der Code wird einmal aufgerufen, wird digit 
nur einmal erhöht, da die Maske an der Stelle auch 1 ist. Wenn der Code 
dann nochmals aufgerufen wird, soll digit 2 mal  erhöht werden, also bis 
zur nächsten 1 in der Maske.

Kann mir vielleicht jemand sagen warum digit immer nur einmal erhöht 
wird?

von Klaus W. (mfgkw)


Lesenswert?

ich verstehe zwar nicht, wie das Programm arbeiten soll, aber
1. falls digit 8 Bit hat, auf 255 steht und einmal erhöht wird, ist es 0
2. ist pow() eine Gleitkommafunktion mit allen Problemen beim Runden 
etc.

von Thorsten (Gast)


Lesenswert?

1
(uint8_t)pow(2,++digit)

Warum einfach, wenn es kompliziert geht, wobei kompliziert nicht mal das 
richtige Ergebnis bringen muss bzw. wird.

Ich bin mal auf die Reaktionen gespannt, die da noch folgen werden.

von Grrrr (Gast)


Lesenswert?

Bitte immer vollständigen und kompilierbaren Code posten,
der den inkriminierten Fehler aufweist.
Dazu beschreiben, wie im einzelnen das passieren soll, von dem Du 
wünschst, dass es passiert und in welchem Teilschritt nicht das 
Erwartete eintritt.

Konkret helfen Dir hier die Bitschiebeoperationen um Potenzen von 2 in 
integer-Variablen zu erzeugen.

1<<0 = 2^0 = 1
1<<1 = 2^1 = 2
1<<2 = 2^2 = 4
etcpp.

von Floh (Gast)


Lesenswert?

Samuel K. schrieb:
> while(!(((uint8_t)pow(2,++digit)) & mask))

Schieben is uncool gell? :-)

while(!(uint8_t)(1<<++digit) & mask)

(ohne Gewähr)

von Sam .. (sam1994)


Lesenswert?

Danke für deine schnelle Antwort, allerdings sind deine 1. Idee geplant. 
Und Runden kommt nicht vor.

@Thorsten
Du hast natürlich Recht, aber wenn was nicht klappt setze ich lieber 
eine Klammer zuviel als zuwenig.

Also ich erkläre es nochmal:
1. digit wird um 1 erhöht
2. Mit 2^digit wird das betroffe Bit in der Maske getestet, 
rundungsfehler gibt es nicht -> es kommt eine ganzzahl raus
3. wenn das bit nicht gesetzt wird, wird digit geprüft ob es 7 ist. WEnn 
ja würde es beim nächsten mal um eins erhöht werden, und da bei 8 0 
entspricht, wird digit auf 255 gesetzt (255 + 1 = 0). Diesen Spezialfall 
gibt es auch am Anfang und deswegen ist die Abfrage auch dort.

von Sam .. (sam1994)


Lesenswert?

Samuel K. schrieb:
> Schieben is uncool gell? :-)

Daran hab ich nicht gedacht, als ich es schrieb, ist natürlich deutlich 
bessere Methode, außerdem funktioniert sie! Danke!

Der Code war übrigens Compiliert (sonst wäre es kein Logik Fehler), ich 
hatte nur die Var Def. nicht gepostet.

In meinem Programm war übrigens ein völlig anderen Logikfehler. Der 
hatte mit dem hier überhaupt nichts zu tun, trotzdem ist er jetzt weg.

von Grrrr (Gast)


Lesenswert?

Samuel K. schrieb:
> Und Runden kommt nicht vor.

Nur weil Du nicht "round" schreibst, heisst das noch lange nicht, das 
keine Rundung passiert. Wahrscheinlich spielt das hier keine Rolle, aber 
recht hast Du dennoch nicht.

> Also ich erkläre es nochmal:
Aha. Na mal sehen...

> 1. digit wird um 1 erhöht
Gegenüber welchem Wert? Vollständigen Code bitte.

> 2. Mit 2^digit wird das betroffe Bit in der Maske getestet,
Mit 2^digit wird die Zwei mit digit Exklusiv-Oder verknüpft, aber nichts 
getestet.

> rundungsfehler gibt es nicht -> es kommt eine ganzzahl raus
Falsch.

> 3. wenn das bit nicht gesetzt wird, wird digit geprüft ob es 7 ist. WEnn
Nein. Es wird getestet ob digit > 6 ist. Das ist nicht das selbe.

> ja würde es beim nächsten mal um eins erhöht werden, und da bei 8 0
Ist das ein Hellseh-Programm?

> entspricht, wird digit auf 255 gesetzt (255 + 1 = 0). Diesen Spezialfall
> gibt es auch am Anfang und deswegen ist die Abfrage auch dort.

Nochmal schreiben. Etwas weniger Selbstbewusstsein und mehr Sorgfalt 
beim formulieren, bitte. Danke für die Beachtung aller 
Sicherheitsmaßnahmen. Siehe 
http://www.mikrocontroller.net/articles/Netiquette

von Grrrr (Gast)


Lesenswert?

Samuel K. schrieb:
> In meinem Programm war übrigens ein völlig anderen Logikfehler. Der
> hatte mit dem hier überhaupt nichts zu tun, trotzdem ist er jetzt weg.

Siehst Du. Das haben wir uns schon gedacht. Darum die Frage nach dem 
kompletten Code.

von Sam .. (sam1994)


Lesenswert?

Naja ich habe es versucht verständlicher auszudrücken. In meinem 
Programm ist eben > 6 dasselbe wie == 7 da digit nie 8 werden wird. 
2^digit habe ich in meinem Code doch gar nicht geschrieben, dass das 
kein Potenzieren bedeutet weiß ich. Deswegen hab ich auch die Pow 
funktion benutzt.

von Thorsten (Gast)


Lesenswert?

>@Thorsten
>Du hast natürlich Recht, aber wenn was nicht klappt setze ich lieber
>eine Klammer zuviel als zuwenig.

Mein etwas sarkastischer Kommentar bezog sich nicht auf die 
Klammersetzung, sondern auf das pow für eine 2er Potenz. Wie hier schon 
geschrieben wurde, macht man sowas üblicherweise durch Shiften.

von Sam .. (sam1994)


Lesenswert?

Grrrr schrieb:
>> In meinem Programm war übrigens ein völlig anderen Logikfehler. Der
>> hatte mit dem hier überhaupt nichts zu tun, trotzdem ist er jetzt weg.
>
> Siehst Du. Das haben wir uns schon gedacht. Darum die Frage nach dem
> kompletten Code.

Ich glaube nicht das du Lust hast dich durch 500 Zeilen, fast nur 
unkommentierten Code zu wursteln (Das ist nämlich das die größte 
Funktion des Hauptprogramms).

von dito (Gast)


Lesenswert?

Samuel K.:
Wenn du so denkst wie du schreibst, dann wundert es mich nicht, dass du 
dein Problem nicht gelöst bekommst. Das ist ja grauenvoll zu lesen und 
nachzuvollziehen.

von Sam .. (sam1994)


Lesenswert?

dito schrieb:
> Wenn du so denkst wie du schreibst, dann wundert es mich nicht, dass du
> dein Problem nicht gelöst bekommst. Das ist ja grauenvoll zu lesen und
> nachzuvollziehen.

Ich meine damit nur, dass ich versucht habe, indem ich euch nur durch 
die nötige Codestelle gebe, es euch leichter zu machen den Fehler zu 
finden.

von Grrrr (Gast)


Lesenswert?

Samuel K. schrieb:
> Grrrr schrieb:
>>> In meinem Programm war übrigens ein völlig anderen Logikfehler. Der
>>> hatte mit dem hier überhaupt nichts zu tun, trotzdem ist er jetzt weg.
>>
>> Siehst Du. Das haben wir uns schon gedacht. Darum die Frage nach dem
>> kompletten Code.
>
> Ich glaube nicht das du Lust hast dich durch 500 Zeilen

Lies die Netiquette! http://www.mikrocontroller.net/articles/Netiquette
Das schreibe ich Dir hier nun schon zum zweiten Mal!

Meinst Du wirklich wir warten hier alle auf Dich, der uns erklärt, das 
grosse Programme gross sind?

Selbstverständlich sollst Du das Programm soweit reduzieren bis nichts 
mehr zu entfernen ist, ohne das der Fehler weggeht!

von Grrrr (Gast)


Lesenswert?

Samuel K. schrieb:
> Ich meine damit nur, dass ich versucht habe, indem ich euch nur durch
> die nötige Codestelle gebe, es euch leichter zu machen den Fehler zu
> finden.

Wie will jemand, der den Fehler nicht erkennt, wissen wo der Fehler 
liegt? Siehst Du nicht selbst den Widerspruch in Deinem Argument?

Es war den meisten hier auf den ersten Blick klar, das das Problem nicht 
in der gezeigten Codestelle liegt. pow ist hier zwar unangebracht, macht 
aber bei so kleinen Exponenten meist noch keine Probleme zumal zu 
vermuten war, das die Potenz nicht groesser als mask werden sollte.
Aber dazu muss man eben den kompletten Code sehen.

Lies verd... nochmal die Netiquette! 
http://www.mikrocontroller.net/articles/Netiquette.

Jetzt reichts mir aber. Mach Deinen Sch... in Zukunft alleine!

von Thorsten (Gast)


Lesenswert?

> Ich glaube nicht das du Lust hast dich durch 500 Zeilen, fast nur
> unkommentierten Code zu wursteln (Das ist nämlich das die größte
> Funktion des Hauptprogramms).

Dazu zwei Fragen:

1. Du lässt 500 Zeilen Code unkommentiert? Dann hol das lieber schnell 
nach. Du wirst dich wundern, dass du jetzt wahrscheinlich schon einige 
Zeilen nicht mehr ihrem genauen Zweck zuordnen kannst. Was meinst du wie 
das in einigen Wochen aussieht?

2. Du schreibst eine Funktion über 500 Zeilen? Ich denke es sicher 
möglich sein, diese Zeilen in Unterfunktionen unterzubringen. Du wirst 
dich wundern wieviel besser der Code dann zu lesen ist.

Das ganze ist nicht böse gemeint, aber du versaust dir durch solche 
Dinge echt den Spaß am Programmieren, denn du wirst schnell merken, dass 
es unübersichtlich wird und du irgendwann genervt bist. Auch meinen 
einige immer: "Ich programmiere erstmal alles und dann räum ich auf und 
kommentiere alles." Ende vom Lied ist, sie wissen gar nicht mehr wofür 
einige Zeilen gut sind und wenn sie dann aufräumen funktioniert ihr Code 
auf einmal nicht mehr und sie fangen wieder von vorne an.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.