Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-range-ext/mrblib/range.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-range-ext/mrblib/range.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-range-ext/mrblib/range.rb	(revision 331)
@@ -0,0 +1,31 @@
+class Range
+  ##
+  # call-seq:
+  #    rng.first    -> obj
+  #    rng.first(n) -> an_array
+  #
+  # Returns the first object in the range, or an array of the first +n+
+  # elements.
+  #
+  #   (10..20).first     #=> 10
+  #   (10..20).first(3)  #=> [10, 11, 12]
+  #
+  def first(*args)
+    return self.begin if args.empty?
+
+    raise ArgumentError, "wrong number of arguments (given #{args.length}, expected 1)" unless args.length == 1
+    nv = args[0]
+    raise TypeError, "no implicit conversion from nil to integer" if nv.nil?
+    raise TypeError, "no implicit conversion of #{nv.class} into Integer" unless nv.respond_to?(:to_int)
+    n = nv.to_int
+    raise TypeError, "no implicit conversion of #{nv.class} into Integer" unless n.kind_of?(Integer)
+    raise ArgumentError, "negative array size (or size too big)" unless 0 <= n
+    ary = []
+    each do |i|
+      break if n <= 0
+      ary.push(i)
+      n -= 1
+    end
+    ary
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-range-ext/src/range.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/mrbgems/mruby-range-ext/src/range.c	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-range-ext/src/range.c	(revision 331)
@@ -1,5 +1,6 @@
-#include "mruby.h"
-#include "mruby/range.h"
+#include <mruby.h>
+#include <mruby/range.h>
 #include <math.h>
+#include <float.h>
 
 static mrb_bool
@@ -44,5 +45,5 @@
 {
   mrb_value val;
-  struct RRange *r = mrb_range_ptr(range);
+  struct RRange *r = mrb_range_ptr(mrb, range);
   mrb_value beg, end;
 
@@ -68,30 +69,4 @@
 /*
  *  call-seq:
- *     rng.first    -> obj
- *     rng.first(n) -> an_array
- *
- *  Returns the first object in the range, or an array of the first +n+
- *  elements.
- *
- *    (10..20).first     #=> 10
- *    (10..20).first(3)  #=> [10, 11, 12]
- */
-static mrb_value
-mrb_range_first(mrb_state *mrb, mrb_value range)
-{
-  mrb_int num;
-  mrb_value array;
-  struct RRange *r = mrb_range_ptr(range);
-
-  if (mrb_get_args(mrb, "|i", &num) == 0) {
-    return r->edges->beg;
-  }
-
-  array = mrb_funcall(mrb, range, "to_a", 0);
-  return mrb_funcall(mrb, array, "first", 1, mrb_fixnum_value(num));
-}
-
-/*
- *  call-seq:
  *     rng.last    -> obj
  *     rng.last(n) -> an_array
@@ -113,5 +88,5 @@
   mrb_value num;
   mrb_value array;
-  struct RRange *r = mrb_range_ptr(range);
+  struct RRange *r = mrb_range_ptr(mrb, range);
 
   if (mrb_get_args(mrb, "|o", &num) == 0) {
@@ -137,13 +112,15 @@
 mrb_range_size(mrb_state *mrb, mrb_value range)
 {
-  struct RRange *r = mrb_range_ptr(range);
+  struct RRange *r = mrb_range_ptr(mrb, range);
   mrb_value beg, end;
-  double beg_f, end_f;
+  mrb_float beg_f, end_f;
   mrb_bool num_p = TRUE;
+  mrb_bool excl;
 
   beg = r->edges->beg;
   end = r->edges->end;
+  excl = r->excl;
   if (mrb_fixnum_p(beg)) {
-    beg_f = (double)mrb_fixnum(beg);
+    beg_f = (mrb_float)mrb_fixnum(beg);
   }
   else if (mrb_float_p(beg)) {
@@ -154,5 +131,5 @@
   }
   if (mrb_fixnum_p(end)) {
-    end_f = (double)mrb_fixnum(end);
+    end_f = (mrb_float)mrb_fixnum(end);
   }
   else if (mrb_float_p(end)) {
@@ -163,12 +140,22 @@
   }
   if (num_p) {
-    double f;
+    mrb_float n = end_f - beg_f;
+    mrb_float err = (fabs(beg_f) + fabs(end_f) + fabs(end_f-beg_f)) * MRB_FLOAT_EPSILON;
 
-    if (beg_f > end_f) return mrb_fixnum_value(0);
-    f = end_f - beg_f;
-    if (!r->excl) {
-      return mrb_fixnum_value((mrb_int)ceil(f + 1));
+    if (err>0.5) err=0.5;
+    if (excl) {
+      if (n<=0) return mrb_fixnum_value(0);
+      if (n<1)
+        n = 0;
+      else
+        n = floor(n - err);
     }
-    return mrb_fixnum_value((mrb_int)ceil(f));
+    else {
+      if (n<0) return mrb_fixnum_value(0);
+      n = floor(n + err);
+    }
+    if (isinf(n+1))
+      return mrb_float_value(mrb, INFINITY);
+    return mrb_fixnum_value((mrb_int)n+1);
   }
   return mrb_nil_value();
@@ -181,5 +168,4 @@
 
   mrb_define_method(mrb, s, "cover?", mrb_range_cover, MRB_ARGS_REQ(1));
-  mrb_define_method(mrb, s, "first",  mrb_range_first, MRB_ARGS_OPT(1));
   mrb_define_method(mrb, s, "last",   mrb_range_last,  MRB_ARGS_OPT(1));
   mrb_define_method(mrb, s, "size",   mrb_range_size,  MRB_ARGS_NONE());
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-range-ext/test/range.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/mrbgems/mruby-range-ext/test/range.rb	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-range-ext/test/range.rb	(revision 331)
@@ -11,4 +11,5 @@
   assert_equal 10, (10..20).first
   assert_equal [10, 11, 12], (10..20).first(3)
+  assert_equal [0, 1, 2], (0..Float::INFINITY).first(3)
 end
 
@@ -26,4 +27,6 @@
   assert_equal 5, (1...6.0).size
   assert_equal 5, (1.1...6).size
+  assert_equal 15, (1.0..15.9).size
+  assert_equal Float::INFINITY, (0..Float::INFINITY).size
   assert_nil ('a'..'z').size
 end
