unsigned int

Status
Nicht offen für weitere Antworten.

Evolver

Bekanntes Mitglied
Irgendwie steh ich gerade auf'm Schlauch. Ich muss folgende C-Zeile in JAVA überführen, hab aber Probleme wegen dem parsen auf unsigned int:

int new_x = (unsigned int)(x - ((4 * scr_x) / z)) % 1000;

Also wie mach ich das?
 
G

Guest

Gast
Code:
int new_x = Math.abs(x - (4 * scr_x) / z) % 1000;
 

Evolver

Bekanntes Mitglied
Nein. Das parsen auf unsigned int liefert nicht den Betrag des Wertes.
Einfach ausgedrückt wird bei int das höchste Bit als Vorzeichen gewertet und bei unsigned int als normaler Teil der Zahl.
 

Evolver

Bekanntes Mitglied
Na so schlau war ich auch schon. Darum frage ich ja, wie ich diese C-Zeile in JAVA überführen kann.
 

Evolver

Bekanntes Mitglied
Nein, weil ja die negativen Werte trotzdem negativ bleiben und nicht zu ihrem (binären) positiven Äquivalent werden.
 
B

Beni

Gast
Ein Cast von int auf long kann man machen, ohne dass das Vorzeichen da bleibt: man setzt die ersten 32 Bits einfach explizit auf 0:
Code:
int x = -123;
		
int last = x & 0xFFFF;
int first = x >> 16 & 0xFFFF;
		
long y = (long)first << 16 | last;
		
System.out.println( "int:  " + Integer.toBinaryString( x ) );
System.out.println( "long: " + Long.toBinaryString( y ) );
 

thE_29

Top Contributor
Warum wird net diese abs (absolute) Methode genommen??

Die tut das Minuszeichen weg ^^


oder aber

if(wert < 0)
wert *= -1;


Da braucht man net bitwixen :bae:
 
B

Beni

Gast
Uf, ich geh mal ein bisschen meditieren und über mich selbst reflektieren... :roll:

@the_29
Es geht nicht nur darum das - wegzubringen, die Bits sollten erhalten bleiben.... (und bei einem Math.abs verändert sich jedes einzelne bit).
 

thE_29

Top Contributor
Unterschied bitte Kennzeichnen:

Code:
    int mzahl = -100;
    
    System.out.println("Ori: " + Integer.toBinaryString(mzahl));
    
    mzahl = Math.abs(mzahl);

    System.out.println("mod: " + Integer.toBinaryString(mzahl));
    mzahl = -100;

    System.out.println("Ori: " + Integer.toBinaryString(mzahl));
    
    mzahl *=  -1;
    
    System.out.println("mod: " + Integer.toBinaryString(mzahl));

    int last = mzahl & 0xFFFF;
    int first = mzahl >> 16 & 0xFFFF;
    long yyy = (long)first << 16 | last;

    System.out.println("Beni1: " + Integer.toBinaryString(last));
    System.out.println("Beni2: " + Long.toBinaryString(yyy));


Ausgabe hat gesagt.:
Ori: 11111111111111111111111110011100

mod: 1100100

Ori: 11111111111111111111111110011100

mod: 1100100

Beni1: 1100100

Beni2: 1100100

Sieht für mich irgendwie gleich aus, stellt sich nur die Frage was schneller/einfacher ist ;)
 

thE_29

Top Contributor
Wobei die Ori Zahl: 4294967295 (höchster Int wert) - 99 (wegen 0) = 4294967196 == 11111111111111111111111110011100) genau das umgekehrte eigentlich ist...

Sehr sehr kömisch..
 
B

Beni

Gast
Also die richtige Ausgabe wäre mal "11111111111111111111111110011100" (32 bit, kann man schnell bestätigen, dass das -100 ist), das sollte irgendwie da bleiben.

Dein "mod" stimmt also hinten und vorne nicht, schau dir nur schon die Anzahl Bits auf 1 an :wink:

Dass du meinen Code bei Beni1 falsch abgetippt hast, dafür kann ich nix.
Dass du mir überhaubt eine falsche Eingabe (100 anstelle von -100) lieferst, dafür kann ich auch nix.

Einen unsigned int kann in Java mit long "so halb" simulieren, und der Long muss dasselbe Bitmuster wie der int haben, und sorry, das sehe ich bei deinem Zeugs überhaupt nicht :wink:

Stevg's Lösung ist IMHO schon die beste von allem bisher präsentierten :bae:
 

thE_29

Top Contributor
Bitte zeig mir wie deine Lösung bitte funktioniert und wo ich was falsch abgetippt habe (habe nämlich paste and copy gemacht ^^)

Außerdem was passt wo nicht??



Nachtrag: habe vergessen die Zahl zum Zurücksetzen:


Code:
    int mzahl = -123;
    System.out.println("Ori: " + Integer.toBinaryString(mzahl));
    
    mzahl = Math.abs(mzahl);

    System.out.println("mod: " + Integer.toBinaryString(mzahl));
    mzahl = -123;

    System.out.println("Ori: " + Integer.toBinaryString(mzahl));

    mzahl *=  -1;
    
    System.out.println("mod: " + Integer.toBinaryString(mzahl));

    mzahl = -123;

    int last = mzahl & 0xFFFF;
    int first = mzahl >> 16 & 0xFFFF;
    long yyy = (long)first << 16 | last;

    System.out.println("Beni1: " + Integer.toBinaryString(last));
    System.out.println("Beni2: " + Long.toBinaryString(yyy));    
    
    yyy = mzahl * 0xFFFFFFFFL;
    
    System.out.println("stev: " + Long.toBinaryString(yyy));


