Float to Int?

#1694571
Lesenswert?

Aber genau das war doch der Unterschied zwischen expliziten und 
impliziten Casts. Implizite macht der Compiler stillschweigend (und alle 
samt ohne Datenverlust) und explizite waren immer bei Datenverlust nötig 
(oder bei komplexen Typen).

Ok, das war nun nicht der Unterschied der definiert was implizit und 
explizit Casts sind. Sondern der Unterschied der die Anwendung dieser 
beschreibt/nötig macht.

/EDIT: Aber du hast Recht. Habe mich nochmal kundig gemacht und 
getestet. Bin wohl noch etwas von Delphi/Pascal geschädigt, da ist es 
wie ich es geschrieben hatte. Aber eine strenge Typprüfung ist ja einer 
der Punkte von Delphi Language/Pascal. In C/C++ ist kein Cast notwendig.
#1694585
Lesenswert?

Thomas K. schrieb:
> Aber genau das war doch der Unterschied zwischen expliziten und
> impliziten Casts. Implizite macht der Compiler stillschweigend (und alle
> samt ohne Datenverlust) und explizite waren immer bei Datenverlust nötig
> (oder bei komplexen Typen).

Du must unterscheiden zwischen einem Fehler, von dem die 
Sprachdefinition fordert, das er angemäkelt wird und einer Warnung, die 
ein Compilerbauer von sich aus, aus freien Stücken, eingebaut hat.

Die Zuweisung eines float an einen int ist kein Fehler. Selbst wenn 
einige Compiler (aus guten Gründen) eine Warnung geben. So nach dem 
Motto: "Ich tu schon was du von mir willst, aber bist du dir da wirklich 
sicher? Oft ist das ein Flüchtigkeitsfehler, drum werfe ich mal 
sicherheitshalber eine Warnung."

Aber auf jeden Fall ist das kein Kandidat für
<Zitat>
dies funktioniert nicht
</Zitat>

Im übrigen ist diese Version, die auch noch rundet
1
  OCR1A = (int)( k + 0.5);
meistens die bessere Wahl. Sonst kann es nämlich ganz schnell passieren, 
das aus 5.99999999 (also praktisch 6) trotzdem 5 wird und nicht 6.
Gast #1694593
Lesenswert?

habe es so versucht:

  OCR1A=(int)k;


funktioniert auch nicht...

fehler meldung ist für mich auch nicht verständlich:

Build started 30.4.2010 at 21:14:40
avr-gcc  -mmcu=atmega32 -Wall -gdwarf-2 -Os -std=gnu99 -funsigned-char 
-funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT 
Pflichtsoftware1.o -MF dep/Pflichtsoftware1.o.d  -c 
../Pflichtsoftware1.c
avr-gcc -mmcu=atmega32 -Wl,-Map=Pflichtsoftware1.map Pflichtsoftware1.o 
-o Pflichtsoftware1.elf
c:/winavr-20090313/bin/../lib/gcc/avr/4.3.2/../../../../avr/lib/avr5\lib 
c.a(log.o):  In function `log':
(.text.fplib+0x46): relocation truncated to fit: R_AVR_13_PCREL against 
symbol `__addsf3' defined in .text section in 
c:/winavr-20090313/bin/../lib/gcc/avr/4.3.2/avr5\libgcc.a(_addsub_sf.o)
c:/winavr-20090313/bin/../lib/gcc/avr/4.3.2/../../../../avr/lib/avr5\lib 
c.a(log.o):  In function `log':
(.text.fplib+0x4e): relocation truncated to fit: R_AVR_13_PCREL against 
symbol `__addsf3' defined in .text section in 
c:/winavr-20090313/bin/../lib/gcc/avr/4.3.2/avr5\libgcc.a(_addsub_sf.o)
make: *** [Pflichtsoftware1.elf] Error 1
Build failed with 1 errors and 0 warnings...
Gast #1694618
Lesenswert?

