Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 8 Mar 2017 23:52:36 -0800
From:      Steve Kargl <sgk@troutmask.apl.washington.edu>
To:        Bruce Evans <brde@optusnet.com.au>
Cc:        freebsd-numerics@freebsd.org
Subject:   Re: Bit twiddling question
Message-ID:  <20170309075236.GA30199@troutmask.apl.washington.edu>
In-Reply-To: <20170309173152.F1269@besplex.bde.org>
References:  <20170308202417.GA23103@troutmask.apl.washington.edu> <20170309173152.F1269@besplex.bde.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, Mar 09, 2017 at 05:58:52PM +1100, Bruce Evans wrote:
> On Wed, 8 Mar 2017, Steve Kargl wrote:
> 
> > Suppose I have a float 'x' that I know is in the
> > range 1 <= x <= 0x1p23 and I know that 'x' is
> > integral, e.g., x = 12.000.  If I use GET_FLOAT_WORD
> > from math_private.h, then x=12.000 maps to ix=0x41400000.
> > Is there a bit twiddling method that I can apply to ix to
> > unambiguously determine if x is even of odd?
> 
> I don't know of any good method.

Spent a day or so searching; hence, my question.

> > Yes, I know I can do
> >
> > float x;
> > int32_t ix;
> > ix = (int32_t)x;
> >
> > and then test (ix & 1).  But, this does not generalize to
> 
> This isn't bit twiddling, and is also slow.

Yes, I know it isn't bit twiddling, but it achieves want I 
need.  I was hoping that if a bit twiddling algorithm was 
available (and was faster), then I could change my algorithm.

> > the case of long double on a ld128 architecture.  That is,
> > if I have 1 <= x < 1xp112, then I would need to have
> >
> > long double x;
> > int128_t ix;
> > ix = (int128_t)x;
> >
> > and AFAICT sparc64 doesn't have an int128_t.
> 
> If sparc64 has this, it would be even slower.  Sparc64 emulates
> all 128-bit FP.  This makes 128-bit sparc64 ~10-100 times slower
> than 64-bit sparc64 FP, and 100-1000 times slower than modern
> x86 64 and 8-bit FP.  FP to integer conversions tend to be slower
> than pure FP, and are especially tricky for integers with more
> bits than FP mantissas.
> 
> Consider bit twiddling to classifiy oddness of 2.0F (0x40000000 in
> bits) and 3.0F (0x40400000 in bits).  The following method seems
> to be not so bad.  Calculates that the unbiased exponent for 3.0F
> is 1.  This means that the 1's bit is (1 << (23 - 1)) = 0x00400000
> where we see it for 3.0F but not for 2.0F.  All bits to the right
> of this must be 0 for the value to be an integer.  I don't know
> how you classified integers efficiently without already determining
> the position of the "point" and looking at these bits.  There are
> complications for powers of 2 and the normalization bit being implicit.

Thanks.  I'll look into the above to see if I can up with
something that does not require the cast.  

To give a hint at what I have been working on, I have implementations
for sinpif(x), sinpi(x), cospif(x), and cospi(x).  For sinpif(x) and
cospif(x) I have kernels that give correctly rounded results for 
FLT_MIN <= x < 0x1p23 (at least on x86_64).   I also have slightly
faster kernels that give max ULPs of about 0.5008.  For sinpi(x) and
cospi(x), my kernels currently give about 1.25 ULP for the worse case
error if I accumulate the polynomials in double precision.  If I 
accumulate the polynomials in long double precision, then I get 
correctly rounded results.  To complete the set, I was hoping to 
work out ld80 and ld128 versions.  `ld128 is going to be problematic
due to the absense of int128_t.

I'll send you what I have in a few days.

-- 
Steve
20161221 https://www.youtube.com/watch?v=IbCHE-hONow



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20170309075236.GA30199>