Forum: Gesperrte Threads Fehler bei Float*integer


von Hansen (Gast)


Lesenswert?

Hallo,

Ich habe heute einen Fehler festgestellt undzwar, wenn ich eine uint32_t 
variable mit *1.5 rechnen möchte, spielt der ganze µC verrückt.

Gibt es dafür eine logische erklärung?
Ebenso wollte er nicht zuerst *15 und danach /10 rechnen. Ich denke es 
hat wieder was mit Float zu tun.

Danke schonmal

Hansen

: Verschoben durch Admin
von 42 (Gast)


Lesenswert?

42

von Markus (Gast)


Lesenswert?

verwendeter uC? Compiler? Codeauschnitt usw. usw.

Hellseherforum ist irgendwo anders.

von (prx) A. K. (prx)


Lesenswert?

Wenn du deinen Frust nun erfolgreich abgeladen hast, dann hast du 
vielleicht wieder die Ruhe, mal drüber nachzudenken, wie jemand auf 
deinen Beitrag reagieren soll, angesichts dessen was alles nicht 
erwähnt wird.

von Hansen (Gast)


Lesenswert?

Ich denke die Frage war gut formuliert, ob ein spezialfall eintritt wenn 
eine 32 Bit Integer Variable mit einer Float konstante multipliziert 
wird.

verwendet wird avr gcc und Atmega 32

Hansen

von Bernd das Brot (Gast)


Lesenswert?

Das Zauberwort heist "cast".
Fertig.

von Stefan B. (stefan) Benutzerseite


Angehängte Dateien:

Lesenswert?

Keine Probleme hier (s. Anhang)

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Hansen schrieb:
> Ich denke die Frage war gut formuliert, ob ein spezialfall eintritt wenn
> eine 32 Bit Integer Variable mit einer Float konstante multipliziert
> wird.
Was soll daran speziell sein?
Das passiert in PC-Programmen tagtäglich.

von Eddy C. (chrisi)


Lesenswert?

Naja, so einen Integer nimmt man ja auch so *1.5:

i += (i>>1);

Aber das ändert an Deinem Problem wohl wenig. Was interessant wäre: Was 
meinst Du mit "spielt der ganze µC verrückt"?

von (prx) A. K. (prx)


Lesenswert?

Hansen schrieb:

> Ich denke die Frage war gut formuliert,

Nein, denn du hast die essentiellen Informationen über Prozessor und 
Compiler vergessen und hast die falsche Frage gestellt, weil du 
tatsächlich eine eigene völlig falsche Vermutung/Diagnose aufgestellt 
hast, die du bestätigt haben wolltest. Besser wäre es gewesen, das 
konkrete Problem zu schildern, d.h. was genau du getan hast (Code) und 
was dabei überraschenderweise herauskam ("spielt verrückt" ist eine 
nutzlose Information).

Tatsächlich gibt es beim avr-gcc bei Fliesskommarechnung zwei Dinge zu 
beachten. Man muss die richtige Lib für die Laufzeitfunktionen einbinden 
und man muss ebenfalls etwas beachten wenn man printf mit 
Fliesskommwerten verwenden will. Beides ist in der Doku zur avr-libc 
aufgeführt.

von Hansen (Gast)


Lesenswert?

Hallo!

Du behauptest ich habe eine völlig falsche vermutung/Diagnose 
aufgestellt. Kannst du doch garnicht wissen oder?

Also Mein Programm funktioniert ganz normal, doch sobald ich irgendwo im 
Programm x*=1.5; einfüge gehts nichtmehr.

selbst wenn der ablauf so ist:

int main(void)
{ ...
  ...
  ...
  while(1);
  x*=1.5;
}

Selbst wenn er es nie erreicht, funktioniert das Programm danach 
nichtmehr.

MfG

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Hansen schrieb:
> Du behauptest ich habe eine völlig falsche vermutung/Diagnose
> aufgestellt.
Soooo sensibel?
> Kannst du doch garnicht wissen oder?
Es ist ganz einfach so, dass offenbar nur DU das Problem hast, und 
deshalb hat es nichts mit C an sich zu tun, sondern mit deiner 
speziellen Konstellation (Compilerschalter, Libs,...)

> Also Mein Programm funktioniert ganz normal, doch sobald ich irgendwo im
> Programm x*=1.5; einfüge gehts nichtmehr.
WAS geht dann nicht mehr?
Das Compilieren?
Was sagt der Debugger?

> Selbst wenn er es nie erreicht, funktioniert das Programm danach
> nichtmehr.
Wenn er die Stelle nie erreicht, funktioniert da vorher schon was 
nicht... :-o

von Sebastian (Gast)


Lesenswert?

Hansen schrieb:
> x*=1.5;
>
> Selbst wenn er es nie erreicht, funktioniert das Programm danach
> nichtmehr.