hier der Code... kann mir niemand helfen?
1
int main(void)
2
{
3
float temperatur_soll_LM45 = 0;
4
float k=0;
5

6
float Kp=200;
7
float Ki=2;
8
float Ta=20;
9

10
float e=0;
11
float esum=0;
12

13
DDRC=0xFF;
14
DDRD=0xFF;
15

16
PORTC=0;
17
PORTD=0xFF;
18
PORTB=0xFF;
19

20
Initialize_Timer0(2,2,256);
21
TIMSK |= (1<<TOIE0);
22

23
ADMUX   |=   (   1<<REFS0   |  1<<MUX0);
24
ADCSRA   |=  (   1<<ADEN    );
25

26
TCCR1A   |=  (  1<<COM1A1  |  1<<WGM10  |  1<<WGM11);
27
TCCR1B  |=  (  1<<CS10    |  1<<CS12);
28

29
OCR1A=0;
30

31
lcd_init();
32
lcd_clear();
33
sei();
34

35
while(1)
36
    {      
37
  temperatur_soll_LM45 = temperatur_ist_NTC+2;
38
  e=temperatur_soll_LM45-temperatur_ist_LM45;
39
  esum+=e;
40

41
  if(esum<-300)esum=-300;
42
  if(esum>300)esum=300;
43

44
  k=e*Kp+Ki*Ta*esum;
45

46

47
  if(k>1021)k=1021;
48
  if(k<0)k=0;
49

50
  OCR1A=(int)k;
51

52
  _delay_ms(250);
53
    {
54
    // Daten an Display ausgeben
55
    char Buffer[20]; // in diesem {} lokal
56
    set_cursor(0,1);lcd_string(" Temp1:");
57
    set_cursor(6,1);lcd_string("     ");set_cursor(6,1);
58
    dtostrf(temperatur_ist_LM45,7,2, Buffer );
59
    lcd_string( Buffer );lcd_data(223);lcd_data('C');
60

61
    set_cursor(0,2);lcd_string(" Temp2:");
62
    set_cursor(6,2);lcd_string("     ");set_cursor(6,2);
63
    dtostrf(temperatur_ist_NTC, 7, 2, Buffer );
64
    lcd_string( Buffer );lcd_data(223);lcd_data('C');
65

66
  /*  set_cursor(0,4);lcd_string("     ");set_cursor(0,4);
67
    itoa(OCR1A, Buffer, 10 );
68
    lcd_string( Buffer );*/
69
    }
70
    }
71
 
72
    return 0;
73
}
#1694633
Lesenswert?

Klaus Wachtler schrieb:
> Die float.h hilft nur dem Compiler.
> Wenn der Linker Fehlermeldungen spuckt, fehlt meist die libm,
> und die wird mit -lm eingebunden.
>
> Das war damit wohl gemeint:
> Karl heinz Buchegger schrieb:
>> Du hast die Floating Point Library nicht eingebunden, oder mit deiner
>> Installation stimmt etwas nicht.

Genau.
Aber ich wusste nicht mehr auswendig, wie man das im AVR-Studio macht 
:-)

Inzwischen hab ich nachgesehen:

Menüpunkt "Project" / "Configuration Options"
Im Dialog dann links "Libraries" anklicken
Im linken Listfeld die libm.a auswählen und "Add Library"

Alles mit OK bestätigen und erneut Builden lassen.
Gast #1694636
Lesenswert?

Hallo,

wieso verwendest du überhaupt "float" Variablen? Sollte auch ohne gehen.
Denn ich sehe nur ganzzahlige Werte. Und eine Division kommt auch nicht 
vor ...
Verwende einfach Int16 bzw. Int32. Das macht auch den Code deutlich 
kleiner.
Gast #1694637
Lesenswert?

hm das Problem ist aber nur beim laden ins OCR1A Register.. ich konnte 
mit float rechnen, diese Werte ans Display übergeben, das hat keine 
Probleme verursacht..

float Bibliothek ist vorhanden, hab es soeben überprüft.
Gast #1694640
Lesenswert?

In der Subroutione wird mit einer Log() funktion gerechnet, daher 
entstehen Zahlen mit Kommastellen

[C]
ISR(TIMER0_OVF_vect){

// Sensor1 auslesen
  ADMUX   =   (   1<<REFS0   |  0<<MUX0  );   // AVcc als 
Referenzspannung, Multiplexer auf Position 0
  ADCSRA   |=  (   1<<ADSC  );           // Start einer Wandlung
  while(CHECKBIT(ADCSRA,ADIF)==0);
  SETBIT(ADCSRA,ADIF);//clear Interupt Flag

// Sensor 1 als LM45 auswerten
  ADC_Wert_LM45=ADCL;
  ADC_Wert_LM45+=ADCH<<8;
  temperatur_ist_LM45=50*ADC_Wert_LM45/102.4;

// Sensor2 auslesen
  ADMUX   =   (   1<<REFS0   |  1<<MUX0  ); // AVcc als 
Referenzspannung, Multiplexer auf Position 1
  ADCSRA   |=  (   1<<ADSC  );           // Start einer Wandlung
  while(CHECKBIT(ADCSRA,ADIF)==0);
  SETBIT(ADCSRA,ADIF);//clear Interupt Flag

// Sensor 2 als NTC behandeln
  ADC_Wert_NTC=ADCL;
  ADC_Wert_NTC+=ADCH<<8;
  temperatur_ist_NTC=(108025/(3625+log(1024/ADC_Wert_NTC-1)*298))*10-273;
  }
[\C]
#1694647
Lesenswert?

Lea Weiss schrieb:
> In der Subroutione wird mit einer Log() funktion gerechnet, daher
> entstehen Zahlen mit Kommastellen

LOL.
Wusste gar nicht das der gcc soooo gut ist.

Die Fehlermledung beschwert sich dass etwas mit log nicht stimmt.

In function `log':
(.text.fplib+0x46): relocation truncated to fit: R_AVR_13_PCREL against
symbol `__addsf3' defined in .text section in
c:/winavr-20090313/bin/../lib/gcc/avr/4.3.2/avr5\libgcc.a(_addsub_sf.o)


und in deiner ISR kommt ein log vor.
Was ist dein logischer Schluss?

> das Problem ist aber nur beim laden ins OCR1A Register.

Das ist der falsche Schluss. Der hat damit nichts oder nur auf Umwegen 
zu tun.
#1694661
Lesenswert?

Aber temperatur_ist_NTC

Ist die volatile?

Im übrigen brauchst du nicht mit mir streiten, denn: Der Compiler/Linker 
hat immer recht. Und dein Linker (nicht der Compiler) beschwert sich, 
dass er ein Problem mit der Funktion log() hat. Steht schwarz auf weiß 
dort.

Das kann nichts mit der Zuweisung zu tun haben. Ausser: Lässt du die 
Zuweisung weg, kann es sein, dass die Voraussetzung für die Berechnung 
des log() in der ISR wegfällt und der Optimizer den log ganz einfach 
rauswirft. Kein log() mehr, kein Problem für den Linker.
Gast #1694671
Lesenswert?

Eine Frage am Rande: wie oft wird der Timer0-Interrupt aufgerufen? Ich 
werde aus
> Initialize_Timer0(2,2,256);
nicht schlau ...

Unabhängig vom Compilier-Fehler: In einer ISR fasst man sich kurz. Hier 
solltest du nur die Messwerte der Sensoren einlesen und sie dann im 
Hauptprogramm bearbeiten.
Gerade Floating Point Berechnungen brauchen viel Zeit ... (und die hat 
man in einer ISR normalerweise nicht.)
Gast #1694724
Lesenswert?

Ist bei der Fehlermmeldung eigentlich eindeutig. Wenn der Linker 
versucht Fließkommaroutinen (wie log) aus der libc.a zu benutzen, fehlt 
immer die libm.a. Entweder weil sie nicht mit angegeben wurde oder wenn 
doch, dann aber an der falschen Stelle.
Persönliche Seite #1694844
Lesenswert?

Karl heinz Buchegger schrieb:

> In function `log':
> (.text.fplib+0x46): relocation truncated to fit: R_AVR_13_PCREL against
> symbol `__addsf3' defined in .text section in
> c:/winavr-20090313/bin/../lib/gcc/avr/4.3.2/avr5\libgcc.a(_addsub_sf.o)

Das Problem ist also, daß bestimmte Relocs nicht passen, weil Offsets 
für PC-relative Adressierung zu groß werden. Irgendwer ruft da die 
__addsf3 auf, und das kann eigentlich nur avr-gcc sein, weil die 
__addsf3 zur libgcc gehört. Möglicherweise kann der Linker das 
ausbügeln, wenn man ihn Sprünge relaxen lässt.

Daß das Problem (zunächst) verschwindet, wenn man das Programm kleiner 
macht, hat nix zu sagen. Dadurch passt die Adresslage wieder, weil dann 
anders lokatiert wird. Irgendwann hat man das Ding aber wieder am 
Schenkel kleben...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren