Int Berechnungen

OP #2533219
Hallo,
warum wird diese Berechnung falsch gemacht?


1
int iStep_Puls_Pause=0;
2
uint16_t iZeit_Puls_Pause=0;
3
uint16_t iZeit_Puls=0; 
4
uint16_t iZeit_Pause=0;     
5
uint16_t iSollwert=0;
6

7
int main(void)
8
{


1
while(1)
2
{
3
    
4

5
float fmemmSollwert=0;
6
    
7
fmemmSollwert= (100-((215/250)*100))+0,5; 
8
iSollwert=fmemmSollwert;
9
    
10
switch (iStep_Puls_Pause)
11
{
12

13
//Puls Pausenzeit berechnen
14
case(1):
15
iZeit_Puls_Pause = 100;
16
iZeit_Puls = ((iZeit_Puls_Pause/100)*iSollwert);
17
iZeit_Pause = iZeit_Puls_Pause - iZeit_Puls;
18
          
19
usart_write_int0(iZeit_Puls_Pause);
20
usart_write_int0(iZeit_Puls);
21
usart_write_int0(iSollwert);
22
usart_write_int0(iZeit_Pause);
23

24
iStep_Puls_Pause = 2;

Ergebnis auf USART:

100
100
100
0


iSollwert müsste doch 14 sein...

(100-((215/250)*100))+0,5 = 14.5

Nach int dann -> abrunden/schneiden = 14.
Gast
Markus P. schrieb:
> Hallo,
> warum wird diese Berechnung falsch gemacht?

Ich vermute mal  das der Fehler hier liegt:
1
  fmemmSollwert= (100-((215/250)*100))+0,5; 
2

3
 //Probier mal; 
4
  fmemmSollwert= (100.0f-((215.0f/250.0f)*100.0f))+0.5f;

Gruß
GoldenEyes
Gast
> float fmemmSollwert=0;
> fmemmSollwert= (100-((215/250)*100))+0,5;

Das wird - so lange nix Gegenteiliges angegeben (=> f Suffix bei 
funktionierender Lösung) - hauptsächlich in int  berechnet:

215/250 = 0
0*100 = 0
100-0 = 100
(float) 100 = 100.0
100.0 + 0.5 = 100.5
fmemmSollwert = 100.5
Gast
Rechnen mit Ganzzahlen:

Solche Ausdrücke (215/250)*100 = 85 rechnet man besser so (215*100)/250 
= 85. Wobei man im Einzelfall aufpassen muss, dass durch die 
Multiplikation kein Überlauf passiert.
Gast
Markus P. schrieb:
> weiss jetzt nur noch nicht ob es vielleicht schon
> b , an , und . in 0.5 gelgen haben kann, das probier ich grad nochmal
> aus...

also du kannst davon ausgehen dass es allein durch "215.0f/250.0f" 
funktionieren müsste.
Ob da 0.5 oder 0,5 steht , sollte hier keinen unterschied machen!
Noch nen Frage:
1
iZeit_Puls_Pause = 100;
2
iZeit_Puls = ((iZeit_Puls_Pause/100)*iSollwert);

Was soll das bringen?
das ergebnis ist doch immer:
1
iZeit_Puls = iSollwert;
Markus P. schrieb:
> Krapao schrieb:
>> 215/250 = 0
>
> Eigentlich doch 0,85 deswegen ja auch erst float...

Nö.

Eigentlich 215/250 -> 0

215 ist ein int
250 ist ein int

Also wird int durch int dividiert.

Dass deine Variable auf der linken Seite der Zuweisung ein float ist, 
interessiert keinen.

http://www.mikrocontroller.net/articles/FAQ#Datentypen_in_Operationen

> fmemmSollwert= (100.0f-((215.0f/250.0f)*100.0f))+0.5f;
>
> das hat aber geholfen,

Ist aber Unsinn. Float Rechnen ist um mindestens den Faktor 30 langsamer 
als int rechnen. Formel ein wenig umstellen und schon gibts keine 
Probleme mehr.
Nachtrag: Wobei ich mich aber frage, wieso im Original-Code 100 raus 
kommt, und nicht 5. Ist das wieder eine Frage der Tokenaufteilung wegen 
dem nicht vorhandenen Leerzeichen zwischen dem + und der 0 (hatten wir 
da kürzlich nicht etwas ähnliches)?
Gast
Na = bindet halt stärker :)
Ergo wird Ausgewertet (und ich hoffe mich hier nicht zu vertun):
1) 215/250
2) 0 * 100
3) 100 - 0
4) 100 + 0
5) fmemmSollwert = 100 (+ Cast)
6) 5
Der Ausdruck ergibt also 5 -- aber die Zuweisung 100.0.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.