Frage zu type cast in C

OP #7298645
Lesenswert?

Hallo,

kleine Frage, ich habe folgendes:

int8_t diff=-102;

uint8_t out=0;

nun steht ja in diff die Bitfolge 0x9A, also b10011010.

Ich möchte nun aber die 102 als positive Ganzzahl (0x66-b01100110) in 
out stehen haben.

geht das so?

out=(uint8_t)diff;

oder so:

out=(diff-1)^0xFF;

Habe gerade einen Knoten im Hirn.

Danke
DS
#7298713
Lesenswert?

Selbst abs() kann zu undefiniertem Verhalten führen, weil der Betrag der 
kleinsten negativen Zahl in Zweierkomplementdarstellung größer ist als 
die größte positive Zahl. Die Verwendung dieser Funktion ist aber der 
naheliegendste erste Ansatz bevor man Murks auf Bit-Ebene fabriziert.

Ob das undefinierte Verhalten von abs() relevant ist, muss je nach 
Anwendung beurteilt werden.
#7298798
Lesenswert?

P. S. schrieb:
> Selbst abs() kann zu undefiniertem Verhalten führen

Also laut GNU C ist abs() so implementiert:
1
/* Return the absolute value of I.  */
2
int
3
abs (int i)
4
{
5
  return i < 0 ? -i : i;
6
}

P. S. schrieb:
> weil der Betrag der kleinsten negativen Zahl in Zweierkomplementdarstellung > 
größer ist als die größte positive Zahl.

Das würde stimmen, wenn du es wieder einem int8_t zuweisen möchtest,
aber nicht wenn du als Ziel uint8_t verwendest.
1
// Das ergibt wieder -128
2
int8_t i = -128;
3

4
i = abs(i);

Oder sehe ich da jetzt etwas falsch?
OP #7298817
Lesenswert?

Adam P. schrieb:
> Oder sehe ich da jetzt etwas falsch?

Der Betrag von -128 ist 128.

Der Zahlenbereich eines int8_t geht von -128 bis 127.

Ich denke das war gemeint. Also der Betrag von -128 passt nicht in eine 
int8_t.

P. S. schrieb:
> Ob das undefinierte Verhalten von abs() relevant ist, muss je nach
> Anwendung beurteilt werden.

Das wäre aber ja nur ein Problem wenn man den Rückgabewert wieder einem 
int8_t zuspielt. In meinem Fall geht er in einen uint8_t, der geht ja 
bis 255...

MaWin schrieb:
> out = (uint8_t)-diff;

tatsächlich so einfach. probiere ich aus, nachher.


EAF schrieb:
> Nein, dieses ist  Implementation Defined, somit nicht als gesichert
> anzunehmen

Was wäre denn "sicher", oder wasserdicht und üblich?

Danke bis hierher.
Gast #7300086
Lesenswert?

Dennis S. schrieb:
> Habe gerade einen Knoten im Hirn.

Meine Tipp: Meide Type-Cast auf Teufel komm raus!

Notwendig erscheinende Casts sind fast immer ein Zeichen, dass mit den 
Datenstrukturen irgendwas faul ist.

Die Warnings oder Errors, die man mit wilden Casts meint unterdrücken zu 
müssen, schmeißt der Compiler aus einem ganz bestimmten Grund, 
namentlich weil er hier Probleme erkannt hat. Dies, wie Muttis lästige 
Händi-Anrufe einfach wegzudrücken ist sicher nicht der beste Weg -- 
sondern gleicht eher einer Vogelstrauß-Taktik.

just my 2 ct
#7300362
Lesenswert?

Wf88 schrieb:
> Wenn du einfach nur das Vorzeichen entfernen willst, dann musst du nur
> das höchstwertige Bit löschen.
>
>
1
> int8_t byte = 0xFF;
2
> int16_t word = 0xFFFF;
3
> uint16_t result;
4
> 
5
> result = (byte & ~0x80);
6
> result = (word & ~0x8000);
7
>

Wegen Integer Promotion kommt beim byte nicht das raus, was du 
erwartest.
Gast #7300382
Lesenswert?

Oliver S. schrieb:
> Hannes schrieb:
>> Meine Tipp: Meide Type-Cast auf Teufel komm raus!
>
> Damit schliesst du für dich das Rechnen mit Datentypen, die kleiner als
> ein Int sind, faktisch aus.
>
> Oliver

Wär mir neu - aber vielleicht reden wir auch von ganz verschiedenen 
Dingen?

Jedenfalls hattest Du bei meinem AG deine liebe Not, beim 'code review' 
einen Cast durchgeboxt zu kriegen.

-H
Gast #7300418
Lesenswert?

warum nicht straight:
1
if(diff >= 0) {out = diff;} else {out = -diff;}

Es ist müßig, irgendwelche halbgaren Tricks oder Standard-Funktionen zu 
vergewaltigen, um ein offensichtliches if zu sparen. Und Casts brauchts 
auch nicht.
#7300645
Lesenswert?

Hannes schrieb:
> Dennis S. schrieb:
>> Habe gerade einen Knoten im Hirn.
>
> Meine Tipp: Meide Type-Cast auf Teufel komm raus!

Mein Tipp wäre eher: Lerne zu verstehen, wo und warum Casts nötig sind. 
Das hilft dabei, sie zu vermeiden, wo sie nicht nötig sind und korrekt 
anzuwenden, wo sie es sind.
Anders gesagt: Immer, wenn man einen Cast hinschreibt, sollte man genau 
sagen können, was er an der Stelle bewirkt und warum er dort 
unvermeidbar ist.

> Die Warnings oder Errors, die man mit wilden Casts meint unterdrücken zu
> müssen, schmeißt der Compiler aus einem ganz bestimmten Grund,
> namentlich weil er hier Probleme erkannt hat. Dies, wie Muttis lästige
> Händi-Anrufe einfach wegzudrücken ist sicher nicht der beste Weg --
> sondern gleicht eher einer Vogelstrauß-Taktik.

Das ist richtig. Der Grund für einen Cast darf niemals sein: "Um die 
Compiler-Warnung wegzubekommen".

Oliver S. schrieb:
> Hannes schrieb:
>> Meine Tipp: Meide Type-Cast auf Teufel komm raus!
>
> Damit schliesst du für dich das Rechnen mit Datentypen, die kleiner als
> ein Int sind, faktisch aus.

Warum?
1
#include <stdio.h>
2
#include <inttypes.h>
3
int main(void)
4
{
5
    uint8_t a = 23:
6
    uint8_t b = 45;
7
    uint8_t c = a + b;
8
    printf("%" PRIu8 "\n", c);
9
}
Ganz ohne Casts.

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