diff --git a/quantum/gate/gate.go b/quantum/gate/gate.go
index 2610d96..0dfd15f 100644
--- a/quantum/gate/gate.go
+++ b/quantum/gate/gate.go
@@ -1,10 +1,8 @@
 package gate
 
 import (
-	"fmt"
 	"math"
 	"math/cmplx"
-	"strconv"
 
 	"github.com/itsubaki/q/math/matrix"
 	"github.com/itsubaki/q/math/number"
@@ -329,36 +327,34 @@ func QFT(n int) matrix.Matrix {
 // len(t) must be larger than log2(N).
 func ControlledModExp2(n, a, j, N, c int, t []int) matrix.Matrix {
 	m := I(n)
-	d, _ := m.Dimension()
-
-	r0len, r1len := n-len(t), len(t)
+	r1len := len(t)
 	a2jmodN := number.ModExp2(a, j, N)
 
-	idx := make([]int64, d)
+	d, _ := m.Dimension()
+	idx := make([]int, d)
 	for i := range d {
-		bits := []rune(fmt.Sprintf("%0*b", n, i))
-
-		if bits[c] == '0' {
-			idx[i] = int64(i)
+		if (i>>(n-1-c))&1 == 0 {
+			// control bit is 0, then do nothing
+			idx[i] = i
 			continue
 		}
 
-		k := number.Must(strconv.ParseInt(string(bits[r0len:]), 2, 0))
-		if k > int64(N-1) {
-			idx[i] = int64(i)
+		// r1len bits of i
+		mask := (1 << r1len) - 1
+		k := i & mask
+		if k > N-1 {
+			idx[i] = i
 			continue
 		}
 
-		a2jkmodN := (int64(a2jmodN) * k) % int64(N)
-		a2jkmodNs := []rune(fmt.Sprintf("%0*b", r1len, a2jkmodN))
-		newbits := append(bits[:r0len], []rune(a2jkmodNs)...)
-
-		idx[i] = number.Must(strconv.ParseInt(string(newbits), 2, 0))
+		// r0len bits of i + a2jkmodN bits
+		a2jkmodN := a2jmodN * k % N
+		idx[i] = (i >> r1len << r1len) | a2jkmodN
 	}
 
 	g := make(matrix.Matrix, d)
-	for i, ii := range idx {
-		g[ii] = m[i]
+	for i, j := range idx {
+		g[j] = m[i]
 	}
 
 	return g
diff --git a/quantum/gate/gate_test.go b/quantum/gate/gate_test.go
index baed330..51210f5 100644
--- a/quantum/gate/gate_test.go
+++ b/quantum/gate/gate_test.go
@@ -113,13 +113,13 @@ func ExampleControlledModExp2() {
 			continue
 		}
 
-		for ii, e := range r {
+		for l, e := range r {
 			if e == complex(0, 0) {
 				continue
 			}
 
 			// decimal number representation of a^2^j * k mod N
-			a2jkmodNs := fmt.Sprintf("%0*s", n, strconv.FormatInt(int64(ii), 2)[1:])
+			a2jkmodNs := fmt.Sprintf("%0*s", n, strconv.FormatInt(int64(l), 2)[1:])
 			a2jkmodN := number.Must(strconv.ParseInt(a2jkmodNs, 2, 64))
 			got := (int64(number.ModExp2(a, j, N)) * k) % int64(N)
 
diff --git a/quantum/qubit/qubit.go b/quantum/qubit/qubit.go
index 003f15d..c723b6c 100644
--- a/quantum/qubit/qubit.go
+++ b/quantum/qubit/qubit.go
@@ -156,12 +156,12 @@ func (q *Qubit) Probability() []float64 {
 // Measure returns a measured qubit.
 func (q *Qubit) Measure(index int) *Qubit {
 	n := q.NumberOfBit()
+	mask := 1 << (n - 1 - index)
 
-	zidx, oidx := make([]int, 0), make([]int, 0)
-	zprop := make([]float64, 0)
+	zidx, zprop := make([]int, 0), make([]float64, 0)
+	oidx := make([]int, 0)
 	for i, p := range q.Probability() {
-		bits := []rune(fmt.Sprintf("%0*b", n, i))
-		if bits[index] == '0' {
+		if i&mask == 0 {
 			zidx, zprop = append(zidx, i), append(zprop, p)
 			continue
 		}
@@ -235,10 +235,9 @@ func (q *Qubit) State(index ...[]int) []State {
 			continue
 		}
 
-		bit := fmt.Sprintf("%0*b", n, i)
 		var bin []string
 		for _, idx := range index {
-			bin = append(bin, take(bit, idx))
+			bin = append(bin, take(n, i, idx))
 		}
 
 		state = append(state, NewState(amp, bin...))
@@ -261,10 +260,12 @@ func round(a complex128, eps ...float64) complex128 {
 	return a
 }
 
-func take(binary string, index []int) string {
+func take(n, i int, index []int) string {
+	s := fmt.Sprintf("%0*b", n, i)
+
 	var sb strings.Builder
 	for _, i := range index {
-		sb.WriteString(binary[i : i+1])
+		sb.WriteString(s[i : i+1])
 	}
 
 	return sb.String()