This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Bug in std::floor?


On 2017-11-10 05:58 +0100, Marc Glisse wrote:
> On Fri, 10 Nov 2017, Nil Geisweiller wrote:
> > Indeed! I would really like to have a look at the floor implementation, but 
> > it has proven difficult. It calls __builtin_floor, that is no where to be 
> > found. It seems to be implemented in gcc/builtins.c but it's too obfuscated 
> > for me to understand.
> 
> Look at the generated asm? Here, it is a single instruction: roundsd.
> For constant folding, you would want to look at real.c.
> builtins.c essentially delegates the work to each target to specify how 
> floor should be expanded, and generates a call to the system's C library 
> when that's not specified.
> 
I found a machine independent version in glibc and slightly modified it
(expanding some macros and removing optimization barriers).  It's attached.
-- 
Xi Ruoyao <ryxi@stu.xidian.edu.cn>
School of Aerospace Science and Technology, Xidian University
/* Based on glibc sysdeps/ieee754/dbl-64/s_floor.h.
   Copyright (C) 2011-2015 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by Ulrich Drepper <drepper@cygnus.com>, 2011.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */

/* Based on a version which carries the following copyright:  */

/*
 * ====================================================
 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
 *
 * Developed at SunPro, a Sun Microsystems, Inc. business.
 * Permission to use, copy, modify, and distribute this
 * software is freely granted, provided that this notice
 * is preserved.
 * ====================================================
 */

#include <stdint.h>
#include <stdio.h>

/*
 * floor(x)
 * Return x rounded toward -inf to integral value
 * Method:
 *        Bit twiddling.
 * Exception:
 *        Inexact flag raised if x not equal to floor(x).
 */

static const double huge = 1.0e300;

union U
{
	double value;
	uint64_t word;
};

double
impl_floor (double x)
{
	int64_t i0, j0;
	union U u;

	u.value = x;
	i0 = u.word;
	j0 = ((i0>>52)&0x7ff)-0x3ff;
	if(j0<52) {
		if(j0<0) {        /* raise inexact if x != 0 */
			if(i0>=0) {i0=0;}
			else if((i0&0x7fffffffffffffffl)!=0)
			  { i0=0xbff0000000000000l;}
		} else {
			uint64_t i = (0x000fffffffffffffl)>>j0;
			if((i0&i)==0) return x; /* x is integral */
			if(i0<0) i0 += (0x0010000000000000l)>>j0;
			i0 &= (~i);
		}
		u.word = i0;
		x = u.value;
	} else if (j0==0x400)
		return x+x;        /* inf or NaN */
	return x;
}

int main()
{
    printf("%.10f %.10f\n", impl_floor(4.6*100), impl_floor(1.7*100));
    return 0;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]