From owner-freebsd-numerics@freebsd.org Thu Mar 9 06:59:02 2017 Return-Path: Delivered-To: freebsd-numerics@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id F1D47D04409 for ; Thu, 9 Mar 2017 06:59:02 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from mail105.syd.optusnet.com.au (mail105.syd.optusnet.com.au [211.29.132.249]) by mx1.freebsd.org (Postfix) with ESMTP id BDA561A94 for ; Thu, 9 Mar 2017 06:59:02 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from besplex.bde.org (c122-106-153-191.carlnfd1.nsw.optusnet.com.au [122.106.153.191]) by mail105.syd.optusnet.com.au (Postfix) with ESMTPS id 9578F1044931; Thu, 9 Mar 2017 17:58:53 +1100 (AEDT) Date: Thu, 9 Mar 2017 17:58:52 +1100 (EST) From: Bruce Evans X-X-Sender: bde@besplex.bde.org To: Steve Kargl cc: freebsd-numerics@freebsd.org Subject: Re: Bit twiddling question In-Reply-To: <20170308202417.GA23103@troutmask.apl.washington.edu> Message-ID: <20170309173152.F1269@besplex.bde.org> References: <20170308202417.GA23103@troutmask.apl.washington.edu> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.2 cv=KeqiiUQD c=1 sm=1 tr=0 a=Tj3pCpwHnMupdyZSltBt7Q==:117 a=Tj3pCpwHnMupdyZSltBt7Q==:17 a=kj9zAlcOel0A:10 a=WF-Rw4ERh08rOXangSMA:9 a=CjuIK1q_8ugA:10 X-BeenThere: freebsd-numerics@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Discussions of high quality implementation of libm functions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 09 Mar 2017 06:59:03 -0000 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. > 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. > 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. Bruce