Das Ergebnis von abs(-2147483648) ist -2147483648, nicht wahr? es scheint inakzeptabel.
printf("abs(-2147483648): %d\n", abs(-2147483648));
Ausgang:
abs(-2147483648): -2147483648
Das Ergebnis von abs(-2147483648) ist -2147483648, nicht wahr? es scheint inakzeptabel.
printf("abs(-2147483648): %d\n", abs(-2147483648));
Ausgang:
abs(-2147483648): -2147483648
Alexej Frunze
Die Norm sagt ca abs()
:
Das
abs
,labs
undllabs
Funktionen berechnen den absoluten Wert einer ganzen Zahlj
. Kann das Ergebnis nicht dargestellt werden, ist das Verhalten undefiniert.
Und das Ergebnis kann tatsächlich nicht dargestellt werden, weil die 2er-Komplement-Darstellung von ganzen Zahlen mit Vorzeichen nicht symmetrisch ist. Denken Sie darüber nach … Wenn Sie 32 Bits in einem haben int
das gibt dir 232 deutliche Werte aus INT_MIN
zu INT_MAX
. Das ist eine gerade Anzahl von Werten. Wenn es also nur eine 0 gibt, kann die Anzahl der Werte größer als 0 nicht gleich der Anzahl der Werte kleiner als 0 sein. Es gibt also kein positives Gegenstück zu INT_MIN
mit einem Wert von –INT_MIN
.
Was also nicht akzeptabel ist, ist anzurufen abs(INT_MIN)
auf Ihrer Plattform.
Lukas Rahne
Negative Zahlen werden normalerweise mit dem binären Komplement dargestellt.
Um Positiv in Negativ umzuwandeln, wird Logik verwendet
x -> not(x)+1
Für 8-Bit-Arithmetik
01111111b ist 127 und -127 wird
10000000b + 1 = 10000001b
und in entgegengesetzter Richtung -127 10000001b wird
01111110b + 1 = 01111111b
Was ist mit -128?
-128 ist 10000000b und es gibt kein positives Gegenstück dazu, weil es in 8-Bit-Arithmetik mit Vorzeichen keine 128 gibt.
10000000 -> 01111111 + 1 = 10000000 und wieder -128
Gleiches gilt für die ursprüngliche Frage
deshalb sind 0 und der Minimalwert nach der Negation im Zweierkomplement immer gleich
– phuklv
13. Januar 2014 um 2:25 Uhr
Alexandre C.
Da 2147483648 größer als ist INT_MAX
auf Ihre Implementierung, dann abs(-2147483648)
ist nicht definiert.
Mazheng
Dies ist Code in abs.c im GNU Glibc-Quellcode.
/* Return the absolute value of I. */
int
DEFUN(abs, (i), int i)
{
return(i < 0 ? -i : i);
}
Also, abs(-2147483648) gibt -(-2147483648) zurück. In x86 wird es durch diese beiden Anweisungen implementiert
movl $-2147483648, %eax
negl %eax
negl-Anweisung wird auf diese Weise implementiert: num=0-num; sbb wird folgendermaßen implementiert: Subtrahiert die Quelle vom Ziel und subtrahiert 1 extra, wenn das Carry-Flag gesetzt ist. Also abs(-2147483648) (Hex ist 0x80000000 ) –> -(-2147483648) –> 0-(-2147483648) wird schließlich zu (0x80000000).
Einzelheiten zu Negl-Anweisungen finden Sie unter http://zsmith.co/intel_n.html#neg
Einzelheiten zu SBB-Anweisungen finden Sie unter http://web.itu.edu.tr/kesgin/mul06/intel/instr/sbb.html
Übermensch
Versuche dies
printf("abs(-2147483648): %u\n", abs(-2147483648));
Das, mein Freund, hat undefiniertes Verhalten. Sie drucken eine vorzeichenbehaftete Ganzzahl mit dem unsigned Formatter. I -1, weil es außerdem die Frage nicht beantwortet.
– Alexander C.
28. Juni 2012 um 11:16 Uhr
Das, mein Freund, hat undefiniertes Verhalten. Sie drucken eine vorzeichenbehaftete Ganzzahl mit dem unsigned Formatter. I -1, weil es außerdem die Frage nicht beantwortet.
– Alexander C.
28. Juni 2012 um 11:16 Uhr
Ich glaube, das ist undefiniertes Verhalten. Ich habe den C-Standard nicht zur Hand, daher kann ich ihn nicht sichern.
– Alexander C.
28. Juni 2012 um 10:53 Uhr
Was erwartest du angesichts dessen
abs(int)
gibt ein zurückint
?– Philipp Kendall
28. Juni 2012 um 10:55 Uhr
Letzter Entwurf von C11 sagt (7.21.6.1, über Bauchmuskeln und Freunde) “Wenn das Ergebnis nicht dargestellt werden kann, ist das Verhalten undefiniert”
– Alexander C.
28. Juni 2012 um 10:58 Uhr
@PhilipKendall Der Absolutwert kann ein negativer Wert sein?
– Viktor S
28. Juni 2012 um 10:59 Uhr
Linux-Manpage sagt (man 3 abs): Der Versuch, den absoluten Wert der negativsten Ganzzahl zu nehmen, ist nicht definiert.
– Pat
28. Juni 2012 um 11:07 Uhr