Forum: Mikrocontroller und Digitale Elektronik PIC (xc16): 4.0E10 / 17039360 = 0 ?


von Andreas B. (biosniper)


Lesenswert?

4.0E10 / 17039360 = 0

Fliesskommazahl / 32Bit Integer = 0 ? Aber nur bei der obigen 
Kombination. Ob der Zähler auch ein anderer sein kann habe ich nicht 
getestet.

PIC: 4.0E10 (float) / 17039360   (32Bit) = 0 ? (<- Error) Casio = 2347
PIC: 4.0E10 (float) / 17039361   (32Bit) = 2347
PIC: 4.0E10 (float) / 17039360.0 (float) = 2347

Umgehen könnte ich das Problem, indem ich den Nenner erst in einen 
float-Buffer kopiere, aber das kann es ja wohl nicht sein.

Habe das schon ins Microchip Forum gepostet, aber da hat noch keiner 
geantwortet, liegt wohl an den Feiertagen.

Hier noch der Prozessor den ich verwende, aber ich denke nicht, dass das 
eine Rolle spielt: PIC24F32KA302

von Erich (Gast)


Lesenswert?

Hast du jetzt einen Taschenrechner oder möchtest du das auf einem uC 
berechnen lassen?

Falls uC, so solltest du deine WIRKLICHEN Programmzeilen hinschreiben, 
und nicht "Teilextrakte wie ich's mir denke" davon.
Am besten das komplette Programm, als .c Anhang, oder sogar das 
komplette Projekt als .zip

DENN:  Auf welchen Typ von Variable du dein erwartetes Ergebnis 
zuweisst, das sieht man an deinem Beitrag nicht.

>PIC: 4.0E10 (float) / 17039360
ist keine gültige C Syntax.

Versuch' mal ungefähr folgendes:

float         ergebnis1;
unsigned int  ergebnis2;

ergebnis1 = 4.0E10 / (float) 17039360 ;  // Berechnung des Zauberwerts
ergebnis2 = ergebnis1;                   // mal sehen was rauskommt

Gruss

von Andreas B. (biosniper)


Lesenswert?

float / float liefert ja ein richtiges Ergebnis, aber nicht uint = float 
/ ulong mit dieser Zahlenkombination, wobei ich nicht weiss, ob man den 
Zähler des Bruches ändern kann.

Ja, den Typ der Zielvariable hatte ich vergessen, sorry. Mein ganzes 
Projekt ist 4000 Zeilen lang und das werde ich nicht posten. Aber ich 
habe das mal etwas besser zusammengefasst.

MPLAB X IDE v1.51, mit dem Software Simulator abgeklappert.

So erhält man ein falsches Ergebnis:
//-----------------------------------
//floatX = 4.0E10; ulongY = 17039360;
//uintCrap = floatX / ulongY;
//
//=> uintCrap = 0 //<- ERROR (2347 wäre richtig)
//-----------------------------------

So erhält man ein richtiges Ergebnis:
//-----------------------------------
//floatX = 4.0E10; floatY = 17039360.0;
//uintCrap = floatX / floatY;
//
//=> uintCrap = 2347 //<- Richtiges Ergebnis.
//-----------------------------------

Ich will das natürlich im PIC berechnen und die Mathe-Library enthält 
offenbar einen Bug.
Man muss wohl alles erst in einen float bappen um sicherzustellen, dass 
da richtige Ergebnisse rauskommen.

Die Berechnung wird auch nicht durch Interrupts unterbrochen.

Ich habe da tausende von Berechnungen durchgeführt und ausgerechnet bei 
dieser Kombination ist es mir plötzlich aufgefallen.
Ich mache da eine Rampenberechnung für einen Schrittmotor und plötzlich 
war PR1=0, ich dachte: Was ist denn das für ein Müll, das geht doch gar 
nicht ?

von Michael L. (michaelx)


Lesenswert?

Hi Andreas.

Erst mal vorab: Schön, dass du dich an der C-Programmierung versuchst.

Andreas Bayer schrieb:
> float / float liefert ja ein richtiges Ergebnis, aber nicht uint = float
> / ulong mit dieser Zahlenkombination, wobei ich nicht weiss, ob man den
> Zähler des Bruches ändern kann.
>
> Ja, den Typ der Zielvariable hatte ich vergessen, sorry. Mein ganzes
> Projekt ist 4000 Zeilen lang und das werde ich nicht posten. Aber ich
> habe das mal etwas besser zusammengefasst.
>
> MPLAB X IDE v1.51, mit dem Software Simulator abgeklappert.
>
> So erhält man ein falsches Ergebnis:
> //-----------------------------------
> //floatX = 4.0E10; ulongY = 17039360;
> //uintCrap = floatX / ulongY;
> //
> //=> uintCrap = 0 //<- ERROR (2347 wäre richtig)
> //-----------------------------------
>
> So erhält man ein richtiges Ergebnis:
> //-----------------------------------
> //floatX = 4.0E10; floatY = 17039360.0;
> //uintCrap = floatX / floatY;
> //
> //=> uintCrap = 2347 //<- Richtiges Ergebnis.
> //-----------------------------------
>
> Ich will das natürlich im PIC berechnen und die Mathe-Library enthält
> offenbar einen Bug.

Ja-nee is klar, der Fehler ist immer bei den Anderen!

Hättest du dich besser mal informiert, wie der Compiler die Datentypen 
konvertiert! Es können nämlich üblicherweise nur Variablen gleichen Typs 
als Operanden einer Berechnung verwendet werden. Das muss nicht 
unbedingt dem entsprechen, was du glaubst, was das Beste in deinem Fall 
wäre. C ist eben keine Sprache, die dem Programmierer das Nachdenken 
abnimmt. Du musst also selbst schauen, dass das Richtige herauskommt. 
Also wird in solchen Fällen ein typecast angeraten.

> Man muss wohl alles erst in einen float bappen um sicherzustellen, dass
> da richtige Ergebnisse rauskommen.

Nein nicht direkt, s.o.

> Die Berechnung wird auch nicht durch Interrupts unterbrochen.
>
> Ich habe da tausende von Berechnungen durchgeführt und ausgerechnet bei
> dieser Kombination ist es mir plötzlich aufgefallen.
> Ich mache da eine Rampenberechnung für einen Schrittmotor und plötzlich
> war PR1=0, ich dachte: Was ist denn das für ein Müll, das geht doch gar
> nicht ?

Wegen sowas Ähnlichem ist die erste Ariane 5 abgestürzt. Zitat 
Wikipedia:
"Die Ariane 5 beschleunigt schneller als die Ariane 4. Dies führte zu 
einem Überlauf einer Variable des Lenksystems. Dieser Programmfehler 
erfolgte bei der Umwandlung einer 64-Bit-Gleitkommazahl für die 
horizontale Geschwindigkeit in eine vorzeichenbehaftete 
16-Bit-Ganzzahl."

Nur mal so zum Nachdenken.

von Andreas B. (biosniper)


Lesenswert?

Bei mir findet aber kein Überlauf statt. Du hättest erstmal selber 
nachdenken sollen.

Typumwandlungen erledigt der Compiler/Library natürlich von selbst.
http://www.sprut.de/electronic/pic/c/pic_c/pic_c20_variablen.html

Aber keine Sorge ich bringe Dir C noch bei.

von Michael L. (michaelx)


Lesenswert?

Andreas Bayer schrieb:
> Bei mir findet aber kein Überlauf statt. Du hättest erstmal selber
> nachdenken sollen.

[ ] Du kennst die Bedeutung von "Ähnlich"

> Typumwandlungen erledigt der Compiler/Library natürlich von selbst.
> http://www.sprut.de/electronic/pic/c/pic_c/pic_c20_variablen.html
>
> Aber keine Sorge ich bringe Dir C noch bei.

Nee danke, hast mit dir selbst schon genug zu tun. Guckst du hier:

Andreas Bayer (also du!) schrieb im Eröffnungspost:
> Umgehen könnte ich das Problem, indem ich den Nenner erst in einen
> float-Buffer kopiere, aber das kann es ja wohl nicht sein.

[ ] Du weißt, wofür ein typecast gut ist.

PS: Was wolltest du noch mal hier?

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.