Forum: Compiler & IDEs Negierung von float Wert


von Pete (Gast)


Lesenswert?

Hallo,

ich benutze einen float Wert in AVR-gcc.

float x = 27.1285.

Funktioniert perfekt in der Verbindung mit sprintf....

Jetzt möchte ich den Wert negieren ? (-27.1285)
Aus der Doku weiss ich das mein float 32bit, also 4 byte gross ist.

Muss ich jetzt das oberste Bit einfach auf 1 setzen ?
das könnte ich ja mit:

x |= 0x8000;

Vielen Dank schon mal für einen Hinweis.

Gruß Pete

: Gesperrt durch Moderator
von Peter (Gast)


Lesenswert?

float x = 27.1285.


x = 0 - x;

oder

x = d * -1;

alles andere ist nicht wirklich Portable.

von Stefan E. (sternst)


Lesenswert?

Peter schrieb:
> float x = 27.1285.
>
>
> x = 0 - x;
>
> oder
>
> x = d * -1;
>
> alles andere ist nicht wirklich Portable.

Was ist denn an
1
x = -x;
nicht portabel?

von Klaus (Gast)


Lesenswert?

Oder  x *= -1;

Oder, oder, oder... :)

von yalu (Gast)


Lesenswert?

Stefan Ernst schrieb:

> Was ist denn an
>
> x = -x;
>
> nicht portabel?

Manchmal liegt das Naheliegende so fern (nämlich einfach ein
Minuszeichen vor die Variable zu schreiben) ;-)

Wer's undurchschaubar mag, kann natürlich auch
1
x = 1/(tan(atan(x)+M_PI/2))

schreiben. Das geht für fast alle x und stimmt wenigstens ungefähr ;-)

von Simon K. (simon) Benutzerseite


Lesenswert?

Ja, es geht aber auch

x = e^(-i * pi + ln(x))

Müsste man nur noch die ganzen Funktionen aus der Mathe Bibliothek 
zusammensammeln ;)

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


Lesenswert?

> Aus der Doku weiss ich das mein float 32bit, also 4 byte gross ist.
> x |= 0x8000;
Damit würdest du z.B. das 15. Bit deiner 32-Bit-Zahl setzen...  :-o

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Lothar Miller schrieb:

> Damit würdest du z.B. das 15. Bit deiner 32-Bit-Zahl setzen...  :-o

Noch schlimmer.  Er würde die Gleitkommazahl in eine Ganzzahl
umwandeln und deren 15. Bit setzen.

von Matthias L. (Gast)


Lesenswert?


von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Hier wäre noch die Variante für die, die es in C schreiben wollen,
sich dabei aber auf die Zahlendarstellungsebene hinunter begeben
wollen. ;-)
1
double minus_x(double x)
2
{
3
        union {
4
                double x;
5
                unsigned char y[4];
6
        } u;
7
8
        u.x = x;
9
        u.y[3] -= 0x80;
10
11
        return u.x;
12
}

von (prx) A. K. (prx)


Lesenswert?

Da solltest du aber noch eine automatische Byteordererkennung anfügen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

A. K. schrieb:

> Da solltest du aber noch eine automatische Byteordererkennung anfügen.

Ich bin mir nicht einmal ganz sicher, ob der Algorithmus für
64-Bit-IEEE-854 der gleiche wäre.  Dort ist der Exponent ja
größer.

Gilt so erst einmal nur für 32-bit-FP auf little-endian (AVR).

von (prx) A. K. (prx)


Lesenswert?

Der Exponent ist egal, weil das Vorzeichen in alle IEEE Formaten im 
höchsten Bit liegt. Aber die Byte-Order ist weniger einfach, wenn man 
auch jene schrägen Varianten berücksichtigt, in denen zwar das untere 
Byte aber das obere Wort vorneweg kommt.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

A. K. schrieb:
> Der Exponent ist egal, weil das Vorzeichen in alle IEEE Formaten im
> höchsten Bit liegt.

Ja, stimmt.

> Aber die Byte-Order ist weniger einfach,

Normalerweise gibt's das als Makro in einem Headerfile, aber das
ist dann halt gerade bei AVR & Co nicht da.

> wenn man
> auch jene schrägen Varianten berücksichtigt, in denen zwar das untere
> Byte aber das obere Wort vorneweg kommt.
1
#if BYTE_ORDER == PDP_ENDIAN

:)

Ich glaube, das hat dieser Tage nur noch historische Relevanz.

von Klaus (Gast)


Lesenswert?

Oder noch etwas umständlicher:
1
float a = -2.1;
2
void *ptr;
3
ptr = memset(ptr+3, 0x40 , 1);

von MaWin. (nur echt mit Punkt) (Gast)


Lesenswert?

Klaus schrieb:
> Oder noch etwas umständlicher:

Was natürlich nicht funktioniert.

von Peter D. (peda)


Lesenswert?

Ich denke mal, der Compiler wird am besten wissen, wie man x = -x; 
optimiert.
Bei float irgendwelche kryptische, unlesbare und nicht portable 
Mikrooptimierungen hinzuschreiben, ist Blödsinn.

von eagle user (Gast)


Lesenswert?

Jörg W. schrieb:
> A. K. schrieb:

>> wenn man
>> auch jene schrägen Varianten berücksichtigt, in denen zwar das untere
>> Byte aber das obere Wort vorneweg kommt.
>
>
1
#if BYTE_ORDER == PDP_ENDIAN
>
> :)
>
> Ich glaube, das hat dieser Tage nur noch historische Relevanz.

Aber nur, weil man eine PDP-11 lieber in Assembler programmiert :)

http://www.theregister.co.uk/2013/06/19/nuke_plants_to_keep_pdp11_until_2050/

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Und was ist am o.g. portablen, offensichtlichen, der mathematischen 
Notation folgenden, nicht kürzer formulierbaren, optimalen Code 
erzeugenden
 
1
float neg (float x)
2
{
3
    return -x;
4
}

auszusetzen?

Macht avr-gcc zu
 
1
neg:
2
  subi r25,0x80
3
  ret

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Klaus schrieb:
> Oder noch etwas umständlicher:

Und Du brauchtest sieben Jahre, um das herauszufinden?

Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.