From a00247f57a1b263d6eace43f36547766566c1de1 Mon Sep 17 00:00:00 2001 From: akr Date: Wed, 12 May 2010 13:23:20 +0000 Subject: [PATCH] * time.c (rb_big_abs_find_minbit): use ffs(). * configure.in: check ffs(). * missing/ffs.c: new file. * include/ruby/missing.h (ffs): declared. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@27759 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 10 +++++++++ configure.in | 2 +- include/ruby/missing.h | 4 ++++ missing/ffs.c | 47 ++++++++++++++++++++++++++++++++++++++++++ time.c | 2 +- 5 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 missing/ffs.c 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 + + * 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 * 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 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; }