diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | configure.in | 2 | ||||
-rw-r--r-- | include/ruby/missing.h | 4 | ||||
-rw-r--r-- | missing/ffs.c | 47 | ||||
-rw-r--r-- | time.c | 2 |
5 files changed, 63 insertions, 2 deletions
@@ -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; +} @@ -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; } |