# Integer und Bit-operationen



## phyrexianer (8. Jan 2008)

Also ich habe fogelnden Code geschrieben


```
private BitSet getBitSetfromInteger(int i){
		String tmp = Integer.toBinaryString(i);
		BitSet bitSet = new BitSet(tmp.length());
		for (int j =0;j< tmp.length();j++){
			Character tmpChar = tmp.charAt(j);
			if(tmpChar.compareTo('1')==0)bitSet.set(j);
		}
		return bitSet;
	}
```

meine Frage ist es ganz einfach gibt es eine einfachere Möglichkeit bit-operationen auf einen Integer an zu wenden ???

Ich habe kurz gesagt ein Integer und möchte einzelne Bits setzen. mache hier halt den Umweg über BitSet.....


----------



## maki (8. Jan 2008)

Könntest die Bitoperatoren verwenden:
&
|
^

Mit Beispielen: http://www.vipan.com/htdocs/bitwisehelp.html


----------



## Der Müde Joe (8. Jan 2008)

phyrexianer hat gesagt.:
			
		

> meine Frage ist es ganz einfach gibt es eine einfachere Möglichkeit bit-operationen auf einen Integer an zu wenden ???



Naja einfacher?


```
public static int setBit(int value, int setter){
        return value ^ setter;
    }
```

zb:

value: 32 --> 100000
setter: 7 --> 111

return 100111

und nochmals mit setter durch wieder 100000


----------



## phyrexianer (8. Jan 2008)

ok, meine Frage war wohl doch etwas undeutlich.....   Ich habe eine Anwednung welche Bits als Flags benutzt bzw. als true oder false.  jetzt kann ich allerdings nur das komplette Array lesen bzw. schreiben und nicht die Einzelnen Bits abfragen. Jetzt will ich um die Einstellung an dem Gerät vor nehmen zu können die einzelnen bits lesen also mir wäre eine Methode ala 
	
	
	
	





```
setBit(int positon,int value) 
setBit(int positon,boolean value)"
```
 dann muss ich wieder das BitSet in  einen Integer wandeln und übertragen.

Meine Hintergedanke war folgender, da ja der Integer aus Bits besteht.... gebe es vielleicht eine Möglichkeit diese direkt an zu sprechen....


----------



## phyrexianer (8. Jan 2008)

maki hat gesagt.:
			
		

> Könntest die Bitoperatoren verwenden:
> &
> |
> ^
> ...



das ist nicht verkehrt also der Link.... aber wenn ich die ganze geschichte mit den so aufziehe wie im Beispielcode hab ich verdammt viel arbeit um 10 Bits willkürlich zu setzten muss ja dann 2^9 Möglichkeiten Brücksichtigen.... aber mal sehen ob ich das eventuell meinen Bedürfnissen anpassen kann.


----------



## Der Müde Joe (8. Jan 2008)

evtl so:

```
public static int flipBit(int value, int pos){
        if(pos < 0 || pos > 32){
            //shit
        }
        int s = (int)Math.pow(2, pos);
        return value ^ s;
    }
```

EDIT:
ungetestet..aber sollte ca gehen


----------



## Backwardsman (8. Jan 2008)

so hätt ich das auch gemacht... allerdings kann man sich das aufwendige Math.pow sparen  ;-)

... so in der Art...

```
public static int flipBit(int value, int pos) {
        if(pos < 0 || pos > 32){
            //shit
        }
        return value ^ (1 << pos);
    }
```


----------



## phyrexianer (8. Jan 2008)

ja das ist soweit ganz gut mit dem Bit verschieben wenn man davon ausgeht das die anderen Bits einen nicht interessieren!!! wenn ich das mit 1 << verschiebe werden ja die anderen Bits mit 0 aufgefüllt... ich soll will ja die Bits an einer bestimmen stelle ändern, ohne die anderen Bits zu verändern.  also im Ergbniss dürfen sie sich nicht verändert haben... was ja beim schieben nicht so ist. 

Was ich jetzt schade finde ist, dass so grundlegende Operationen bzw. doch recht kompliziert um zu setzten sind.


----------



