diff --git a/btypes_big_integer/src/main/java/de/hhu/stups/btypes/BInteger.java b/btypes_big_integer/src/main/java/de/hhu/stups/btypes/BInteger.java
index aca62d9e50d3edb6abeb311aa2290087af7090bf..7df4aac3ae6e56c966b5a627b2ef60065734eb6b 100755
--- a/btypes_big_integer/src/main/java/de/hhu/stups/btypes/BInteger.java
+++ b/btypes_big_integer/src/main/java/de/hhu/stups/btypes/BInteger.java
@@ -6,96 +6,95 @@ import clojure.lang.BigInt;
 import clojure.lang.RT;
 import clojure.lang.Var;
 
-public class BInteger extends java.lang.Number implements Comparable<BInteger>, BObject {
+public final class BInteger extends java.lang.Number implements Comparable<BInteger>, BObject {
 
-	private static final Var PLUS = RT.var("clojure.core", "+");
+	public static final BInteger ZERO = new BInteger(0);
+	public static final BInteger ONE = new BInteger(1);
+	public static final BInteger TWO = new BInteger(2);
 
+	private static final Var PLUS = RT.var("clojure.core", "+");
 	private static final Var MINUS = RT.var("clojure.core", "-");
-
 	private static final Var MULTIPLY = RT.var("clojure.core", "*");
-
 	private static final Var DIVIDE = RT.var("clojure.core", "quot");
-
 	private static final Var MODULO = RT.var("clojure.core", "mod");
-
 	private static final Var COMPARE = RT.var("clojure.core", "compare");
-
-	public static final Var INC = RT.var("clojure.core", "inc");
-
+	private static final Var INC = RT.var("clojure.core", "inc");
 	private static final Var DEC = RT.var("clojure.core", "dec");
+	private static final Var SHIFT_LEFT = RT.var("clojure.core", "bit-shift-left");
+	private static final Var SHIFT_RIGHT = RT.var("clojure.core", "bit-shift-right");
+	private static final long serialVersionUID = -6484548796859331267L;
 
-	private static final Var BIGINT = RT.var("clojure.core", "bigint");
+	private final BigInt value;
 
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if (obj instanceof BInteger) {
-			return this.compareTo((BInteger) obj) == 0;
-		}
-		return false;
+	public BInteger(BigInt value) {
+		this.value = Objects.requireNonNull(value, "value");
 	}
 
-	private static final long serialVersionUID = -6484548796859331267L;
-	private BigInt value;
-
-	@Override
-	public int hashCode() {
-		return Objects.hash(value);
+	public BInteger(int value) {
+		this(BigInt.fromLong(value));
 	}
 
 	public BInteger(String value) {
+		BigInt parsed;
 		try {
-			this.value = BigInt.fromLong(Long.parseLong(value));
-		} catch (NumberFormatException e) {
-			this.value = BigInt.fromBigInteger(new java.math.BigInteger(value));
+			parsed = BigInt.fromLong(Long.parseLong(value));
+		} catch (NumberFormatException ignored) {
+			parsed = BigInt.fromBigInteger(new java.math.BigInteger(value));
 		}
+		this.value = parsed;
 	}
 
-	public BInteger(BigInt value) {
-		this.value = value;
+	public static BInteger build(int value) {
+		return new BInteger(value);
 	}
 
-	public BInteger(int value) { new BInteger(String.valueOf(value)); }
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj) {
+			return true;
+		} else if (!(obj instanceof BInteger)) {
+			return false;
+		} else {
+			return this.value.equals(((BInteger) obj).value);
+		}
+	}
 
-	public static BInteger build(int value) {
-		return new BInteger(String.valueOf(value));
+	@Override
+	public int hashCode() {
+		return this.value.hashCode();
 	}
 
+	@Override
 	public int compareTo(BInteger o) {
-		BInteger other = (BInteger) o;
-		return (int) COMPARE.invoke(this.value, other.value);
+		return (int) COMPARE.invoke(this.value, o.value);
 	}
 
 	public BBoolean lessEqual(BInteger o) {
-		return new BBoolean(this.value <= o.value);
+		return new BBoolean(compareTo(o) <= 0);
 	}
 
-
 	public BBoolean greaterEqual(BInteger o) {
-		return new BBoolean(this.value >= o.value);
+		return new BBoolean(compareTo(o) >= 0);
 	}
 
 	public java.math.BigInteger asBigInteger() {
-		return new java.math.BigInteger(String.valueOf(value));
+		return value.toBigInteger();
 	}
 
 	public BBoolean less(BInteger o) {
-		return new BBoolean(this.value < o.value);
+		return new BBoolean(compareTo(o) < 0);
 	}
 
 	public BBoolean greater(BInteger o) {
-		return new BBoolean(this.value > o.value);
+		return new BBoolean(compareTo(o) > 0);
 	}
 
 	public BBoolean equal(BInteger o) {
-		return new BBoolean(this.value == o.value);
+		return new BBoolean(compareTo(o) == 0);
 	}
 
 	public BBoolean unequal(BInteger o) {
-		return new BBoolean(this.value != o.value);
+		return new BBoolean(compareTo(o) != 0);
 	}
 
 	@Override
@@ -118,10 +117,8 @@ public class BInteger extends java.lang.Number implements Comparable<BInteger>,
 		return this.value.doubleValue();
 	}
 
-
 	public BInteger plus(BInteger o) {
-		BInteger other = (BInteger) o;
-		return new BInteger((BigInt) PLUS.invoke(this.value, other.value));
+		return new BInteger((BigInt) PLUS.invoke(this.value, o.value));
 	}
 
 	public java.lang.String toString() {
@@ -129,38 +126,39 @@ public class BInteger extends java.lang.Number implements Comparable<BInteger>,
 	}
 
 	public BInteger minus(BInteger o) {
-		BInteger other = (BInteger) o;
-		return new BInteger((BigInt) MINUS.invoke(this.value, other.value));
+		return new BInteger((BigInt) MINUS.invoke(this.value, o.value));
 	}
 
 	public BInteger multiply(BInteger o) {
-		BInteger other = (BInteger) o;
-		return new BInteger((BigInt) MULTIPLY.invoke(this.value, other.value));
+		return new BInteger((BigInt) MULTIPLY.invoke(this.value, o.value));
 	}
 
 	public BInteger power(BInteger exp) {
-		if(exp.equal(new BInteger("0")).booleanValue()) {
-			return new BInteger("1");
+		if (exp.isNotNatural().booleanValue()) {
+			throw new IllegalArgumentException("Exponent must be a natural number");
 		}
-		BInteger tmp = power(exp.divide(new BInteger("2")));
-		if(exp.modulo(new BInteger("2")).equal(new BInteger("0")).booleanValue()) {
-			return tmp.multiply(tmp);
-		} else {
-			if(exp.greater(new BInteger("0")).booleanValue()) {
-				return this.multiply(tmp.multiply(tmp));
-			} else {
-				return (tmp.multiply(tmp)).divide(this);
+
+		BInteger result = ONE;
+		while (true) {
+			if (ONE.equals(exp.modulo(TWO))) {
+				result = result.multiply(this);
 			}
+
+			exp = exp.divide(TWO);
+			if (ZERO.equals(exp)) {
+				return result;
+			}
+
+			result = result.multiply(result);
 		}
 	}
+
 	public BInteger divide(BInteger o) {
-		BInteger other = (BInteger) o;
-		return new BInteger((BigInt) DIVIDE.invoke(this.value, other.value));
+        return new BInteger((BigInt) DIVIDE.invoke(this.value, o.value));
 	}
 
 	public BInteger modulo(BInteger o) {
-		BInteger other = (BInteger) o;
-		return new BInteger((BigInt) MODULO.invoke(this.value, other.value));
+		return new BInteger((BigInt) MODULO.invoke(this.value, o.value));
 	}
 
 	public BInteger succ() {
@@ -172,11 +170,11 @@ public class BInteger extends java.lang.Number implements Comparable<BInteger>,
 	}
 
 	public BInteger leftShift(BInteger o) {
-		return null;
+		return new BInteger((BigInt) SHIFT_LEFT.invoke(this.value));
 	}
 
 	public BInteger rightShift(BInteger o) {
-		return null;
+		return new BInteger((BigInt) SHIFT_RIGHT.invoke(this.value));
 	}
 
 	public boolean isCase(BInteger o) {
@@ -204,7 +202,7 @@ public class BInteger extends java.lang.Number implements Comparable<BInteger>,
 	}
 
 	public BBoolean isNatural() {
-		return this.greaterEqual(new BInteger("0"));
+		return this.greaterEqual(ZERO);
 	}
 
 	public BBoolean isNotNatural() {
@@ -212,11 +210,10 @@ public class BInteger extends java.lang.Number implements Comparable<BInteger>,
 	}
 
 	public BBoolean isNatural1() {
-		return this.greater(new BInteger("0"));
+		return this.greater(ZERO);
 	}
 
 	public BBoolean isNotNatural1() {
 		return isNatural1().not();
 	}
-
-}
\ No newline at end of file
+}
diff --git a/btypes_big_integer/src/main/java/de/hhu/stups/btypes/BRelation.java b/btypes_big_integer/src/main/java/de/hhu/stups/btypes/BRelation.java
index 1d3816877bc9afdad4e77e5f057a86db81af425e..fdbbc1767c8b47bc5d2d1b7c32ca3acc69cc6cd4 100644
--- a/btypes_big_integer/src/main/java/de/hhu/stups/btypes/BRelation.java
+++ b/btypes_big_integer/src/main/java/de/hhu/stups/btypes/BRelation.java
@@ -200,11 +200,11 @@ public class BRelation<S,T> implements BObject, Iterable<BTuple<S,T>> {
 	}
 
 	public BInteger card() {
-		return new BInteger(String.valueOf((int) this.size()));
+		return new BInteger(this.size());
 	}
 
 	public BInteger _size() {
-		return new BInteger(String.valueOf((int) this.size()));
+		return new BInteger(this.size());
 	}
 
 	public BBoolean equal(BRelation<S,T> o) {
@@ -494,7 +494,7 @@ public class BRelation<S,T> implements BObject, Iterable<BTuple<S,T>> {
 
 	@SuppressWarnings("unchecked")
 	public T first() {
-		return this.functionCall((S) new BInteger("1"));
+		return this.functionCall((S) BInteger.ONE);
 	}
 
 	@SuppressWarnings("unchecked")
@@ -506,7 +506,7 @@ public class BRelation<S,T> implements BObject, Iterable<BTuple<S,T>> {
 	public BRelation<S,T> reverse() {
 		BInteger size = this.card();
 		PersistentHashMap resultMap = PersistentHashMap.EMPTY;
-		for(BInteger i = new BInteger("1"); i.lessEqual(size).booleanValue(); i = i.succ()) {
+		for(BInteger i = BInteger.ONE; i.lessEqual(size).booleanValue(); i = i.succ()) {
 			T rangeElement = (T) this.functionCall((S) size.minus(i).succ());
 			resultMap = (PersistentHashMap) ASSOC.invoke(resultMap, i, SET.invoke(SEQ.invoke(LIST.invoke(rangeElement))));
 		}
@@ -522,7 +522,7 @@ public class BRelation<S,T> implements BObject, Iterable<BTuple<S,T>> {
 	public BRelation<S,T> tail() {
 		BInteger size = this._size();
 		PersistentHashMap resultMap = PersistentHashMap.EMPTY;
-		for(BInteger i = new BInteger("2"); i.lessEqual(size).booleanValue(); i = i.succ()) {
+		for(BInteger i = BInteger.TWO; i.lessEqual(size).booleanValue(); i = i.succ()) {
 			T rangeElement = (T) this.functionCall((S) i);
 			resultMap = (PersistentHashMap) ASSOC.invoke(resultMap, i.pred(), SET.invoke(SEQ.invoke(LIST.invoke(rangeElement))));
 		}
@@ -560,7 +560,7 @@ public class BRelation<S,T> implements BObject, Iterable<BTuple<S,T>> {
 		PersistentHashMap resultMap = this.map;
 		PersistentHashMap otherMap = arg.map;
 		BInteger size = this.card();
-		for(BInteger i = new BInteger("1"); i.lessEqual(arg._size()).booleanValue(); i = i.succ()) {
+		for(BInteger i = BInteger.ONE; i.lessEqual(arg._size()).booleanValue(); i = i.succ()) {
 			resultMap = (PersistentHashMap) ASSOC.invoke(resultMap, size.plus(i), (PersistentHashSet) GET.invoke(otherMap, i));
 		}
 		return new BRelation<S, T>(resultMap);
@@ -570,7 +570,7 @@ public class BRelation<S,T> implements BObject, Iterable<BTuple<S,T>> {
 	public <R,A> T conc() {
 		BRelation<R,A> result = new BRelation<R,A>();
 		BInteger size = this.card();
-		for(BInteger i = new BInteger("1"); i.lessEqual(size).booleanValue(); i = i.succ()) {
+		for(BInteger i = BInteger.ONE; i.lessEqual(size).booleanValue(); i = i.succ()) {
 			result = result.concat((BRelation<R,A>) functionCall((S) i));
 		}
 		return (T) result;
@@ -588,10 +588,10 @@ public class BRelation<S,T> implements BObject, Iterable<BTuple<S,T>> {
 		PersistentHashMap resultMap = PersistentHashMap.EMPTY;
 		PersistentHashMap thisMap = this.map;
 		BInteger size = this._size();
-		for(BInteger i = new BInteger("1"); i.lessEqual(size).booleanValue(); i = i.succ()) {
+		for(BInteger i = BInteger.ONE; i.lessEqual(size).booleanValue(); i = i.succ()) {
 			resultMap = (PersistentHashMap) ASSOC.invoke(resultMap, i.succ(), (PersistentHashSet) GET.invoke(thisMap, i));
 		}
-		resultMap = (PersistentHashMap) ASSOC.invoke(resultMap, new BInteger("1"), (PersistentHashSet) SET.invoke(SEQ.invoke(LIST.invoke(arg))));
+		resultMap = (PersistentHashMap) ASSOC.invoke(resultMap, BInteger.ONE, (PersistentHashSet) SET.invoke(SEQ.invoke(LIST.invoke(arg))));
 		return new BRelation<S, T>(resultMap);
 	}
 
diff --git a/btypes_big_integer/src/main/java/de/hhu/stups/btypes/BSet.java b/btypes_big_integer/src/main/java/de/hhu/stups/btypes/BSet.java
index 068d11a96471ac36676a2775c010e327dc55085e..b6df22b3149c66acd2b3120ecb9a6c754403da29 100755
--- a/btypes_big_integer/src/main/java/de/hhu/stups/btypes/BSet.java
+++ b/btypes_big_integer/src/main/java/de/hhu/stups/btypes/BSet.java
@@ -213,7 +213,7 @@ public class BSet<T> implements BObject, Set<T> {
 
 	public static BSet<BInteger> interval(BInteger a, BInteger b) {
 		PersistentHashSet persistentSet = PersistentHashSet.create();
-		for(BInteger i = a; i.lessEqual(b).booleanValue(); i = i.plus(new BInteger("1"))) {
+		for(BInteger i = a; i.lessEqual(b).booleanValue(); i = i.succ()) {
 			persistentSet = (PersistentHashSet) persistentSet.cons(i);
 		}
 		return new BSet<BInteger>(persistentSet);
@@ -221,11 +221,11 @@ public class BSet<T> implements BObject, Set<T> {
 
 
 	public BInteger card() {
-		return new BInteger(String.valueOf((int) COUNT.invoke(this.set)));
+		return new BInteger((int) COUNT.invoke(this.set));
 	}
 
 	public BInteger _size() {
-		return new BInteger(String.valueOf((int) COUNT.invoke(this.set)));
+		return new BInteger((int) COUNT.invoke(this.set));
 	}
 
 	public BBoolean elementOf(T object) {
@@ -326,7 +326,7 @@ public class BSet<T> implements BObject, Set<T> {
 	}
 
 	public BSet<BRelation<BInteger,T>> permutate() {
-		BSet<BInteger> interval = BSet.interval(new BInteger("1"), this._size());
+		BSet<BInteger> interval = BSet.interval(BInteger.ONE, this._size());
 		BSet<BRelation<BInteger,T>> permutations = BRelation.cartesianProduct(interval, this).pow();
 		BSet<BRelation<BInteger,T>> result = permutations;
 		for(BRelation<BInteger, T> permutation : permutations) {
diff --git a/btypes_primitives/src/main/java/de/hhu/stups/btypes/BInteger.java b/btypes_primitives/src/main/java/de/hhu/stups/btypes/BInteger.java
index ac742abcb7be2d6f5013d017da95ebd3bf9ec2fc..64576cb95e4b53d4cfd70040f31bb2933d51c220 100644
--- a/btypes_primitives/src/main/java/de/hhu/stups/btypes/BInteger.java
+++ b/btypes_primitives/src/main/java/de/hhu/stups/btypes/BInteger.java
@@ -1,56 +1,55 @@
 package de.hhu.stups.btypes;
 
-import java.util.Objects;
+import java.math.BigInteger;
 
-/**
- * Created by fabian on 15.10.18.
- */
-public class BInteger extends java.lang.Number implements Comparable<BInteger>, BObject {
+public final class BInteger extends java.lang.Number implements Comparable<BInteger>, BObject {
 
+    public static final BInteger ZERO = new BInteger(0);
+    public static final BInteger ONE = new BInteger(1);
+    public static final BInteger TWO = new BInteger(2);
+
+    private static final long serialVersionUID = -6484548796859331267L;
+    private final int value;
+
+    public BInteger(int value) {
+        this.value = value;
+    }
+
+    public static BInteger build(int value) {
+        return new BInteger(value);
+    }
 
     @Override
     public boolean equals(Object obj) {
-        if (this == obj)
+        if (this == obj) {
             return true;
-        if (obj == null)
+        } else if (!(obj instanceof BInteger)) {
             return false;
-        if (obj instanceof BInteger) {
-            return this.compareTo((BInteger) obj) == 0;
+        } else {
+            return this.value == ((BInteger) obj).value;
         }
-        return false;
     }
 
-    private static final long serialVersionUID = -6484548796859331267L;
-    private int value;
-
     @Override
     public int hashCode() {
         return Integer.hashCode(value);
     }
 
-    public BInteger(int value) {
-        this.value = value;
-    }
-
-    public static BInteger build(int value) {
-        return new BInteger(value);
-    }
-
+    @Override
     public int compareTo(BInteger o) {
-        return this.value - o.value;
+        return Integer.compare(this.value, o.value);
     }
 
     public BBoolean lessEqual(BInteger o) {
         return new BBoolean(this.value <= o.value);
     }
 
-
     public BBoolean greaterEqual(BInteger o) {
         return new BBoolean(this.value >= o.value);
     }
 
     public java.math.BigInteger asBigInteger() {
-        return new java.math.BigInteger(String.valueOf(value));
+        return BigInteger.valueOf(value);
     }
 
     public BBoolean less(BInteger o) {
@@ -106,18 +105,22 @@ public class BInteger extends java.lang.Number implements Comparable<BInteger>,
     }
 
     public BInteger power(BInteger exp) {
-        if(exp.intValue() == 0) {
-            return new BInteger(1);
+        if (exp.isNotNatural().booleanValue()) {
+            throw new IllegalArgumentException("Exponent must be a natural number");
         }
-        BInteger tmp = power(exp.divide(new BInteger(2)));
-        if(exp.modulo(new BInteger(2)).equal(new BInteger(0)).booleanValue()) {
-            return tmp.multiply(tmp);
-        } else {
-            if(exp.greater(new BInteger(0)).booleanValue()) {
-                return this.multiply(tmp.multiply(tmp));
-            } else {
-                return (tmp.multiply(tmp)).divide(this);
+
+        BInteger result = ONE;
+        while (true) {
+            if (ONE.equals(exp.modulo(TWO))) {
+                result = result.multiply(this);
             }
+
+            exp = exp.divide(TWO);
+            if (ZERO.equals(exp)) {
+                return result;
+            }
+
+            result = result.multiply(result);
         }
     }
 
@@ -184,5 +187,4 @@ public class BInteger extends java.lang.Number implements Comparable<BInteger>,
     public BBoolean isNotNatural1() {
         return isNatural1().not();
     }
-
-}
\ No newline at end of file
+}