summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--configure.in2
-rw-r--r--include/ruby/missing.h4
-rw-r--r--missing/ffs.c47
-rw-r--r--time.c2
5 files changed, 63 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index bdd3a79e46..d927f3688f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Wed May 12 22:22:05 2010 Tanaka Akira <akr@fsij.org>
+
+ * time.c (rb_big_abs_find_minbit): use ffs().
+
+ * configure.in: check ffs().
+
+ * missing/ffs.c: new file.
+
+ * include/ruby/missing.h (ffs): declared.
+
Wed May 12 16:43:12 2010 Nobuyoshi Nakada <nobu@ruby-lang.org>
* numeric.c (flo_to_s): fixed broken output including nuls.
diff --git a/configure.in b/configure.in
index 98633bb526..9717f4731f 100644
--- a/configure.in
+++ b/configure.in
@@ -1117,7 +1117,7 @@ AS_CASE([$rb_cv_broken_glibc_ia64_erfc],[yes],[ac_cv_func_erf=no])
AC_REPLACE_FUNCS(dup2 memmove strerror\
strchr strstr crypt flock\
isnan finite isinf hypot acosh erf tgamma lgamma_r cbrt \
- strlcpy strlcat)
+ strlcpy strlcat ffs)
AC_CACHE_CHECK(for signbit, rb_cv_have_signbit,
[AC_TRY_LINK([
#include <math.h>
diff --git a/include/ruby/missing.h b/include/ruby/missing.h
index e4ac07018f..18dabaa5b3 100644
--- a/include/ruby/missing.h
+++ b/include/ruby/missing.h
@@ -159,6 +159,10 @@ RUBY_EXTERN size_t strlcpy(char *, const char*, size_t);
RUBY_EXTERN size_t strlcat(char *, const char*, size_t);
#endif
+#ifndef HAVE_FFS
+RUBY_EXTERN int ffs(int);
+#endif
+
#if defined(__cplusplus)
#if 0
{ /* satisfy cc-mode */
diff --git a/missing/ffs.c b/missing/ffs.c
new file mode 100644
index 0000000000..9bbb707959
--- /dev/null
+++ b/missing/ffs.c
@@ -0,0 +1,47 @@
+/* ffs.c - find first set bit */
+/* ffs() is defined by POSIX. */
+
+#include "ruby.h"
+
+int ffs(int arg)
+{
+ unsigned int x = (unsigned int)arg;
+ int r = 0;
+
+ if (x == 0)
+ return 0;
+
+#if 32 < SIZEOF_INT * CHAR_BIT
+ if ((x & 0xffffffff) == 0) {
+ x >>= 32;
+ r += 32;
+ }
+#endif
+
+ if ((x & 0xffff) == 0) {
+ x >>= 16;
+ r += 16;
+ }
+
+ if ((x & 0xff) == 0) {
+ x >>= 8;
+ r += 8;
+ }
+
+ if ((x & 0xf) == 0) {
+ x >>= 4;
+ r += 4;
+ }
+
+ if ((x & 0x3) == 0) {
+ x >>= 2;
+ r += 2;
+ }
+
+ if ((x & 0x1) == 0) {
+ x >>= 1;
+ r += 1;
+ }
+
+ return r;
+}
diff --git a/time.c b/time.c
index 1b461bbb34..9355c87ec9 100644
--- a/time.c
+++ b/time.c
@@ -345,7 +345,7 @@ rb_big_abs_find_minbit(VALUE big)
return Qnil;
res = mul(LONG2NUM(i), INT2FIX(SIZEOF_BDIGITS * CHAR_BIT));
d = ds[i];
- res = add(res, LONG2FIX(bdigit_find_maxbit(d & (~d+1))));
+ res = add(res, LONG2FIX(ffs(d)-1));
return res;
}