Forum: PC-Programmierung Per Hand prüfen ob Zahl im Werterbereich liegt


von Kukuku (Gast)


Lesenswert?

Hallo alle zusammen,

bei Aufgaben (Einführung in die Programmierung) in denen ich prüfen 
soll, ob eine Zahl im Wertebereich liegt, und wie die Zahl dann 
dargestellt wird falls nicht, tue ich mich irgendwie schwer.

Bspw. habe ich die Zahl 384 von der ich weiß, wenn ich sie in byte 
konvertiere sie als -128 dargestellt wird.

byte läuft ja von -128 bis 127.

Irgendwie verstehe ich nicht, warum sie als -128 dargestellt wird. Also 
klar, ich weiß das der ab 127 bei -128 weiter läuft... Aber:

Ich würde es z. B. so machen.

127 + 128 + 127 = 2    und ich wäre bei -128 angekommen (oder nicht?). 
Dann müsste doch die Darstellung -126 sein und nicht -128 sein.

Klar - sollte sie nicht. -128 ist schon richtig, aber wie kann ich 
soetwas denn wirklich "bullet proof" per Hand rechnen so das ich mich da 
nicht andauernd um minimal-Werte verhauhe?

Liebe Grüße

von Peter II (Gast)


Lesenswert?

dazu fehlt noch die Festlegung wie die Negative zahl gespeichert wird, 
sonst kann man das überhaupt nicht sagen!

siehe: http://de.wikipedia.org/wiki/Zweierkomplement

von Peter II (Gast)


Lesenswert?


von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Kukuku schrieb:
> byte läuft ja von -128 bis 127.

Tut es das?

von Dummschwaetzer (Gast)


Lesenswert?

384: 0x180
aber: nur 8Bit! : 0x80;
damit hast du -128;

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Dummschwaetzer schrieb:
> damit hast du -128;

Wenn es vorzeichenbehaftet ausgewertet wird. Das aber muss es nicht.

von Kukuku (Gast)


Lesenswert?

Erstmal Vielen Dank für die Antworten.

Wir rechnen auf Grundlage von Java. Ich glaube Java stellt alle Zahlen 
im Zweierkomplement dar.

Rufus Τ. Firefly schrieb:
> Kukuku schrieb:
>> byte läuft ja von -128 bis 127.
>
> Tut es das?

Das steht so zumindest in meinem Script.

von -2^7 bis -2^7 - 1

Dummschwaetzer schrieb:
> 384: 0x180
> aber: nur 8Bit! : 0x80;
> damit hast du -128;

Auch wenn sich das gut anhört habe ich das lieder nicht verstanden.^^


Liebe Grüße und danke schonmal für die tolle Hilfe.

von Kukuku (Gast)


Lesenswert?

Also vielleicht ist nicht ganz klar was ich möchte.

ich habe soetwas gegeben:

(byte) 0x180

und ich soll jetzt sagen, welcher Wert nach der Konvertierung 
herauskommt. Ich kann das leider nur nicht rechnen, weil ich mich immer 
um wenige Stellen vertue. Ich würde nämlich die 180 per Hornerschema 
Dezimal darstellen und dann bis "0" loslaufen und gucken wie oft meine 
Dezimalzahl in -128 bis 127 passt und dann gucken wo ich herauskomme. 
Aber bei mir kommt dann immer -126 heraus, dabei sagt auch meine Ausgabe 
in Java das es -128 sein soll.

Wie kann ich das schnell und einfach per Hand anstellen?

von Dennis S. (eltio)


Lesenswert?

Ich kenne mich leider kaum in Java aus, aber die Darstellung der 
negativen, ganzen Zahlen mittels Zweierkomplement ist einfach 
alogithmisch durchführbar. Hier mal ein paar Anmerkungen in Kürze:

1) Du musst erstmal wissen ob die Zahl als negative Zahl betrachtet 
werden soll, denn im Speicher sind nur 0 und 1.
2) Umrechnen der Zahl in Binär:
   1 1000 0000
3) Invertieren (= Einerkomplement):
   0 0111 1111
4) Addieren von 1 (= Zweierkomplement):
   0 1000 0000
5) Zurück ins Dezimal:
   128
6) Da du weißt, dass es sich um eine negative Zahl handelt:
   -128

Bei Wikipedia ist das recht gut beschrieben.

Gruß
Dennis

P.S.: Den Bezug zum Horner-Schema verstehe ich nicht...!?

: Bearbeitet durch User
von Dennis S. (eltio)


Lesenswert?

Noch eine Ergänzung:
Unter [1] ist der von dir angegebene Wertebereich auch noch mal 
angegeben. Somit sollte der Aufgabentyp keine Probleme mehr bereiten! 
:-)

Gruß Dennis

[1] http://www.factsandmore.ch/?p=478

von Kukuku (Gast)


Lesenswert?

Dennis S. schrieb:
> 1) Du musst erstmal wissen ob die Zahl als negative Zahl betrachtet
> werden soll, denn im Speicher sind nur 0 und 1.
> 2) Umrechnen der Zahl in Binär:
>    1 1000 0000
> 3) Invertieren (= Einerkomplement):
>    0 0111 1111
> 4) Addieren von 1 (= Zweierkomplement):
>    0 1000 0000
> 5) Zurück ins Dezimal:
>    128
> 6) Da du weißt, dass es sich um eine negative Zahl handelt:
>    -128

Hallo Dennis. Angenommen deine Rechnung würde stimmen, wäre Schritt 5 
und 6 etwas sehr geschustert. Das da jetzt 128 rauskommt und das in den 
Wertebereich von byte passt, ist nur Zufall. Und eine weitere Überlegung 
zur negativen Zahl müsste ich dann trotzdem anstellen.

Du wandelst falsch ins Einerkomplement um.
Das Einerkomplement von 110000000 (= 384) ist 0110000000 (also einfach 
vorne eine 0 dran hängen). Das was du in Schritt 2 darstellt ist das 
Einerkomplement von 127.

Das zweierkomplement von 0110000000 ist dann 1010000000 (einfach von 
rechts bis zur ersten 1, dann invertieren - so kann man schritt 2 und 3 
zusammen packen) und daraus kann ich überhaupt keine Schlüsse über den 
Wert der Zahl ziehen, nur das ich zur Darstellung im Zweierkomplement 
von 384 eben 9 bit brauche, ich aber bei byte nur ausgeschrieben 7 bit 
zur Verfügung habe. => folgt nur das die Zahl nicht in meinen 
Wertebereich passt, aber bei Java gibts eben Over- und Underflow.

Also so kommen wir offensichtlich nicht weiter.


Dennis S. schrieb:
> P.S.: Den Bezug zum Horner-Schema verstehe ich nicht...!?

Naja. Ich kann jede Zahl mittels Horner Schema in einer Zahl beliebeiger 
Basis umwandeln.

0x180

Mittels Horner Schema Dezimal dargestellt.

180

0 + 1 = 1
1 * 16 = 16
16 + 8 = 24
24 * 16 = 384
384 + 0 = 384

von Karl H. (kbuchegg)


Lesenswert?

Kukuku schrieb:
> Also vielleicht ist nicht ganz klar was ich möchte.
>
> ich habe soetwas gegeben:
>
> (byte) 0x180

Die 0x180 sind 3 Hexadezimale Nibble, oder anders ausgedrückt 12 Bit.

Ein Byte hat aber nicht 12 Bit (3 Nibbles) sondern dessen nur 8 (2 
Nibbles).
D.h. da muss irgendwas unter den Tisch fallen.


Das Problem ist ungefähr dasselbe, wie wenn du ein Formular hast, in 
welches du eine 2-stellige Zahl eintragen sollst, du aber eine 
3-stellige Zahl hast.
1
                                              +---+---+
2
Aufgabe: schreibe die Zahl 378 in die Felder  |   |   |
3
                                              +---+---+

Es geht nicht. Iregendwas muss unter den Tisch fallen. Du kannst
1
                                              +---+---+
2
                                              | 7 | 8 |
3
                                              +---+---+

reinschreiben, aber das wars dann auch schon (ok, du hättest auch 37 
reinschreiben können, aber das ist nicht das was auf einem Computer 
passiert).

Dazu musst du überhaupt nichts rechnen, sondern dir nur die Ausgangszahl 
ansehen und wohin sie konvertiert wird.

In deinem Fall versuchst du die Hex-Zahl 0x180 in einem Byte
1
  +---+---+
2
  |   |   |
3
  +---+---+
unterzubringen, was natürlich nicht geht, weil 1 Byte nur maximal 
2-stellige Hex-Zahlen aufnehmen kann.
1
  +---+---+
2
  | 8 | 0 |
3
  +---+---+

Man kann das natürlich auch binär betrachten. Die Hex-Zahl 0x180 wäre 
binär
1
  1 1000 0000

ein Byte hat aber keine 9 Bit. 1 Byte hat 8 Bit. Also muss wieder etwas 
unter den Tisch fallen. Wie üblich sind es die höchstwertigeren Stellen, 
die da wegfallen
1
  1 1000 0000
2
      |
3
      | Reduktion auf 8 Bit
4
      v
5
    1000 0000

und wieder landen wir bei den 0x80, die denn entweder als signed oder 
als unsigned Zahl ausgegeben werden können. Als signed Zahl ausgegeben 
wäre das (wegen 2-er Komplement) -128. Als unsigned Zahl wäre das ganz 
banal +128.


Das du die dezimalen 380 natürlich erst mal fehlerfrei in eine Hex-Zahl 
umwandeln können musst, ist eine andere Sache. Tip: Der 
Windows-Taschenrechner in der Einstellung "Programmierer" kann dir 
helfen, deine Umrechnungen zu kontrollieren.

von Kukuku (Gast)


Lesenswert?

Karl Heinz, du bist mein persönlicher Held ^^

Vielen Dank für diese erste Sahne Erklärung. Jetzt ist es vollkommen 
klar.

Danke !

von Dennis S. (eltio)


Lesenswert?

Kukuku schrieb:
> Hallo Dennis. Angenommen deine Rechnung würde stimmen, wäre Schritt 5
> und 6 etwas sehr geschustert. Das da jetzt 128 rauskommt und das in den
> Wertebereich von byte passt, ist nur Zufall. Und eine weitere Überlegung
> zur negativen Zahl müsste ich dann trotzdem anstellen.
Was heißt denn "geschustert"? Wie gesagt, das sind Notizen. Das Thema 
wird ja auf unzähligen Webseiten ausgekaut, weswegen ich hier nicht 
erkläre wie man Zahlensysteme umrechnet.

> Du wandelst falsch ins Einerkomplement um.
> Das Einerkomplement von 110000000 (= 384) ist 0110000000 (also einfach
> vorne eine 0 dran hängen). Das was du in Schritt 2 darstellt ist das
> Einerkomplement von 127.
Bist du dir da sicher? Einerkomplement wird durch invertieren der Bits 
gebildet. Siehe z.B.: https://de.wikipedia.org/wiki/Einerkomplement

> Naja. Ich kann jede Zahl mittels Horner Schema in einer Zahl beliebeiger
> Basis umwandeln.
Sieht umständlich aus. Mag aber daran liegen, dass ich das Horner-Schema 
nie in dem Zusammenhang genutzt habe.

Gruß Dennis

Edit: Karl Heinz ist wie immer der Schnellste! ;-)

: Bearbeitet durch User
von Kukuku (Gast)


Lesenswert?

Dennis schrieb
> Bist du dir da sicher?

Meine Erklärung ist falsch, sorry, aber deine Rechnung ist trotzdem 
falsch^^ Das mit der 0 dran hängen ist direkt die Umwandlung ins 
Zweierkomplement (funktioniert nur bei positiven Zahlen).

z. B. 5  ist Binär 101

5 im Zweierkomplement ist dann vorne die 0 dran hängen = 0101.


Aber damit kann man dann auch direkt die -5 im zweier Komplement 
herleiten


1) 5 Binär = 101
2) 5 im Zweierkomplement  0101 (0 vorne dran  hängen).
3) von 5 zu -5, man nehme 0101, bis zur ersten 1 von rechts, rest 
invertieren = 1011


Also das was du in Schritt 2 darstellst, ist das Zweierkomplement von 
127, bzw wenn du die 0en vorne komplett streichst einfach nur 127 binär.

von Karl H. (kbuchegg)


Lesenswert?

Kukuku schrieb:
> Dennis schrieb
>> Bist du dir da sicher?
>
> Meine Erklärung ist falsch, sorry, aber deine Rechnung ist trotzdem
> falsch^^ Das mit der 0 dran hängen ist direkt die Umwandlung ins
> Zweierkomplement (funktioniert nur bei positiven Zahlen).

Nö.
Das ist Quatsch.

Einerkomplement bzw. Zweierkomplement hat per se erst mal nichts mit 
Bitzahlen zu tun.

Dass da eine führende 0 vorgestellt wird hat einfach nur damit zu tun, 
dass du bei Überlauf eine Stelle mehr brauchen würdest. Das ist aber im 
Grunde recht uninteressant, weil die überlaufenden Bits sowieso nicht 
mehr berücksichtigt werden.

Einerkomplement:    alle Bits umdrehen
Zweierkomplement:   alle Bits umdrehen UND dann noch 1 addieren.


> z. B. 5  ist Binär 101
>
> 5 im Zweierkomplement ist dann vorne die 0 dran hängen = 0101.
>
>
> Aber damit kann man dann auch direkt die -5 im zweier Komplement
> herleiten
>
>
> 1) 5 Binär = 101
> 2) 5 im Zweierkomplement  0101 (0 vorne dran  hängen).
> 3) von 5 zu -5, man nehme 0101, bis zur ersten 1 von rechts, rest
> invertieren = 1011


wie kann 1011 in einem System mit 3 Bits ein gültiges Ergebnis sein?

Entweder deine 5 hatte schon immer 4 Bits 0101 oder du rechnest eben 
alles mit 3 Bits.
Das sind führende 0-en! Davon kannst du links so viele anhängen wie du 
willst, deswegen ändert sich die Zahl nicht. Sinnvollerweise wird man 
soviele führende 0-en anhängen, wie man in der gewählten Repräsentierung 
(zb 1 Byte == 8 Bit) benötigt. Aber wenn du willst kannst du auch 379 
führende 0-en anhängen. Die 5 bleibt nach wie vor eine 5. Und hat mit 
einem Einerkomplement nicht das geringste zu tun.

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:

>> 1) 5 Binär = 101
>> 2) 5 im Zweierkomplement  0101 (0 vorne dran  hängen).
>> 3) von 5 zu -5, man nehme 0101, bis zur ersten 1 von rechts, rest
>> invertieren = 1011

Da scheint mir ein Missverständnis vorzuliegen.
2-er Komplement bezeichnet das Vorgehen, welches man benutzt um aus 
einer Zahl die jeweils negative Zahl zu machen.

Der Vorgang um aus
1
+5      0000 0101
2
3
        1111 1010      alle Bits umdrehen
4
        1111 1011      noch 1 addieren
5
6
1111 1011 ist das 8-Bit Bitmuster für -5
zu erhalten, den nennt man das 2-er Komplement.

gegenprobe: das negative von -5 ist ja +5
1
-5      1111 1011
2
3
        0000 0100   alle Bits umdrehen
4
        0000 0101   noch 1 addieren
5
6
das Bitmuster 0000 0101 ist das 8-Biot Bitmuster für +5

passt.

Noch eine Probe.
Es muss ja gelten  -5 + 5 ergibt 0
1
      1111 1011           -5
2
  +   0000 0101           +5
3
  --------------
4
    1 0000 0000
5
6
     da wir aber in 8 Bit rechnen, ist der Überlauf in die
7
     9. Stelle uninteressant, das Bit fällt einfach weg
8
9
      0000 0000           = 0

passt.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:


> Es muss ja gelten  -5 + 5 ergibt 0
> ...
> passt.


(und nebenbei bemerkt ist genau das letzte Beispiel schon die halbe 
Miete um die Bedeutung des 2-er Komplements zu verstehen. Ich muss mich 
nicht darum kümmern ob Zahlen positiv oder negativ sind. Ich addiere die 
einfach und es kommt immer das richtige raus - nur bei einem 
Overflow/Underflow muss man aufpassen ob der real ist, oder ob er durch 
die Art der Darstellung hervorgerufen wurde)
um +8 + (-6) zu rechnen:
1
+8    0000 1000
um die Bitrepräsentierung für -6 zu bestimmen, nehm ich erst mal die 
Bitdarstellung für +6
1
+6    0000 0110
und wende das 2-er komplement an, um das zu negieren
1
      0000 0110
2
3
      1111 1001    alle Bits umdrehen
4
      1111 1010    und noch 1 addieren
die Binärdastellung für -6 lautet also 1111 1010
jetzt kann man die Addition machen
1
+8       0000 1000
2
-6     + 1111 1010
3
      ------------
4
       1 0000 0010
wieder: Da wir uns im 8 Bit Raum gewegen, fällt das Übertragsbit an der 
9. Stelle weg, und das Ergebnis lautet
1
         0000 0010    = 2
und 2 ist ja offensichtlich korrekt für 8 + (-6)

Aber lass uns mal 6 - 8 rechnen.
Das bitmuster für +6 lautet
1
+6    0000 0110
das Bitmuster für -8 lautet?
Na das bestimmen wir wieder aus dem Muster für +8, in dem wir die +8 
negieren.
1
+8   0000 1000
2
3
     1111 0111     alle Bits umdrehen
4
     1111 1000     und noch 1 addieren

Damit sind alle Zutaten beisammen um 6 + (-8) rechnen zu können

1
+6       0000 0110
2
-8     + 1111 1000
3
       ------------
4
         1111 1110

da das Ergebnis hier in der höchsten gültigen Stelle
1
         1111 1110
2
         ^
ein 1 Bit ist, wissen wir, dass es sich um ein negatives Ergebnis 
handelt. Aber welches?
nun dazu negieren wir einfach das Ergebnis, wir machen also aus -x ein 
+x und sehen uns an was dieses x ist. EIne Zahl negieren ist aber 
leicht. genau das ist ja, was das 2-er Komplement macht. ALso
1
Zahl     1111 1110
2
3
         0000 0001    alle Bits umdrehen
4
         0000 0010    und noch 1 addieren

Das Ergebnis, 0000 0010, erkenn wir als die Binärrepräsentierung von 
dezimal 2 wieder. Wenn das aber +2 ist, dann muss die Ausgangsbasis 1111 
1110 ein -2 gewesen sein.

6 + (-8) liefert also das Ergebnis -2.
Und auch das ist offensichtlich korrekt.

: Bearbeitet durch User
von Amateur (Gast)


Lesenswert?

@Kukuku

Auch mit einem Hammer bekommst Du 384 in kein Byte.

Ein einfaches Beispiel hierzu: 8 Stellen (binär)   0 ... 255
                               2 Stellen (dezimal) 0 ... 99

Alle Zahlen oberhalb von 255 (bin) oder 99 (dez) klemmen.

Die ganze Spielerei mit dem Vorzeichen bringt auch nichts, denn 8 
Stellen sind 8 Stellen.
Willst Du ein Vorzeichen haben, so klaust Du Dir eine Stelle und hast 
nur noch 7 Stellen. Die 8. Stelle ist dann das Vorzeichen. Für die 
Zahlen bleiben dann nur noch 7 Bit also 127 bis 0 bis -128. Oder so.

von Rainer V. (rudi994)


Lesenswert?

Nur mal zur Vervollständigung des Durcheinanders:
Führende Nullen werden vorangestellt und nicht angehängt. Durch Anhängen 
einer Null wird eine Zahl um 1 Ziffernstelle nach links geschoben, also 
mit der Systemzahl multipliziert. Dezimalzahlen haben keine führenden 
Nullen, außer im Display von alten Rechenmaschinen, wo zum Rechnen noch 
an einer Kurbel gedreht werden muß.

von Arc N. (arc)


Lesenswert?

Noch kurz der Verweis auf die Java-Dokumentation.
http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html
"A narrowing conversion of a signed integer to an integral type T simply 
discards all but the n lowest order bits, where n is the number of bits 
used to represent type T. In addition to a possible loss of information 
about the magnitude of the numeric value, this may cause the sign of the 
resulting value to differ from the sign of the input value. "

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.