## Ark (8. Jan 2008)

@phyrexianer: Eigne dir bitte die Grundlagen von Binärarithmetik und Boolescher Algebra an. In Java verknüpfen folgende Operatoren alle Bits zweier Ganzzahlen entsprechend:
& für AND
| für OR
^ für XOR

Der Operator ~ bildet das Einerkomplement einer Zahl.

Ark


----------



## Backwardsman (9. Jan 2008)

naja, ganz einfach... wenn du das a-te, b-te und c-te bit switchen willst machst du einfach


```
return value ^ ((1 << a) + (1 << b) + (1 << c));
```



> Was ich jetzt schade finde ist, dass so grundlegende Operationen bzw. doch recht kompliziert um zu setzten sind.



Naja, java ist halt einfach nicht dafür ausgelegt, an einzelnen bits rumzumanipulieren... aber wenn man sich einigermaßen mit den bit-operanten auskennt, geht es ganz leicht, wie du siehst ;-)


----------



## phyrexianer (9. Jan 2008)

@Backwardsman

ja das habe ich Begriffen jedoch erfüllt es nicht ganz meinen Zweck....  du verknüpfst die Integer über ein XOR welcher mir nur dann den Wert ändert wenn die werte unterschiedlich sind  das heißt wenn ich mein ursprungswert 1001 ist und ich die letzte 1 auf eine null haben will muss ich es mit einer 1^1 das und wenn ich wieder eine 1 haben will dann  wieder mit 0^1 , das hat diesen schön "flip" effekt... ich hätte halt gerne den "set" effekt ;-)  

im folgenden seht ihr meine Hilfsklasse
	
	
	
	





```
public class BitEditor {
	private BitSet bitSet;
	private int value;
	private boolean bit;
	
public BitEditor() {
	// TODO Auto-generated constructor stub
}

public Integer setBit(int vValue,int pos,boolean bitValue){
	
	String tmp = Integer.toBinaryString(vValue);

	bitSet = new BitSet(32);
	for(int i=0; i<tmp.length();i++){
		if(tmp.charAt(i)=='1')bitSet.set(i);
	}
	bitSet.set(pos, bitValue);
	return value;
	
}

}
```

muss hier noch den Schritt von dem BitSet zum Integer machen was ich wohl über Math.pow() und einer schleife machen werde.


----------



## Der Müde Joe (9. Jan 2008)

hmmm....

enjoy...

```
public static int setBit(int value, int position){
        int bitToSet = 1 << position;
        //mach ein OR: sicher 1 nachher
        return value | bitToSet;
    }
    
    public static int unsetBit(int value, int position){
        int bitToNull = 1 << position;
        //setze OR: sicher 1 : dann XOR: sicher 0
        return (value | bitToNull )^ bitToNull;
    }
```

ungetestet...


----------



## phyrexianer (9. Jan 2008)

das sieht gut aus.... sowas wollte ich haben ;-) werde es mal gleich testen!


----------



## phyrexianer (9. Jan 2008)

So wie es aussieht geht es... bzw. scheint bisher zu funktionieren.... habe es auch gleichzeitig erweitert um eine Abfrage wobe eine true oder false Ausgabe etwas mehr Sinn ergibt als eine zahl ungleich null raus zu geben !?!


```
public static int setBit(int value, int position){
        int bitToSet = 1 << position;
        //mach ein OR: sicher 1 nachher
        return value | bitToSet;
    }
   
    public static int unsetBit(int value, int position){
        int bitToNull = 1 << position;
        //setze OR: sicher 1 : dann XOR: sicher 0
        return (value | bitToNull )^ bitToNull;
    }
    
    public static boolean getBit(int value, int position){
    	int bitToGet = 1 << position;
    	//setze UND: alle bits bis auf das gefragte auf 0 wenn Bit gesetzt ergebniss ungleich 0
    	if((value & bitToGet)!=0)return true;
    	else return false;
    }
```

@Ark 
die Grundlagen zu kennen und mit Ihnen zu arbeiten sind doch unterschiedliche Dinge in meinen Augen. So habe ich ein Beispiel bekommen konnte damit Arbeit daraus was lernen und es gleichzeitig "erweitern" bzw. das neu gelernte anwenden.

@Der Müde Joe
Danke nochmals ;-)


----------



## Backwardsman (9. Jan 2008)

phyrexianer hat gesagt.:
			
		

> ja das habe ich Begriffen jedoch erfüllt es nicht ganz meinen Zweck....  du verknüpfst die Integer über ein XOR welcher mir nur dann den Wert ändert wenn die werte unterschiedlich sind  das heißt wenn ich mein ursprungswert 1001 ist und ich die letzte 1 auf eine null haben will muss ich es mit einer 1^1 das und wenn ich wieder eine 1 haben will dann  wieder mit 0^1 , das hat diesen schön "flip" effekt... ich hätte halt gerne den "set" effekt ;-)



und NOCHMAL... schau dir die bit-operatoren an!!! wenn du die Set-Methode realisieren willst nimmst du halt statt XOR ein OR und wenn du eine unset-Methode brauchst invertierst du die zahl und machst ein AND (oder ähnliches).

weißt du überhaupt was die operatoren OR, AND, NOR, XOR, NOT und wie sie alle heißen machen??



> Was ich jetzt schade finde ist, dass so grundlegende Operationen bzw. doch recht kompliziert um zu setzten sind.


ich weiß nicht, was daran kompliziert sein soll, alles was du vorhast lässt sich mit einer ein bis maximal zweizeiligen funktion realisieren!


----------



## Hilefoks (9. Jan 2008)

Backwardsman hat gesagt.:
			
		

> > Was ich jetzt schade finde ist, dass so grundlegende Operationen bzw. doch recht kompliziert um zu setzten sind.
> 
> 
> 
> Naja, java ist halt einfach nicht dafür ausgelegt, an einzelnen bits rumzumanipulieren... aber wenn man sich einigermaßen mit den bit-operanten auskennt, geht es ganz leicht, wie du siehst ;-)



Das stimmt so nicht. Java bietet alle Funktionen die man für Bit-Operationen benötigt. Auch sind diese die gleichen wie in anderen Sprachen - d.h. auch C, C++, Python, Groovy oder PHP (um nur einige zu nennen) bieten auf dieser Ebene nicht mehr "komfort". Komplizierter, im Vergleich zu C/C++, wird Java erst dann wenn es um vorzeichenlose Datentypen geht. Aber danach wurde hier ja letztlich nicht gefragt.

Die Bit-Operationen sind letztlich elementare mathematische Grundlagen. Genauso wie Arithmetik oder Algebra. Die Programmiersprache oder gar den Computer kann man nicht verantwortlich machen wenn man diese mathematischen Grundlagen nicht beherrscht.


> Computer rechnen vor allem damit, dass der Mensch denkt!



MfG,
Hilefoks


----------



## Leroy42 (9. Jan 2008)

Hilefoks hat gesagt.:
			
		

> > Computer rechnen vor allem damit, dass der Mensch denkt!



Gefällt mir! Weißt du von wem das ist?


----------



## Hilefoks (9. Jan 2008)

Leroy42 hat gesagt.:
			
		

> Gefällt mir! Weißt du von wem das ist?


Nein - leider nicht. Laut Wikiquote ist der Author leider unbekannt.

MfG,
Hilefoks


----------



## Backwardsman (10. Jan 2008)

Hilefoks hat gesagt.:
			
		

> Backwardsman hat gesagt.:
> 
> 
> 
> ...


naja, warum stimmt das den nicht? was ist denn jetzt der unterschied zwischen "nicht dafür ausgelegt" und "bietet nicht den komfort". wenn die java-entwickler gewollt hätten, dass man unsigned variablen hat (und direkte bit-manipulations-funktionen), dann hätten sie diese einem auch zur verfügung gestellt, wie es halt bei anderen programmiersprachen auch der fall ist! es geht natürlich schon, aber nur über umwege, java ist also nicht dafür vorgesehen/ausgelegt bzw. man hat nicht den gleichen komfort wie bei anderen sprachen ;-)


----------



## phyrexianer (10. Jan 2008)

@all danke für alles aber so eine Diskussion habe ich nicht erwartet... zudem wurde ja mein Problem gelöst und ich weis nicht ob Ihr euch auch meinen letzten Beitrag durchgelesen habt aber da habe ich denke ich deutlich zu verstehen gebeben dass es mit den XOR AND OR usw. gut geklappt nach dem Beispiel von "Der Müde Joe".

Mein "Fehler" wenn man es so nennen kann war folgender... ich habe eine Methode in der Form von "Object.setBit(int value, int pos)" von Java erwartet bzw. es zu einer Grundlegenden Operation zugeordnet wie + oder - oder * und da ich nach einer "BitOperation.class" gesucht habe habe ich BitSet gefunden welche das ja bereitstellt was ich will jedoch musste ich ja da die Bits erst reinbekommen und konnte das nicht einfach auf einen Integer anwenden.  Deswegen auch mein Posting ob es einen besseren Weg gibt was ja scheinbar mit den logischen Operation doch recht "simpel" zu realisieren war.

@Backwardsman Ja ich kenne die Bedeutung der logischen Operatoren aber blos weil man ein Auto hat ist man noch lange nicht ein Ralley-Fahrer (Auch wenn es hier nur um den Gang einlegen geht)


----------



## Bernd das Brot (10. Jan 2008)

Der Müde Joe hat gesagt.:
			
		

> ```
> public static int unsetBit(int value, int position){
> int bitToNull = 1 << position;
> //setze OR: sicher 1 : dann XOR: sicher 0
> ...



Sorry, aber da MUSS ich einfach kurz noch was zu sagen, denn der unsetBit ist recht "unelegant"


```
public static int unsetBit(int value, int position){
        return value & (~(1<<position));
    }
```

Ein paar Beispiele der Binärithmetik:


```
// Bit 7 gesetzt, damit die Ausgabe hübsch ist.
	int value = 0x8000;
	System.out.println("0b" + Integer.toBinaryString(value));

	int bit = 4; // 4. Bit setzen und löschen
	value |= (1<<bit);
	System.out.println("0b" + Integer.toBinaryString(value));
			
	value &= ~(1<<bit);
	System.out.println("0b" + Integer.toBinaryString(value));
			
	// eine andere interessante Maske, die ALLE BITS AB Position verändert:
	value = 0xFFFF;
	value &= ~((1<<bit)-1);
	System.out.println("0b" + Integer.toBinaryString(value));
			
	// Ganzahlige Division durch 2
	value = 5;
	value >>=1;
	System.out.println("0b" + Integer.toBinaryString(value));
			
	// Ganzahlige Multiplikation mit 2
	value = 5;
	value <<=1;
	System.out.println("0b" + Integer.toBinaryString(value));
	// Analog mit 4, 8, 16, ...
```

XOR (das ^ Hütchen) kann man herrvoragend zum Maskieren verwenden, wobei die verwendete Maske sowas wie ein Schlüssel ist. Billige krytographische Techniken basieren auf XOR.

Auf eines muss ich noch hinweisen: und zwar, daß der int signed ist - also per Zweierkomplement negative Zahlen darstellt. Das *kann* problematisch werden, wenn man das 15. Bit setzt.
Ferner ist es wichtig, daß Maske und Wert beide vom gleichen Typ sein sollten. Andernfalls muss man genau wissen, was man tut.


----------



## Bernd das Brot (10. Jan 2008)

Zum Ehrenrettung von XOR noch eine Bemerkung dazu:

In Assembler sieht man oft den folgenden Befehl: 
	
	
	
	





```
XOR eax, eax
```

Was macht das? Ganze einfach: das Register eax ist danach 0 - dieser Befehl braucht nur einen Takt-Zyklus und nur einen OP-Code puls einen Operanden-Code (für's Register). Damit ist der Befehl schneller und kürzer, als 
	
	
	
	





```
MOV eax, 0
```
, der 6 Byte benötigt.

In Java entspricht das:

```
int a = 15;
a ^= a;
System.out.println(a); // <-- a ist wieder 0
```

In Java braucht man das allerdings doch recht selten


----------

