float zu unsigned int: Verhalten bei negativen Zahlen

Gast #5218524
Lesenswert?
• ▲
▼
Ich habe folgendes Stück Code, das mit einem GCC 4.6.3 kompiliert wird. 
GetValue() liefert als Rückgabewert einen float.
1
unsigned long helper;
2
float value;
3

4
value = GetValue();
5

6
helper = (value * 1000);
Muss ich damit rechnen, dass das Vorzeichen abgeschnitten wird und der 
Inhalt von 'helper' immer positiv ist?
Gast #5218565
Lesenswert?
• ▲
▼
Das Ergebnis ist nicht definiert für negative Zahlen, weil die 
Darstellung negativer signed integer nicht festgelegt ist. Es wird schon 
irgendein Bitmuster herauskommen, das als unsigned integer interpretiert 
dann natürlich positiv ist. Höchstwahrscheinlich wird aber z.B. eine 
-2.0 nicht als 2 enden.
Moderator #5218778
Lesenswert?
• ▲
▼
Wie Nop schon geschrieben hat, ist das Ergebnis undefiniert. In der
ISO-Norm kannst du das nachlesen:

1
When a finite value of real floating type is converted to an integer
2
type other than _Bool, the fractional part is discarded (i.e., the value
3
is truncated toward zero). If the value of the integral part cannot be
4
represented by the integer type, the behavior is undefined.

Der GCC scheint in solchen Fällen den nächstliegenden darstellbaren Wert
zu nehmen. Bei der Konvertierung eines negativen double oder float in
ein unsigned int ist dieser immer 0.
Gast #5218790
Lesenswert?
• ▲
▼
Man könnte vielleicht Yalus Gedanken so weiterführen:

Falls ein bestimmtes Verhalten undefiniert ist, dann ist es nützlich, 
das erwünschte Verhalten ausdrücklich als Code hin zu schreiben. Das hat 
zwei positive Effekte.

1. und ganz offensichtlich, wird eben genau das erwünschte Verhalten 
erreicht. Und zwar nichts Anderes und definitiv und mit absoluter 
Sicherheit.
2. Die Varianten des unterschiedlichen Compilerverhaltens in einem, dem 
Standard nach undefinierten Fall, müssen nicht jeweils erinnert und 
festgestellt werden und der Code ist ohne weiteres portabel. Es reicht 
im Code eine Bemerkung wie: "Explicitly describing conversion behaviour 
due to undefined case (converting negative floats to unsigned) from 
standard" oder sinngemäß.

Das wäre so meine Idee dazu. Hoffe, dass ist nützlich.
#5218876
Lesenswert?
• ▲
▼
Peter D. schrieb:
> Theor schrieb:
>> Falls ein bestimmtes Verhalten undefiniert ist, dann ist es nützlich,
>> das erwünschte Verhalten ausdrücklich als Code hin zu schreiben.
>
> Gute Idee.
> Z.B.:
>
1
> uint32_t convert( float val )
2
> {
3
>   if( val <= 0 )
4
>     return 0;
5
>   if( val >= (uint32_t)-1 )
6
>     return -1;
7
>   return val;
8
> }
9
>

Nö. Genau so eigentlich nicht. Undefiniertes Verhalten lässt sich nicht 
mit undefiniertem Verhalten ( (uint32_t) -1) "wegprogrammieren".

Die ISO Dokumentation empfiehlt so was, z.B.:
1
(unsigned long) fmod(fabs(rint(f)), LONG_MAX + 1.0)

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 8 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.