Ausgabe hat gesagt.:
Ori: 11111111111111111111111110000101

mod: 1111011

Ori: 11111111111111111111111110000101

mod: 1111011

Beni1: 1111111110000101

Beni2: 11111111111111111111111110000101

stev: 1111111111111111111111111000010100000000000000000000000001111011


Nachtrag2: Wollte grad ein C Tool testen, aber in dem ollen windoof geht das anscheinend net, weil der dem Typ int alles verpasst...
 

Evolver

Bekanntes Mitglied
stevg hat genau das gemacht, was ich brauche. Nur dass ich nicht extra ne long-Variable will, sondern die int so, dass das höchste Bit immer Null ist. Also habe ich es jetzt wie folgr angestellt:

x = x & Integer.reverse(0xFFFFFFFE);

Das müsste so stimmen, oder hat jemand Einwände?
 

Evolver

Bekanntes Mitglied
Ja, bin nur ein bisschen auf Kriegsfuß mit HexZahlen, darum hab ich die nicht gefunden und mich des reverse() bedient.
 
B

Beni

Gast
Meine güte, was hast du getrunken? Wird ja mit jedem Post schlimmer :shock: (stevgs Code hast du auch nicht erwischt).

Code:
    // hier sollte nicht "last" sondern "mzahl" eingetragen sein. 
    System.out.println("Beni1: " + Integer.toBinaryString(last)); // <<<<
    System.out.println("Beni2: " + Long.toBinaryString(yyy));    
    
   // Und hier nicht * sondern &
    yyy = mzahl * 0xFFFFFFFFL; // <<<<<<<
    
    System.out.println("stev: " + Long.toBinaryString(yyy));

Was nicht passt:
"1111011" und "11111111111111111111111110000101" sind komplett andere Bitmuster.Ein unsigned int und ein signed int stellen andere Zahlenräume dar, die sich allerdings teilweise überschneiden.

Der Evolver möchte sein Ergebnis gerne als unsigned int ansehen, aber er bekommt einen signed int. Jetzt muss er das irgendwie umrechnen, den signed int als unsigned int interpretieren. Dieses Umrechnen bedeutet aber: die Bits so lassen wie sie sind, und das erste bit (das derzeitige sign-bit) als ein b*2^31 verstehen.
Bei Java ist das nicht vorgesehen, aber wenn er den int in einen long übertragen kann (ohne dass sich das Bitmuster der letzten 32 bits ändert, und die ersten 32 bits 0 bleiben, somit keinen Einfluss haben), bekommt er (annähernd) das Verhalten eines unsigned Ints.

Und jetzt erkläre mir, wieso du denkst, das deine Lösung richtig (und meine falsch) ist, schliesslich habe ich keine Garantie auf Korrektheit in meinen Gedankengängen :wink:
 
G

Guest

Gast
mal was anderes, der cast

int new_x = (unsigned int)(x - ((4 * scr_x) / z)) % 1000;

auf unsigned int ist doch überflüssig?
es kommt doch eher drauf an, als was es ausgeben wird ob mit %i bzw %d oder mit %u
 

thE_29

Top Contributor
Jop!

Der Cast ist total unsinnig....

Habes vorher mit C probiert..

Dem ist das auch egal ob das unsinged int oder signed int steht, der speichert trotzdem die Minuswerte (weil eben ja nur Bitmuster) schön brav ab!!

@beni: okay, das last ist falsch, aber das andere passt und stevs Lösung habe ich auch nur copy und paste.. (maybe hat ers geändert oder ich dreh bald durch)


Und wo habe ich jemals gesagt das deine falsch ist? (Ich fragte nur wo der Unterschied ist, weil bei mir keiner war, daja falsch eingetippt)


Ausgabe von C hat gesagt.:
Signed (-123): 11111111111111111111111110000101
Unsigned (4294967173 == -123): 11111111111111111111111110000101
Code:
int cmp_int = -123;
	printf("\nSigned (%d): ",cmp_int);
	for(int i1=0; i1 < 4*8;i1++)
	{
		
		
		if(cmp_int & 0x80000000)
		{ printf("1"); }
		else 
		{	printf("0"); }
		cmp_int = cmp_int << 1;
	}	

	cmp_int = -123;
	unsigned int ucmp_int = (unsigned int) cmp_int;
	printf("\nUnsigned (%u == %d): ",ucmp_int,ucmp_int);
	for(i1=0; i1 < 4*8;i1++)
	{
		if(ucmp_int & 0x80000000)
		{ printf("1"); }
		else 
		{	printf("0"); }
		ucmp_int = ucmp_int << 1;
	}
 
B

Beni

Gast
Also in chronologischer Reihenfolge: zuerst hast du behauptet, man könne doch einfach "Math.abs" verwenden.

Dass das nicht die Lösung ist, da bist du ja einverstanden? (Das würde auch deinem C-Programm widersprechen).

Nun, wenn du mein Zeugs richtig eintippst :D wirst du sehen, dass es unterschiedeliche Ergebnisse gibt, das ist dann der Unterschied nach dem du fragst. Irgendwie glaube ich, ist das Problem bei dem missglückten Copy&Paste :wink:
 
S

stev.glasow

Gast
Das long yyy = (long)first << 16 | last; ist nicht on mir, auch nicht editiert oder so.
 

thE_29

Top Contributor
Jo, das deines anders ist is mir eh klar ;)

Nur anscheinend spinnt mein Copy & Paste :bae:


Bei mir kam es ja auf den Wert drauf an (sprich mit abs die richtige Lösung) und net auf das Bitmuster ^^
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben