diff --git a/lib/ipaddr.rb b/lib/ipaddr.rb
index 7a5cf94..808ccd8 100644
--- a/lib/ipaddr.rb
+++ b/lib/ipaddr.rb
@@ -176,9 +176,7 @@ def mask(prefixlen)
   def include?(other)
     other = coerce_other(other)
     return false unless other.family == family
-    range = to_range
-    other = other.to_range
-    range.begin <= other.begin && range.end >= other.end
+    begin_addr <= other.begin_addr && end_addr >= other.end_addr
   end
   alias === include?
 
@@ -400,17 +398,6 @@ def hash
 
   # Creates a Range object for the network address.
   def to_range
-    begin_addr = (@addr & @mask_addr)
-
-    case @family
-    when Socket::AF_INET
-      end_addr = (@addr | (IN4MASK ^ @mask_addr))
-    when Socket::AF_INET6
-      end_addr = (@addr | (IN6MASK ^ @mask_addr))
-    else
-      raise AddressFamilyError, "unsupported address family"
-    end
-
     self.class.new(begin_addr, @family)..self.class.new(end_addr, @family)
   end
 
@@ -491,6 +478,21 @@ def zone_id=(zid)
 
   protected
 
+  def begin_addr
+    @addr & @mask_addr
+  end
+
+  def end_addr
+    case @family
+    when Socket::AF_INET
+      @addr | (IN4MASK ^ @mask_addr)
+    when Socket::AF_INET6
+      @addr | (IN6MASK ^ @mask_addr)
+    else
+      raise AddressFamilyError, "unsupported address family"
+    end
+  end
+
   # Set +@addr+, the internal stored ip address, to given +addr+. The
   # parameter +addr+ is validated using the first +family+ member,
   # which is +Socket::AF_INET+ or +Socket::AF_INET6+.