Passt das Programm noch in den Controller? Der Fliesskomma-Code ist 
recht groß. Poste mal die vollständigen Compilermeldungen.

Sebastian

von Hansen (Gast)


Lesenswert?

AVR Memory Usage
----------------
Device: atmega32

Program:    8886 bytes (27.1% Full)
(.text + .data + .bootloader)

Data:        794 bytes (38.8% Full)
(.data + .bss + .noinit)


Build succeeded with 0 Warnings...


Also das past alles noch rein!

Ich meine, alles was nach while(1); steht, wird doch 100%ig nie 
aufgerufen.

Compilieren und alles geht, doch wenn ich das Programm auf den µC lade, 
funktioniert es nichtmehr.

Wenn ich dagegen statt *1.5 schreibe *12 und danach >>3 funktioniert es.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Hier mal ein PC-Programm
1
#include <stdio.h>
2
3
int main(int argc, char *argv[])
4
{
5
    int i = 28;
6
    i *= 1.5;
7
    printf("%d",i);
8
    return 0;
9
}
Und was wird ausgegeben?
Logisch: 42

von Klaus W. (mfgkw)


Lesenswert?

Und wenn du davor eine Endlosschleife einfügst, funktioniert es nicht 
mehr.
q.e.d.

von lika (Gast)


Lesenswert?

Lothar Miller schrieb:
>> Selbst wenn er es nie erreicht, funktioniert das Programm danach
>> nichtmehr.
> Wenn er die Stelle nie erreicht, funktioniert da vorher schon was
> nicht... :-o
Da ist ein Semikolon (Strichpunkt). ;-)

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Hansen schrieb:
> Wenn ich dagegen statt *1.5 schreibe *12 und danach >>3 funktioniert es.
Zeig jetzt doch einfach endlich mal deinen Code!
Und beschreibe, WAS da nicht mehr funtktioniert.

> Ich meine, alles was nach while(1); steht, wird doch 100%ig nie
> aufgerufen.
Es sei denn, da wäre ein break in der Schleife, oder ein goto...

von Hansen (Gast)


Lesenswert?

ich verspreche dir, in einem while(1); kann kein goto oder break stehen 
;) weil der Strichpunkt gleich nach dem while is, und somit ist es nur 
eine sinnlose endlosschleife!

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Hansen schrieb:
> ich verspreche dir
Gut, da hast du Recht... :-o
Aber wo ist der Rest vom Code? Was ist die Minimalausführung 
(Dreizeiler) der das von dir beschriebene fehlerhafte Verhalten zeigt?

von Hansen (Gast)


Lesenswert?

Ok es scheint nun doch zu funktionieren !?

aber ne andere Frage, goto in gcc funktioniert ? könnte ich damit 
mittels eines Interrupts aus einer Endlosschleife hinausspringen?

Hansen

von Oberlehrer (Gast)


Lesenswert?

Ganz im Ernst, ich kann hier nur allen Beteiligten dazu raten nicht 
weiter darauf einzugehen. Es wird zig mal nach dem Code gefragt, darauf 
wird nicht eingegangen und schließlich ist das Problem wie durch 
Zauberei behoben.

von Hansen (Gast)


Lesenswert?

Oberlehrer, dein Name triffts exakt ;)

Ich habe den Code mit absicht nicht angefügt, da die Diskussion ÜBER den 
Code ( ohne das Problem von dem ich anfangs geschildert habe ) über 
mehrere Tage gelaufen wäre, und schlussendlich hätte niemand was davon.

Ob wer antwortet oder nicht, muss er eh selbst entscheiden.

von Helmut S. (helmuts)


Lesenswert?

Wenn du aus einem Interrupt direkt in einen anderen Programmteil 
springen würdest, dann müsstest du den Programm-Stackpointer selber 
korrigieren.
Geht das in C überhaupt?
Das wäre aber schlechter Code. Setz doch in deinem Interrupt eine 
Variable die in deiner Schleife abgefragt wird. Wenn die dann z. B. 1 
ist, dann machst du einen ganz "normalen" Abbruch der Schleife.

von derdas (Gast)


Lesenswert?

Mein Tipp: Das Problem ist ein ganz anderes. Manchmal wird ein Fehler 
erst durch das einfügen einer Zeile "aktiviert". Deshalb versucht man 
den Fehler zu isolieren.
Also z.B. ein neues Programm, was nur die fragliche Zeilen enthält. Wenn 
der Fehler dann immer noch auftritt hat man zumindest nicht soviele 
Parameter an denen man spielen muss um den Fehler vielleicht zu 
verstehen.

Ausserdem, mach doch * 3 / 2 (oder noch besser was Eddy Current 
vorgeschlagen hat), ist auch viel schneller als mit float rumzurechen, 
und anschliessend wieder alle Nachkommastellen wegzuwerfen !

von (prx) A. K. (prx)


Lesenswert?

Helmut S. schrieb:

> Wenn du aus einem Interrupt direkt in einen anderen Programmteil
> springen würdest, dann müsstest du den Programm-Stackpointer selber
> korrigieren.
> Geht das in C überhaupt?

Im Prinzip ja, mit setjmp/longjmp. Allerdings ist das nicht aus ISRs 
vorgesehen, da es dafür nicht selten spezieller Handlungen zur 
Beendigung des Handlers bedarf, die nicht Bestandteil von longjmp sind.

> Das wäre aber schlechter Code.

Allerdings. Davon ist auch dann abzuraten, wenn es mit longjmp möglich 
sein sollte.

von derdas (Gast)


Lesenswert?

Normalerweise macht man das so:
Eine Variable als volatile deklarieren und initialisieren, z.b. als 0.
Im Interrupt die variable auf 1 setzen.
In der Schleifenbedingung abfragen, ob die variable 1 ist, wenn ja dann 
raus gehen.

von Karl H. (kbuchegg)


Lesenswert?

Hansen schrieb:
> Oberlehrer, dein Name triffts exakt ;)
>
> Ich habe den Code mit absicht nicht angefügt, da die Diskussion ÜBER den
> Code ( ohne das Problem von dem ich anfangs geschildert habe ) über
> mehrere Tage gelaufen wäre, und schlussendlich hätte niemand was davon.

Aha.
Du meinst also wenn wir dir zeigen, wie man die Dinge richtig macht, 
dann hat niemand was davon.
Du hast insofern recht, als wir uns dann Arbeit sparen. Aber abgesehen 
davon liegst du falsch.

Die Frage nach dem goto macht mich allerdings stutzig.


Und noch was:
Scheint zu funktionieren bedeutet in vielen Fällen, dass sich ein oder 
mehrere Fehler ganz einfach noch nicht bemerkbar gemacht haben. Nicht 
mehr. Scheint zu funktionieren bedeutet auf keinen Fall, dass alles 
richtig ist.

von Hansen (Gast)


Lesenswert?

Bittesehr, es funktioniert alles.

Nun alle zufrieden oder was ?

von Bernd (Gast)


Lesenswert?

Hansen, den Namen muss ich mir merken,
nicht dass ich da aus Versehen mal antworte ...

von (prx) A. K. (prx)


Lesenswert?

Bernd schrieb:

> Hansen, den Namen muss ich mir merken,
> nicht dass ich da aus Versehen mal antworte ...

Jau, da hatte ich auch schon dran gedacht. Aber wie es sich für die 
heutige Zeit gehört automatisiert, als Verbesserungsvorschlag für 
Andreas. Eine persönliche Blacklist fürs Forum.

von Markus (Gast)


Lesenswert?

Hansen schrieb:
> Bittesehr, es funktioniert alles.
>
> Nun alle zufrieden oder was ?

Ich ja. Hat das Trauerspiel hier endlich ein Ende. Viel Glück noch, 
wirst Du brauchen bei Deiner Kompetenz im technischen wie im 
kommunikativen Bereich.

von Qwertz (Gast)


Lesenswert?

>Nun alle zufrieden oder was ?

Was hast Du für einen Eindruck?

Wir hätten Dir gerne geholfen und das so, das auch anderen mit dem 
selben Problem geholfen ist.

Du kannst davon ausgehen, das die Fragen der kompetenteren Antworter 
hier, nicht völlig blödsinnig sind. Deine Beurteilung der Frage, ob und 
welche Informationen zur Lösung Deines Problems nötig sind kollidiert 
naturgemäß mit der Beurteilung derjenigen die Dir hier helfen wollen.

Das ist mehr oder weniger zwangsweise so, denn ganz klar: Probleme 
beruhen entweder auf ungenügender, d.h. unvollständiger oder 
irrelevanter Information oder auf Fehler in ihrer Darstellung.

Deswegen fragen potentielle Helfer nach Informationen.

Umgekehrt, wenn Du in der Lage wärst (ich meine einfach nur Deinen 
Kenntnisstand und nicht Deine grundsätzliche Fähigkeit dazu) die 
Informationen vollständig und relevant zu geben und darzustellen, 
hättest Du das Problem schon selbst erkannt, weil es irgendwo einen 
Widerspruch gegeben hätte.

In Anbetracht dessen halte ich Deine Empfindlichkeit nicht angebracht.

von I. L. (Gast)


Lesenswert?

Hansen schrieb:
> Bittesehr, es funktioniert alles.

Dann geh wieder spielen!

Hansen schrieb:
> Nun alle zufrieden oder was ?

Wenn du es bist!

Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.