openlibm-0.5.0/000077500000000000000000000000001266752446200133375ustar00rootroot00000000000000openlibm-0.5.0/.gitignore000066400000000000000000000000461266752446200153270ustar00rootroot00000000000000*.o *~ *.a *.dll* *.so* *.dylib* *.pc openlibm-0.5.0/.mailmap000066400000000000000000000056451266752446200147720ustar00rootroot00000000000000JuliaLang JuliaLang Jeff Bezanson Jeff Bezanson Jeff Bezanson Jeff Bezanson Jeff Bezanson Jeff Bezanson Jeff Bezanson Jeff Bezanson Jeff Bezanson Jeff Bezanson Jeff Bezanson Jeff Bezanson Jeff Bezanson Stefan Karpinski Stefan Karpinski Stefan Karpinski Viral B. Shah Viral B. Shah Viral B. Shah Viral B. Shah George Xing George Xing Stephan Boyer Stephan Boyer Stephan Boyer Stephan Boyer Giuseppe Zingales Giuseppe Zingales Jameson Nash Jameson Nash Jameson Nash Alan Edelman PlayMyCode PlayMyCode Corey M. Hoffstein Corey M. Hoffstein Stefan Kroboth Tim Holy Tim Holy Patrick O'Leary Ivan Mantova Keno Fischer Keno Fischer Keno Fischer openlibm-0.5.0/.travis.sh000077500000000000000000000012301266752446200152600ustar00rootroot00000000000000#!/bin/sh set -eux case "$TARGET" in host) uname -a export LOADER= make ;; arm32) sudo bash -c 'echo >> /etc/apt/sources.list "deb http://archive.ubuntu.com/ubuntu/ trusty main restricted universe"' sudo apt-get update sudo apt-get -y install gcc-4.7-arm-linux-gnueabihf qemu binfmt-support make CC="arm-linux-gnueabihf-gcc-4.7" export LD_LIBRARY_PATH=/usr/arm-linux-gnueabihf/lib #export LOADER=/usr/arm-linux-gnueabihf/lib/ld-linux-armhf.so.3 export LOADER="echo TESTS DISABLED ON ARM" ;; *) echo 'Unknown TARGET!' exit 1 ;; esac $LOADER make check make clean && git status --ignored --porcelain && test -z "$(git status --ignored --porcelain)" openlibm-0.5.0/.travis.yml000066400000000000000000000002761266752446200154550ustar00rootroot00000000000000language: c script: ./.travis.sh os: - linux env: - TARGET=host - TARGET=arm32 matrix: exclude: - os: osx env: TARGET=arm32 notifications: email: false openlibm-0.5.0/LICENSE.md000066400000000000000000000133411266752446200147450ustar00rootroot00000000000000## OpenLibm OpenLibm contains code that is covered by various licenses. The OpenLibm code derives from the FreeBSD msun and OpenBSD libm implementations, which in turn derives from FDLIBM 5.3. As a result, it has a number of fixes and updates that have accumulated over the years in msun, and also optimized assembly versions of many functions. These improvements are provided under the BSD and ISC licenses. The msun library also includes work placed under the public domain, which is noted in the individual files. Further work on making a standalone OpenLibm library from msun, as part of the Julia project is covered under the MIT license. The test files, test-double.c and test-float.c are under the LGPL. ## Parts copyrighted by the Julia project (MIT License) > Copyright (c) 2011-14 The Julia Project. > https://github.com/JuliaLang/openlibm/graphs/contributors > > Permission is hereby granted, free of charge, to any person obtaining > a copy of this software and associated documentation files (the > "Software"), to deal in the Software without restriction, including > without limitation the rights to use, copy, modify, merge, publish, > distribute, sublicense, and/or sell copies of the Software, and to > permit persons to whom the Software is furnished to do so, subject to > the following conditions: > > The above copyright notice and this permission notice shall be > included in all copies or substantial portions of the Software. > > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND > NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE > LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION > OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION > WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ## Parts copyrighted by Stephen L. Moshier (ISC License) > Copyright (c) 2008 Stephen L. Moshier > > Permission to use, copy, modify, and distribute this software for any > purpose with or without fee is hereby granted, provided that the above > copyright notice and this permission notice appear in all copies. > > THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES > WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR > ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES > WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN > ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF > OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ## FREEBSD MSUN (FreeBSD/2-clause BSD/Simplified BSD License) > Copyright 1992-2011 The FreeBSD Project. All rights reserved. > > Redistribution and use in source and binary forms, with or without > modification, are permitted provided that the following conditions are > met: > > 1. Redistributions of source code must retain the above copyright > notice, this list of conditions and the following disclaimer. > > 2. Redistributions in binary form must reproduce the above copyright > notice, this list of conditions and the following disclaimer in the > documentation and/or other materials provided with the distribution. > THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT ``AS IS'' AND ANY > EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD PROJECT OR > CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, > EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, > PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR > PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF > LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING > NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS > SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > > The views and conclusions contained in the software and documentation > are those of the authors and should not be interpreted as representing > official policies, either expressed or implied, of the FreeBSD > Project. ## FDLIBM > 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. ## Tests > Copyright (C) 1997, 1999 Free Software Foundation, Inc. > This file is part of the GNU C Library. > Contributed by Andreas Jaeger , 1997. > > 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, write to the Free > Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA > 02111-1307 USA. openlibm-0.5.0/Make.inc000066400000000000000000000066651266752446200147240ustar00rootroot00000000000000# -*- mode: makefile-gmake -*- OS := $(shell uname) # Do not forget to bump SOMINOR when changing VERSION, # and SOMAJOR when breaking ABI in a backward-incompatible way VERSION = 0.5-dev SOMAJOR = 2 SOMINOR = 1 DESTDIR = prefix = /usr/local bindir = $(prefix)/bin libdir = $(prefix)/lib includedir = $(prefix)/include ifeq ($(OS), FreeBSD) pkgconfigdir = $(prefix)/libdata/pkgconfig else pkgconfigdir = $(libdir)/pkgconfig endif USEGCC = 1 USECLANG = 0 ifeq ($(OS), Darwin) USEGCC = 0 USECLANG = 1 endif ifeq ($(OS), FreeBSD) USEGCC = 0 USECLANG = 1 endif AR = ar ifeq ($(USECLANG),1) USEGCC = 0 CC = clang CFLAGS_add += -fno-builtin endif ifeq ($(USEGCC),1) CC = gcc CFLAGS_add += -fno-gnu89-inline -fno-builtin endif ARCH ?= $(shell $(CC) -dumpmachine | sed "s/\([^-]*\).*$$/\1/") ARCH_ORIGIN := $(origin ARCH) ifeq ($(ARCH),mingw32) $(error "the mingw32 compiler you are using fails the openblas testsuite. please see the Julia README.windows.md document for a replacement") endif CFLAGS_add += -std=c99 -Wall -I$(OPENLIBM_HOME) -I$(OPENLIBM_HOME)/include -I$(OPENLIBM_HOME)/ld80 -I$(OPENLIBM_HOME)/$(ARCH) -I$(OPENLIBM_HOME)/src -DASSEMBLER -D__BSD_VISIBLE -Wno-implicit-function-declaration default: all # *int / *intf need to be built with -O0 src/%int.c.o: src/%int.c $(CC) $(CPPFLAGS) -O0 $(CFLAGS_add) -c $< -o $@ src/%intf.c.o: src/%intf.c $(CC) $(CPPFLAGS) -O0 $(CFLAGS_add) -c $< -o $@ %.c.o: %.c $(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_add) -c $< -o $@ %.S.o: %.S $(CC) $(CPPFLAGS) $(SFLAGS) $(SFLAGS_add) $(filter -m% -B% -I% -D%,$(CFLAGS_add)) -c $< -o $@ # OS-specific stuff REAL_ARCH := $(ARCH) ifeq ($(findstring arm,$(ARCH)),arm) override ARCH := arm endif ifeq ($(findstring powerpc,$(ARCH)),powerpc) override ARCH := powerpc endif ifeq ($(findstring ppc,$(ARCH)),ppc) override ARCH := powerpc endif ifeq ($(ARCH),i386) override ARCH := i387 endif ifeq ($(ARCH),i486) override ARCH := i387 endif ifeq ($(ARCH),i586) override ARCH := i387 endif ifeq ($(ARCH),i686) override ARCH := i387 endif ifeq ($(ARCH),x86_64) override ARCH := amd64 endif # The optimization flag may be overriden with the environment variable CFLAGS. CFLAGS ?= -O2 ifneq (,$(findstring MINGW,$(OS))) override OS=WINNT endif #keep these if statements separate ifeq ($(OS), WINNT) SHLIB_EXT = dll SONAME_FLAG = -soname override CFLAGS_add += -nodefaultlibs shlibdir = $(bindir) else ifeq ($(OS), Darwin) SHLIB_EXT = dylib SONAME_FLAG = -install_name else SHLIB_EXT = so SONAME_FLAG = -soname endif override CFLAGS_add += -fPIC shlibdir = $(libdir) endif # The target specific FLAGS_add ifeq ($(ARCH_ORIGIN),file) CFLAGS_add_TARGET_$(ARCH) := SFLAGS_add_TARGET_$(ARCH) := LDFLAGS_add_TARGET_$(ARCH) := else ifeq ($(ARCH),i387) CFLAGS_add_TARGET_$(ARCH) := -m32 -march=$(REAL_ARCH) SFLAGS_add_TARGET_$(ARCH) := -m32 -march=$(REAL_ARCH) LDFLAGS_add_TARGET_$(ARCH) := -m32 -march=$(REAL_ARCH) endif CFLAGS_add_TARGET_x86_64 := -m64 SFLAGS_add_TARGET_x86_64 := -m64 LDFLAGS_add_TARGET_x86_64 := -m64 # Arm ifeq ($(ARCH),arm) ifneq ($(REAL_ARCH),arm) CFLAGS_add_TARGET_$(ARCH) := -march=$(REAL_ARCH) SFLAGS_add_TARGET_$(ARCH) := -march=$(REAL_ARCH) LDFLAGS_add_TARGET_$(ARCH) := -march=$(REAL_ARCH) else $(error No known generic arm cflags. Please specify arch type) endif endif endif # Actually finish setting the FLAGS_add CFLAGS_add += $(CFLAGS_add_TARGET_$(ARCH)) LDFLAGS_add += $(LDFLAGS_add_TARGET_$(ARCH)) SFLAGS_add += $(SFLAGS_add_TARGET_$(ARCH)) openlibm-0.5.0/Makefile000066400000000000000000000042741266752446200150060ustar00rootroot00000000000000OPENLIBM_HOME=$(abspath .) include ./Make.inc SUBDIRS = src $(ARCH) bsdsrc ifneq ($(ARCH), arm) ifneq ($(ARCH), powerpc) SUBDIRS += ld80 endif endif define INC_template TEST=test override CUR_SRCS = $(1)_SRCS include $(1)/Make.files SRCS += $$(addprefix $(1)/,$$($(1)_SRCS)) endef DIR=test $(foreach dir,$(SUBDIRS),$(eval $(call INC_template,$(dir)))) DUPLICATE_NAMES = $(filter $(patsubst %.S,%,$($(ARCH)_SRCS)),$(patsubst %.c,%,$(src_SRCS))) DUPLICATE_SRCS = $(addsuffix .c,$(DUPLICATE_NAMES)) OBJS = $(patsubst %.f,%.f.o,\ $(patsubst %.S,%.S.o,\ $(patsubst %.c,%.c.o,$(filter-out $(addprefix src/,$(DUPLICATE_SRCS)),$(SRCS))))) .PHONY: all check test clean distclean install all: libopenlibm.a libopenlibm.$(SHLIB_EXT) check test: test/test-double test/test-float test/test-double test/test-float libopenlibm.a: $(OBJS) $(AR) -rcs libopenlibm.a $(OBJS) libopenlibm.$(SHLIB_EXT): $(OBJS) ifeq ($(OS),WINNT) $(CC) -shared $(OBJS) $(LDFLAGS) $(LDFLAGS_add) -Wl,$(SONAME_FLAG),libopenlibm.$(SHLIB_EXT) -o libopenlibm.$(SHLIB_EXT) else $(CC) -shared $(OBJS) $(LDFLAGS) $(LDFLAGS_add) -Wl,$(SONAME_FLAG),libopenlibm.$(SHLIB_EXT).$(SOMAJOR) -o libopenlibm.$(SHLIB_EXT).$(SOMAJOR).$(SOMINOR) ln -sf libopenlibm.$(SHLIB_EXT).$(SOMAJOR).$(SOMINOR) libopenlibm.$(SHLIB_EXT).$(SOMAJOR) ln -sf libopenlibm.$(SHLIB_EXT).$(SOMAJOR).$(SOMINOR) libopenlibm.$(SHLIB_EXT) endif test/test-double: libopenlibm.$(SHLIB_EXT) $(MAKE) -C test test-double test/test-float: libopenlibm.$(SHLIB_EXT) $(MAKE) -C test test-float clean: rm -f amd64/*.o arm/*.o bsdsrc/*.o i387/*.o ld128/*.o ld80/*.o src/*.o rm -f libopenlibm.a libopenlibm.$(SHLIB_EXT)* $(MAKE) -C test clean openlibm.pc: openlibm.pc.in Make.inc Makefile echo "prefix=${prefix}" > openlibm.pc echo "version=${VERSION}" >> openlibm.pc cat openlibm.pc.in >> openlibm.pc install: all openlibm.pc mkdir -p $(DESTDIR)$(shlibdir) mkdir -p $(DESTDIR)$(pkgconfigdir) mkdir -p $(DESTDIR)$(includedir)/openlibm cp -f -a libopenlibm.$(SHLIB_EXT)* $(DESTDIR)$(shlibdir)/ cp -f -a libopenlibm.a $(DESTDIR)$(libdir)/ cp -f -a include/*.h $(DESTDIR)$(includedir)/openlibm cp -f -a src/*.h $(DESTDIR)$(includedir)/openlibm cp -f -a openlibm.pc $(DESTDIR)$(pkgconfigdir)/ openlibm-0.5.0/README.md000066400000000000000000000032271266752446200146220ustar00rootroot00000000000000# OpenLibm [![Build Status](https://travis-ci.org/JuliaLang/openlibm.svg?branch=master)](https://travis-ci.org/JuliaLang/openlibm) [OpenLibm](http://www.openlibm.org) is an effort to have a high quality, portable, standalone C mathematical library ([`libm`](http://en.wikipedia.org/wiki/libm)). It can be used standalone in applications and programming language implementations. The project was born out of a need to have a good `libm` for the [Julia programming langage](http://www.julialang.org) that worked consistently across compilers and operating systems, and in 32-bit and 64-bit environments. ## Platform support OpenLibm builds on Linux, Mac OS X, Windows, FreeBSD, and OpenBSD. It builds with both GCC and clang. Although largely tested and widely used on x86 architectures, openlibm also supports ARM and powerPC. ## Build instructions 1. Use `make` to build OpenLibm. 2. Use `make USEGCC=1` to build with GCC. This is the default on Linux and Windows. 3. Use `make USECLANG=1` to build with clang. This is the default on OS X and FreeBSD. 4. Architectures are auto-detected. Use `make ARCH=i386` to force a build for i386. Other supported architectures are i486, i586, and i686. GCC 4.8 is the minimum requirement for correct codegen on older 32-bit architectures. 5. On OpenBSD, you need to install GNU Make (port name: `gmake`) and a recent version of `gcc` (tested: 4.9.2), as the default version provided by OpenBSD is too old (4.2.1). If you use OpenBSD's port system for this (port name: `gcc`), run `make CC=egcc` to force Make to use the newer `gcc`. ## Acknowledgements PowerPC support for openlibm was graciously sponsored by IBM. openlibm-0.5.0/amd64/000077500000000000000000000000001266752446200142525ustar00rootroot00000000000000openlibm-0.5.0/amd64/Make.files000066400000000000000000000004361266752446200161560ustar00rootroot00000000000000$(CUR_SRCS) = fenv.c e_remainder.S e_remainderf.S e_remainderl.S \ e_sqrt.S e_sqrtf.S e_sqrtl.S \ s_llrint.S s_llrintf.S s_llrintl.S \ s_logbl.S s_lrint.S s_lrintf.S s_lrintl.S \ s_remquo.S s_remquof.S s_remquol.S \ s_rintl.S s_scalbn.S s_scalbnf.S s_scalbnl.S openlibm-0.5.0/amd64/bsd_asm.h000066400000000000000000000070771266752446200160460ustar00rootroot00000000000000/*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * William Jolitz. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * from: @(#)DEFS.h 5.1 (Berkeley) 4/23/90 * $FreeBSD: src/sys/amd64/include/asm.h,v 1.18 2007/08/22 04:26:07 jkoshy Exp $ */ #ifndef _BSD_ASM_H_ #define _BSD_ASM_H_ #ifdef __APPLE__ #include "../i387/osx_asm.h" #define CNAME(x) EXT(x) #else #include "bsd_cdefs.h" #ifdef PIC #define PIC_PLT(x) x@PLT #define PIC_GOT(x) x@GOTPCREL(%rip) #else #define PIC_PLT(x) x #define PIC_GOT(x) x #endif /* * CNAME and HIDENAME manage the relationship between symbol names in C * and the equivalent assembly language names. CNAME is given a name as * it would be used in a C program. It expands to the equivalent assembly * language name. HIDENAME is given an assembly-language name, and expands * to a possibly-modified form that will be invisible to C programs. */ #define CNAME(csym) csym #define HIDENAME(asmsym) .asmsym #define _START_ENTRY .p2align 4,0x90 #if defined(__ELF__) #define _ENTRY(x) .text; _START_ENTRY; \ .globl CNAME(x); .type CNAME(x),@function; CNAME(x): #define END(x) .size x, . - x #elif defined(_WIN32) #ifndef _MSC_VER #define END(x) .end #define _START_ENTRY_WIN .text; _START_ENTRY #else #define END(x) end #define _START_ENTRY_WIN .code; _START_ENTRY #endif #define _ENTRY(x) _START_ENTRY_WIN; \ .globl CNAME(x); .section .drectve; .ascii " -export:" #x; \ .section .text; .def CNAME(x); .scl 2; .type 32; .endef; CNAME(x): #endif #ifdef PROF #define ALTENTRY(x) _ENTRY(x); \ pushq %rbp; movq %rsp,%rbp; \ call PIC_PLT(HIDENAME(mcount)); \ popq %rbp; \ jmp 9f #define ENTRY(x) _ENTRY(x); \ pushq %rbp; movq %rsp,%rbp; \ call PIC_PLT(HIDENAME(mcount)); \ popq %rbp; \ 9: #else #define ALTENTRY(x) _ENTRY(x) #define ENTRY(x) _ENTRY(x) #endif #define RCSID(x) .text; .asciz x #undef __FBSDID #if !defined(lint) && !defined(STRIP_FBSDID) #define __FBSDID(s) .ident s #else #define __FBSDID(s) /* nothing */ #endif /* not lint and not STRIP_FBSDID */ #endif #endif /* !_BSD_ASM_H_ */ openlibm-0.5.0/amd64/bsd_fpu.h000066400000000000000000000154151266752446200160530ustar00rootroot00000000000000/*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * William Jolitz. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * from: @(#)npx.h 5.3 (Berkeley) 1/18/91 * $FreeBSD: src/sys/x86/include/fpu.h,v 1.1 2012/03/16 20:24:30 tijl Exp $ */ /* * Floating Point Data Structures and Constants * W. Jolitz 1/90 */ #ifndef _BSD_FPU_H_ #define _BSD_FPU_H_ #include "types-compat.h" /* Environment information of floating point unit. */ struct env87 { int32_t en_cw; /* control word (16bits) */ int32_t en_sw; /* status word (16bits) */ int32_t en_tw; /* tag word (16bits) */ int32_t en_fip; /* fp instruction pointer */ uint16_t en_fcs; /* fp code segment selector */ uint16_t en_opcode; /* opcode last executed (11 bits) */ int32_t en_foo; /* fp operand offset */ int32_t en_fos; /* fp operand segment selector */ }; /* Contents of each x87 floating point accumulator. */ struct fpacc87 { uint8_t fp_bytes[10]; }; /* Floating point context. (i386 fnsave/frstor) */ struct save87 { struct env87 sv_env; /* floating point control/status */ struct fpacc87 sv_ac[8]; /* accumulator contents, 0-7 */ uint8_t sv_pad0[4]; /* saved status word (now unused) */ /* * Bogus padding for emulators. Emulators should use their own * struct and arrange to store into this struct (ending here) * before it is inspected for ptracing or for core dumps. Some * emulators overwrite the whole struct. We have no good way of * knowing how much padding to leave. Leave just enough for the * GPL emulator's i387_union (176 bytes total). */ uint8_t sv_pad[64]; /* padding; used by emulators */ }; /* Contents of each SSE extended accumulator. */ struct xmmacc { uint8_t xmm_bytes[16]; }; /* Contents of the upper 16 bytes of each AVX extended accumulator. */ struct ymmacc { uint8_t ymm_bytes[16]; }; /* Rename structs below depending on machine architecture. */ #ifdef __i386__ #define __envxmm32 envxmm #else #define __envxmm32 envxmm32 #define __envxmm64 envxmm #endif struct __envxmm32 { uint16_t en_cw; /* control word (16bits) */ uint16_t en_sw; /* status word (16bits) */ uint16_t en_tw; /* tag word (16bits) */ uint16_t en_opcode; /* opcode last executed (11 bits) */ uint32_t en_fip; /* fp instruction pointer */ uint16_t en_fcs; /* fp code segment selector */ uint16_t en_pad0; /* padding */ uint32_t en_foo; /* fp operand offset */ uint16_t en_fos; /* fp operand segment selector */ uint16_t en_pad1; /* padding */ uint32_t en_mxcsr; /* SSE control/status register */ uint32_t en_mxcsr_mask; /* valid bits in mxcsr */ }; struct __envxmm64 { uint16_t en_cw; /* control word (16bits) */ uint16_t en_sw; /* status word (16bits) */ uint8_t en_tw; /* tag word (8bits) */ uint8_t en_zero; uint16_t en_opcode; /* opcode last executed (11 bits ) */ uint64_t en_rip; /* fp instruction pointer */ uint64_t en_rdp; /* fp operand pointer */ uint32_t en_mxcsr; /* SSE control/status register */ uint32_t en_mxcsr_mask; /* valid bits in mxcsr */ }; /* Floating point context. (i386 fxsave/fxrstor) */ struct savexmm { struct __envxmm32 sv_env; struct { struct fpacc87 fp_acc; uint8_t fp_pad[6]; /* padding */ } sv_fp[8]; struct xmmacc sv_xmm[8]; uint8_t sv_pad[224]; } __attribute__ ((aligned(16))); #ifdef __i386__ union savefpu { struct save87 sv_87; struct savexmm sv_xmm; }; #else /* Floating point context. (amd64 fxsave/fxrstor) */ struct savefpu { struct __envxmm64 sv_env; struct { struct fpacc87 fp_acc; uint8_t fp_pad[6]; /* padding */ } sv_fp[8]; struct xmmacc sv_xmm[16]; uint8_t sv_pad[96]; } __attribute__ ((aligned(16))); #endif struct xstate_hdr { uint64_t xstate_bv; uint8_t xstate_rsrv0[16]; uint8_t xstate_rsrv[40]; }; struct savexmm_xstate { struct xstate_hdr sx_hd; struct ymmacc sx_ymm[16]; }; struct savexmm_ymm { struct __envxmm32 sv_env; struct { struct fpacc87 fp_acc; int8_t fp_pad[6]; /* padding */ } sv_fp[8]; struct xmmacc sv_xmm[16]; uint8_t sv_pad[96]; struct savexmm_xstate sv_xstate; } __attribute__ ((aligned(16))); struct savefpu_xstate { struct xstate_hdr sx_hd; struct ymmacc sx_ymm[16]; }; struct savefpu_ymm { struct __envxmm64 sv_env; struct { struct fpacc87 fp_acc; int8_t fp_pad[6]; /* padding */ } sv_fp[8]; struct xmmacc sv_xmm[16]; uint8_t sv_pad[96]; struct savefpu_xstate sv_xstate; } __attribute__ ((aligned(64))); #undef __envxmm32 #undef __envxmm64 /* * The hardware default control word for i387's and later coprocessors is * 0x37F, giving: * * round to nearest * 64-bit precision * all exceptions masked. * * FreeBSD/i386 uses 53 bit precision for things like fadd/fsub/fsqrt etc * because of the difference between memory and fpu register stack arguments. * If its using an intermediate fpu register, it has 80/64 bits to work * with. If it uses memory, it has 64/53 bits to work with. However, * gcc is aware of this and goes to a fair bit of trouble to make the * best use of it. * * This is mostly academic for AMD64, because the ABI prefers the use * SSE2 based math. For FreeBSD/amd64, we go with the default settings. */ #define __INITIAL_FPUCW__ 0x037F #define __INITIAL_FPUCW_I386__ 0x127F #define __INITIAL_NPXCW__ __INITIAL_FPUCW_I386__ #define __INITIAL_MXCSR__ 0x1F80 #define __INITIAL_MXCSR_MASK__ 0xFFBF #endif /* !_BSD_FPU_H_ */ openlibm-0.5.0/amd64/bsd_ieeefp.h000066400000000000000000000174641266752446200165240ustar00rootroot00000000000000/*- * Copyright (c) 2003 Peter Wemm. * Copyright (c) 1990 Andrew Moore, Talke Studio * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * from: @(#) ieeefp.h 1.0 (Berkeley) 9/23/93 * $FreeBSD: src/sys/amd64/include/ieeefp.h,v 1.14 2005/04/12 23:12:00 jhb Exp $ */ /* * IEEE floating point type and constant definitions. */ #ifndef _BSD_IEEEFP_H_ #define _BSD_IEEEFP_H_ /* * FP rounding modes */ typedef enum { FP_RN=0, /* round to nearest */ FP_RM, /* round down to minus infinity */ FP_RP, /* round up to plus infinity */ FP_RZ /* truncate */ } fp_rnd_t; /* * FP precision modes */ typedef enum { FP_PS=0, /* 24 bit (single-precision) */ FP_PRS, /* reserved */ FP_PD, /* 53 bit (double-precision) */ FP_PE /* 64 bit (extended-precision) */ } fp_prec_t; #define fp_except_t int /* * FP exception masks */ #define FP_X_INV 0x01 /* invalid operation */ #define FP_X_DNML 0x02 /* denormal */ #define FP_X_DZ 0x04 /* zero divide */ #define FP_X_OFL 0x08 /* overflow */ #define FP_X_UFL 0x10 /* underflow */ #define FP_X_IMP 0x20 /* (im)precision */ #define FP_X_STK 0x40 /* stack fault */ /* * FP registers */ #define FP_MSKS_REG 0 /* exception masks */ #define FP_PRC_REG 0 /* precision */ #define FP_RND_REG 0 /* direction */ #define FP_STKY_REG 1 /* sticky flags */ /* * FP register bit field masks */ #define FP_MSKS_FLD 0x3f /* exception masks field */ #define FP_PRC_FLD 0x300 /* precision control field */ #define FP_RND_FLD 0xc00 /* round control field */ #define FP_STKY_FLD 0x3f /* sticky flags field */ /* * SSE mxcsr register bit field masks */ #define SSE_STKY_FLD 0x3f /* exception flags */ #define SSE_DAZ_FLD 0x40 /* Denormals are zero */ #define SSE_MSKS_FLD 0x1f80 /* exception masks field */ #define SSE_RND_FLD 0x6000 /* rounding control */ #define SSE_FZ_FLD 0x8000 /* flush to zero on underflow */ /* * FP register bit field offsets */ #define FP_MSKS_OFF 0 /* exception masks offset */ #define FP_PRC_OFF 8 /* precision control offset */ #define FP_RND_OFF 10 /* round control offset */ #define FP_STKY_OFF 0 /* sticky flags offset */ /* * SSE mxcsr register bit field offsets */ #define SSE_STKY_OFF 0 /* exception flags offset */ #define SSE_DAZ_OFF 6 /* DAZ exception mask offset */ #define SSE_MSKS_OFF 7 /* other exception masks offset */ #define SSE_RND_OFF 13 /* rounding control offset */ #define SSE_FZ_OFF 15 /* flush to zero offset */ #if (defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE__)) || defined(_WIN32) \ && !defined(__cplusplus) #define __fldenv(addr) __asm __volatile("fldenv %0" : : "m" (*(addr))) #define __fnstenv(addr) __asm __volatile("fnstenv %0" : "=m" (*(addr))) #define __fldcw(addr) __asm __volatile("fldcw %0" : : "m" (*(addr))) #define __fnstcw(addr) __asm __volatile("fnstcw %0" : "=m" (*(addr))) #define __fnstsw(addr) __asm __volatile("fnstsw %0" : "=m" (*(addr))) #define __ldmxcsr(addr) __asm __volatile("ldmxcsr %0" : : "m" (*(addr))) #define __stmxcsr(addr) __asm __volatile("stmxcsr %0" : "=m" (*(addr))) /* * General notes about conflicting SSE vs FP status bits. * This code assumes that software will not fiddle with the control * bits of the SSE and x87 in such a way to get them out of sync and * still expect this to work. Break this at your peril. * Because I based this on the i386 port, the x87 state is used for * the fpget*() functions, and is shadowed into the SSE state for * the fpset*() functions. For dual source fpget*() functions, I * merge the two together. I think. */ /* Set rounding control */ static __inline__ fp_rnd_t __fpgetround(void) { unsigned short _cw; __fnstcw(&_cw); return ((_cw & FP_RND_FLD) >> FP_RND_OFF); } static __inline__ fp_rnd_t __fpsetround(fp_rnd_t _m) { unsigned short _cw; unsigned int _mxcsr; fp_rnd_t _p; __fnstcw(&_cw); _p = (_cw & FP_RND_FLD) >> FP_RND_OFF; _cw &= ~FP_RND_FLD; _cw |= (_m << FP_RND_OFF) & FP_RND_FLD; __fldcw(&_cw); __stmxcsr(&_mxcsr); _mxcsr &= ~SSE_RND_FLD; _mxcsr |= (_m << SSE_RND_OFF) & SSE_RND_FLD; __ldmxcsr(&_mxcsr); return (_p); } /* * Set precision for fadd/fsub/fsqrt etc x87 instructions * There is no equivalent SSE mode or control. */ static __inline__ fp_prec_t __fpgetprec(void) { unsigned short _cw; __fnstcw(&_cw); return ((_cw & FP_PRC_FLD) >> FP_PRC_OFF); } static __inline__ fp_prec_t __fpsetprec(fp_rnd_t _m) { unsigned short _cw; fp_prec_t _p; __fnstcw(&_cw); _p = (_cw & FP_PRC_FLD) >> FP_PRC_OFF; _cw &= ~FP_PRC_FLD; _cw |= (_m << FP_PRC_OFF) & FP_PRC_FLD; __fldcw(&_cw); return (_p); } /* * Look at the exception masks * Note that x87 masks are inverse of the fp*() functions * API. ie: mask = 1 means disable for x87 and SSE, but * for the fp*() api, mask = 1 means enabled. */ static __inline__ fp_except_t __fpgetmask(void) { unsigned short _cw; __fnstcw(&_cw); return ((~_cw) & FP_MSKS_FLD); } static __inline__ fp_except_t __fpsetmask(fp_except_t _m) { unsigned short _cw; unsigned int _mxcsr; fp_except_t _p; __fnstcw(&_cw); _p = (~_cw) & FP_MSKS_FLD; _cw &= ~FP_MSKS_FLD; _cw |= (~_m) & FP_MSKS_FLD; __fldcw(&_cw); __stmxcsr(&_mxcsr); /* XXX should we clear non-ieee SSE_DAZ_FLD and SSE_FZ_FLD ? */ _mxcsr &= ~SSE_MSKS_FLD; _mxcsr |= ((~_m) << SSE_MSKS_OFF) & SSE_MSKS_FLD; __ldmxcsr(&_mxcsr); return (_p); } /* See which sticky exceptions are pending, and reset them */ static __inline__ fp_except_t __fpgetsticky(void) { unsigned short _sw; unsigned int _mxcsr; fp_except_t _ex; __fnstsw(&_sw); _ex = _sw & FP_STKY_FLD; __stmxcsr(&_mxcsr); _ex |= _mxcsr & SSE_STKY_FLD; return (_ex); } #endif /* __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE__ && !__cplusplus */ #if !defined(__IEEEFP_NOINLINES__) && !defined(__cplusplus) \ && defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE__) #define fpgetround() __fpgetround() #define fpsetround(_m) __fpsetround(_m) #define fpgetprec() __fpgetprec() #define fpsetprec(_m) __fpsetprec(_m) #define fpgetmask() __fpgetmask() #define fpsetmask(_m) __fpsetmask(_m) #define fpgetsticky() __fpgetsticky() /* Suppress prototypes in the MI header. */ #define _IEEEFP_INLINED_ 1 #else /* !__IEEEFP_NOINLINES__ && !__cplusplus && __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE__ */ /* Augment the userland declarations */ __BEGIN_DECLS extern fp_prec_t fpgetprec(void); extern fp_prec_t fpsetprec(fp_prec_t); __END_DECLS #endif /* !__IEEEFP_NOINLINES__ && !__cplusplus && __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE__ */ #endif /* !_BSD_IEEEFP_H_ */ openlibm-0.5.0/amd64/e_remainder.S000066400000000000000000000011361266752446200166510ustar00rootroot00000000000000/* * Based on the i387 version written by: * J.T. Conklin (jtc@netbsd.org) * Public domain. */ #include //RCSID("from: FreeBSD: src/lib/msun/i387/e_remainder.S,v 1.8 2005/02/04 14:08:32 das Exp") //__FBSDID("$FreeBSD: src/lib/msun/amd64/e_remainder.S,v 1.2 2011/01/07 16:13:12 kib Exp $") ENTRY(remainder) movsd %xmm0,-8(%rsp) movsd %xmm1,-16(%rsp) fldl -16(%rsp) fldl -8(%rsp) 1: fprem1 fstsw %ax testw $0x400,%ax jne 1b fstpl -8(%rsp) movsd -8(%rsp),%xmm0 fstp %st ret /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/amd64/e_remainderf.S000066400000000000000000000011141266752446200170130ustar00rootroot00000000000000/* * Based on the i387 version written by J.T. Conklin . * Public domain. */ #include //RCSID("from: $NetBSD: e_remainderf.S,v 1.2 1995/05/08 23:49:47 jtc Exp $") //__FBSDID("$FreeBSD: src/lib/msun/amd64/e_remainderf.S,v 1.2 2011/01/07 16:13:12 kib Exp $") ENTRY(remainderf) movss %xmm0,-4(%rsp) movss %xmm1,-8(%rsp) flds -8(%rsp) flds -4(%rsp) 1: fprem1 fstsw %ax testw $0x400,%ax jne 1b fstps -4(%rsp) movss -4(%rsp),%xmm0 fstp %st ret /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/amd64/e_remainderl.S000066400000000000000000000011141266752446200170210ustar00rootroot00000000000000/* * Based on the i387 version written by: * J.T. Conklin (jtc@netbsd.org) * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/amd64/e_remainderl.S,v 1.2 2011/01/07 16:13:12 kib Exp $") ENTRY(remainderl) #ifndef _WIN64 fldt 24(%rsp) fldt 8(%rsp) #else fldt (%r8) fldt (%rdx) #endif 1: fprem1 fstsw %ax testw $0x400,%ax jne 1b fstp %st(1) #ifdef _WIN64 mov %rcx,%rax movq $0x0,0x8(%rcx) fstpt (%rcx) #endif ret /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/amd64/e_sqrt.S000066400000000000000000000031471266752446200157000ustar00rootroot00000000000000/*- * Copyright (c) 2005 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include //__FBSDID("$FreeBSD: src/lib/msun/amd64/e_sqrt.S,v 1.4 2011/01/07 16:13:12 kib Exp $") ENTRY(sqrt) sqrtsd %xmm0, %xmm0 ret END(sqrt) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/amd64/e_sqrtf.S000066400000000000000000000031511266752446200160410ustar00rootroot00000000000000/*- * Copyright (c) 2005 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include //__FBSDID("$FreeBSD: src/lib/msun/amd64/e_sqrtf.S,v 1.3 2011/01/07 16:13:12 kib Exp $") ENTRY(sqrtf) sqrtss %xmm0, %xmm0 ret END(sqrtf) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/amd64/e_sqrtl.S000066400000000000000000000033311266752446200160470ustar00rootroot00000000000000/*- * Copyright (c) 2008 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include //__FBSDID("$FreeBSD: src/lib/msun/amd64/e_sqrtl.S,v 1.2 2011/01/07 16:13:12 kib Exp $") ENTRY(sqrtl) #ifndef _WIN64 fldt 8(%rsp) fsqrt #else fldt (%rdx) fsqrt mov %rcx,%rax movq $0x0,0x8(%rcx) fstpt (%rcx) #endif ret /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/amd64/fenv.c000066400000000000000000000077511266752446200153660ustar00rootroot00000000000000/*- * Copyright (c) 2004-2005 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/lib/msun/amd64/fenv.c,v 1.8 2011/10/21 06:25:31 das Exp $ */ #include "bsd_fpu.h" #include "math_private.h" #ifdef _WIN32 #define __fenv_static #endif #include #ifdef __GNUC_GNU_INLINE__ #error "This file must be compiled with C99 'inline' semantics" #endif const fenv_t __fe_dfl_env = { { 0xffff0000 | __INITIAL_FPUCW__, 0xffff0000, 0xffffffff, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff } }, __INITIAL_MXCSR__ }; extern inline DLLEXPORT int feclearexcept(int __excepts); extern inline DLLEXPORT int fegetexceptflag(fexcept_t *__flagp, int __excepts); DLLEXPORT int fesetexceptflag(const fexcept_t *flagp, int excepts) { fenv_t env; __fnstenv(&env.__x87); env.__x87.__status &= ~excepts; env.__x87.__status |= *flagp & excepts; __fldenv(env.__x87); __stmxcsr(&env.__mxcsr); env.__mxcsr &= ~excepts; env.__mxcsr |= *flagp & excepts; __ldmxcsr(env.__mxcsr); return (0); } DLLEXPORT int feraiseexcept(int excepts) { fexcept_t ex = excepts; fesetexceptflag(&ex, excepts); __fwait(); return (0); } extern inline DLLEXPORT int fetestexcept(int __excepts); extern inline DLLEXPORT int fegetround(void); extern inline DLLEXPORT int fesetround(int __round); DLLEXPORT int fegetenv(fenv_t *envp) { __fnstenv(&envp->__x87); __stmxcsr(&envp->__mxcsr); /* * fnstenv masks all exceptions, so we need to restore the * control word to avoid this side effect. */ __fldcw(envp->__x87.__control); return (0); } DLLEXPORT int feholdexcept(fenv_t *envp) { uint32_t mxcsr; __stmxcsr(&mxcsr); __fnstenv(&envp->__x87); __fnclex(); envp->__mxcsr = mxcsr; mxcsr &= ~FE_ALL_EXCEPT; mxcsr |= FE_ALL_EXCEPT << _SSE_EMASK_SHIFT; __ldmxcsr(mxcsr); return (0); } extern inline DLLEXPORT int fesetenv(const fenv_t *__envp); DLLEXPORT int feupdateenv(const fenv_t *envp) { uint32_t mxcsr; uint16_t status; __fnstsw(&status); __stmxcsr(&mxcsr); fesetenv(envp); feraiseexcept((mxcsr | status) & FE_ALL_EXCEPT); return (0); } int feenableexcept(int mask) { uint32_t mxcsr, omask; uint16_t control; mask &= FE_ALL_EXCEPT; __fnstcw(&control); __stmxcsr(&mxcsr); omask = ~(control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT; control &= ~mask; __fldcw(control); mxcsr &= ~(mask << _SSE_EMASK_SHIFT); __ldmxcsr(mxcsr); return (omask); } int fedisableexcept(int mask) { uint32_t mxcsr, omask; uint16_t control; mask &= FE_ALL_EXCEPT; __fnstcw(&control); __stmxcsr(&mxcsr); omask = ~(control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT; control |= mask; __fldcw(control); mxcsr |= mask << _SSE_EMASK_SHIFT; __ldmxcsr(mxcsr); return (omask); } openlibm-0.5.0/amd64/s_llrint.S000066400000000000000000000004151266752446200162240ustar00rootroot00000000000000#include //__FBSDID("$FreeBSD: src/lib/msun/amd64/s_llrint.S,v 1.3 2011/02/04 21:54:06 kib Exp $") ENTRY(llrint) cvtsd2si %xmm0, %rax ret END(llrint) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/amd64/s_llrintf.S000066400000000000000000000004201266752446200163660ustar00rootroot00000000000000#include //__FBSDID("$FreeBSD: src/lib/msun/amd64/s_llrintf.S,v 1.3 2011/02/04 21:54:06 kib Exp $") ENTRY(llrintf) cvtss2si %xmm0, %rax ret END(llrintf) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/amd64/s_llrintl.S000066400000000000000000000032641266752446200164050ustar00rootroot00000000000000/*- * Copyright (c) 2005 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include //__FBSDID("$FreeBSD: src/lib/msun/amd64/s_llrintl.S,v 1.2 2011/01/07 16:13:12 kib Exp $"); ENTRY(llrintl) #ifndef _WIN64 fldt 8(%rsp) #else fldt (%rcx) #endif subq $8,%rsp fistpll (%rsp) popq %rax ret /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/amd64/s_logbl.S000066400000000000000000000007301266752446200160170ustar00rootroot00000000000000/* * Written by: * J.T. Conklin (jtc@netbsd.org) * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/amd64/s_logbl.S,v 1.4 2011/01/07 16:13:12 kib Exp $") ENTRY(logbl) #ifndef _WIN64 fldt 8(%rsp) #else fldt (%rdx) #endif fxtract fstp %st #ifdef _WIN64 mov %rcx,%rax movq $0x0,0x8(%rcx) fstpt (%rcx) #endif ret /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/amd64/s_lrint.S000066400000000000000000000032341266752446200160520ustar00rootroot00000000000000/*- * Copyright (c) 2005 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include //__FBSDID("$FreeBSD: src/lib/msun/amd64/s_lrint.S,v 1.3 2011/01/07 16:13:12 kib Exp $") ENTRY(lrint) #ifndef _WIN64 cvtsd2si %xmm0, %rax #else cvtsd2si %xmm0, %eax #endif ret END(lrint) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/amd64/s_lrintf.S000066400000000000000000000032371266752446200162230ustar00rootroot00000000000000/*- * Copyright (c) 2005 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include //__FBSDID("$FreeBSD: src/lib/msun/amd64/s_lrintf.S,v 1.3 2011/01/07 16:13:12 kib Exp $") ENTRY(lrintf) #ifndef _WIN64 cvtss2si %xmm0, %rax #else cvtss2si %xmm0, %eax #endif ret END(lrintf) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/amd64/s_lrintl.S000066400000000000000000000032551266752446200162310ustar00rootroot00000000000000/*- * Copyright (c) 2008 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include //__FBSDID("$FreeBSD: src/lib/msun/amd64/s_lrintl.S,v 1.2 2011/01/07 16:13:12 kib Exp $"); ENTRY(lrintl) #ifndef _WIN64 fldt 8(%rsp) #else fldt (%rcx) #endif subq $8,%rsp fistpll (%rsp) popq %rax ret /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/amd64/s_remquo.S000066400000000000000000000045031266752446200162320ustar00rootroot00000000000000/*- * Copyright (c) 2005 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Based on public-domain remainder routine by J.T. Conklin . */ #include //__FBSDID("$FreeBSD: src/lib/msun/amd64/s_remquo.S,v 1.3 2011/01/07 16:13:12 kib Exp $"); ENTRY(remquo) movsd %xmm0,-8(%rsp) movsd %xmm1,-16(%rsp) fldl -16(%rsp) fldl -8(%rsp) 1: fprem1 fstsw %ax btw $10,%ax jc 1b fstp %st(1) /* Extract the three low-order bits of the quotient from C0,C3,C1. */ shrl $6,%eax movl %eax,%ecx andl $0x108,%eax rorl $7,%eax orl %eax,%ecx roll $4,%eax orl %ecx,%eax andl $7,%eax /* Negate the quotient bits if x*y<0. Avoid using an unpredictable branch. */ movl -12(%rsp),%ecx xorl -4(%rsp),%ecx sarl $16,%ecx sarl $16,%ecx xorl %ecx,%eax andl $1,%ecx addl %ecx,%eax /* Store the quotient and return. */ #ifndef _WIN64 movl %eax,(%rdi) #else movl %eax,(%r8) #endif fstpl -8(%rsp) movsd -8(%rsp),%xmm0 ret END(remquo) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/amd64/s_remquof.S000066400000000000000000000045031266752446200164000ustar00rootroot00000000000000/*- * Copyright (c) 2005 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Based on public-domain remainder routine by J.T. Conklin . */ #include //__FBSDID("$FreeBSD: src/lib/msun/amd64/s_remquof.S,v 1.3 2011/01/07 16:13:12 kib Exp $"); ENTRY(remquof) movss %xmm0,-4(%rsp) movss %xmm1,-8(%rsp) flds -8(%rsp) flds -4(%rsp) 1: fprem1 fstsw %ax btw $10,%ax jc 1b fstp %st(1) /* Extract the three low-order bits of the quotient from C0,C3,C1. */ shrl $6,%eax movl %eax,%ecx andl $0x108,%eax rorl $7,%eax orl %eax,%ecx roll $4,%eax orl %ecx,%eax andl $7,%eax /* Negate the quotient bits if x*y<0. Avoid using an unpredictable branch. */ movl -8(%rsp),%ecx xorl -4(%rsp),%ecx sarl $16,%ecx sarl $16,%ecx xorl %ecx,%eax andl $1,%ecx addl %ecx,%eax /* Store the quotient and return. */ #ifndef _WIN64 movl %eax,(%rdi) #else movl %eax,(%r8) #endif fstps -4(%rsp) movss -4(%rsp),%xmm0 ret END(remquof) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/amd64/s_remquol.S000066400000000000000000000046251266752446200164130ustar00rootroot00000000000000/*- * Copyright (c) 2005-2008 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Based on public-domain remainder routine by J.T. Conklin . */ #include //__FBSDID("$FreeBSD: src/lib/msun/amd64/s_remquol.S,v 1.2 2011/01/07 16:13:12 kib Exp $"); ENTRY(remquol) #ifndef _WIN64 fldt 24(%rsp) fldt 8(%rsp) #else fldt (%r8) fldt (%rdx) mov %rcx,%r8 #endif 1: fprem1 fstsw %ax btw $10,%ax jc 1b fstp %st(1) /* Extract the three low-order bits of the quotient from C0,C3,C1. */ shrl $6,%eax movl %eax,%ecx andl $0x108,%eax rorl $7,%eax orl %eax,%ecx roll $4,%eax orl %ecx,%eax andl $7,%eax /* Negate the quotient bits if x*y<0. Avoid using an unpredictable branch. */ movl 32(%rsp),%ecx xorl 16(%rsp),%ecx movsx %cx,%ecx sarl $16,%ecx sarl $16,%ecx xorl %ecx,%eax andl $1,%ecx addl %ecx,%eax /* Store the quotient and return. */ #ifndef _WIN64 movl %eax,(%rdi) #else movl %eax,(%r9) mov %r8,%rax movq $0x0,0x8(%r8) fstpt (%r8) #endif ret /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/amd64/s_rintl.S000066400000000000000000000005611266752446200160520ustar00rootroot00000000000000/* * Written by: * J.T. Conklin (jtc@netbsd.org) * Public domain. */ #include ENTRY(rintl) #ifndef _WIN64 fldt 8(%rsp) frndint #else fldt (%rdx) frndint mov %rcx,%rax movq $0x0,0x8(%rcx) fstpt (%rcx) #endif ret /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/amd64/s_scalbn.S000066400000000000000000000036351266752446200161710ustar00rootroot00000000000000/*- * Copyright (c) 2005 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include //__FBSDID("$FreeBSD: src/lib/msun/amd64/s_scalbn.S,v 1.3 2011/01/07 16:13:12 kib Exp $") ENTRY(scalbn) movsd %xmm0,-8(%rsp) #ifndef _WIN64 movl %edi,-12(%rsp) #else movl %edx,-12(%rsp) #endif fildl -12(%rsp) fldl -8(%rsp) fscale fstp %st(1) fstpl -8(%rsp) movsd -8(%rsp),%xmm0 ret #ifndef _WIN64 END(scalbn) .globl CNAME(ldexp) #else .globl CNAME(ldexp); .section .drectve; .ascii " -export:ldexp" #endif .set CNAME(ldexp),CNAME(scalbn) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/amd64/s_scalbnf.S000066400000000000000000000036421266752446200163350ustar00rootroot00000000000000/*- * Copyright (c) 2005 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include //__FBSDID("$FreeBSD: src/lib/msun/amd64/s_scalbnf.S,v 1.4 2011/01/07 16:13:12 kib Exp $") ENTRY(scalbnf) movss %xmm0,-8(%rsp) #ifndef _WIN64 movl %edi,-4(%rsp) #else movl %edx,-4(%rsp) #endif fildl -4(%rsp) flds -8(%rsp) fscale fstp %st(1) fstps -8(%rsp) movss -8(%rsp),%xmm0 ret #ifndef _WIN64 END(scalbnf) .globl CNAME(ldexpf) #else .globl CNAME(ldexpf); .section .drectve; .ascii " -export:ldexpf" #endif .set CNAME(ldexpf),CNAME(scalbnf) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/amd64/s_scalbnl.S000066400000000000000000000014661266752446200163450ustar00rootroot00000000000000/* * Based on code written by J.T. Conklin . * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/amd64/s_scalbnl.S,v 1.3 2011/01/07 16:13:12 kib Exp $") /* //RCSID("$NetBSD: s_scalbnf.S,v 1.4 1999/01/02 05:15:40 kristerw Exp $") */ ENTRY(scalbnl) #ifndef _WIN64 movl %edi,-4(%rsp) fildl -4(%rsp) fldt 8(%rsp) #else mov %r8,%rax movl %eax,-4(%rsp) fildl -4(%rsp) fldt (%rdx) #endif fscale fstp %st(1) #ifdef _WIN64 mov %rcx,%rax movq $0x0,0x8(%rcx) fstpt (%rcx) #endif ret #ifndef _WIN64 END(scalbnl) .globl CNAME(ldexpl) #else .globl CNAME(ldexpl); .section .drectve; .ascii " -export:ldexpl" #endif .set CNAME(ldexpl),CNAME(scalbnl) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/arm/000077500000000000000000000000001266752446200141165ustar00rootroot00000000000000openlibm-0.5.0/arm/Make.files000066400000000000000000000000251266752446200160140ustar00rootroot00000000000000$(CUR_SRCS) = fenv.c openlibm-0.5.0/arm/fenv.c000066400000000000000000000043761266752446200152320ustar00rootroot00000000000000/*- * Copyright (c) 2004 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/lib/msun/arm/fenv.c,v 1.3 2011/10/16 05:37:56 das Exp $ */ #define __fenv_static #include #ifdef __GNUC_GNU_INLINE__ #error "This file must be compiled with C99 'inline' semantics" #endif /* * Hopefully the system ID byte is immutable, so it's valid to use * this as a default environment. */ const fenv_t __fe_dfl_env = 0; extern inline int feclearexcept(int __excepts); extern inline int fegetexceptflag(fexcept_t *__flagp, int __excepts); extern inline int fesetexceptflag(const fexcept_t *__flagp, int __excepts); extern inline int feraiseexcept(int __excepts); extern inline int fetestexcept(int __excepts); extern inline int fegetround(void); extern inline int fesetround(int __round); extern inline int fegetenv(fenv_t *__envp); extern inline int feholdexcept(fenv_t *__envp); extern inline int fesetenv(const fenv_t *__envp); extern inline int feupdateenv(const fenv_t *__envp); openlibm-0.5.0/bsdsrc/000077500000000000000000000000001266752446200146175ustar00rootroot00000000000000openlibm-0.5.0/bsdsrc/Make.files000066400000000000000000000000601266752446200165140ustar00rootroot00000000000000$(CUR_SRCS) += b_exp.c b_log.c b_tgamma.c openlibm-0.5.0/bsdsrc/b_exp.c000066400000000000000000000120151266752446200160570ustar00rootroot00000000000000/* * Copyright (c) 1985, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* @(#)exp.c 8.1 (Berkeley) 6/4/93 */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/bsdsrc/b_exp.c,v 1.9 2011/10/16 05:37:20 das Exp $"); #include /* EXP(X) * RETURN THE EXPONENTIAL OF X * DOUBLE PRECISION (IEEE 53 bits, VAX D FORMAT 56 BITS) * CODED IN C BY K.C. NG, 1/19/85; * REVISED BY K.C. NG on 2/6/85, 2/15/85, 3/7/85, 3/24/85, 4/16/85, 6/14/86. * * Required system supported functions: * scalb(x,n) * copysign(x,y) * finite(x) * * Method: * 1. Argument Reduction: given the input x, find r and integer k such * that * x = k*ln2 + r, |r| <= 0.5*ln2 . * r will be represented as r := z+c for better accuracy. * * 2. Compute exp(r) by * * exp(r) = 1 + r + r*R1/(2-R1), * where * R1 = x - x^2*(p1+x^2*(p2+x^2*(p3+x^2*(p4+p5*x^2)))). * * 3. exp(x) = 2^k * exp(r) . * * Special cases: * exp(INF) is INF, exp(NaN) is NaN; * exp(-INF)= 0; * for finite argument, only exp(0)=1 is exact. * * Accuracy: * exp(x) returns the exponential of x nearly rounded. In a test run * with 1,156,000 random arguments on a VAX, the maximum observed * error was 0.869 ulps (units in the last place). */ #include "mathimpl.h" static const double p1 = 0x1.555555555553ep-3; static const double p2 = -0x1.6c16c16bebd93p-9; static const double p3 = 0x1.1566aaf25de2cp-14; static const double p4 = -0x1.bbd41c5d26bf1p-20; static const double p5 = 0x1.6376972bea4d0p-25; static const double ln2hi = 0x1.62e42fee00000p-1; static const double ln2lo = 0x1.a39ef35793c76p-33; static const double lnhuge = 0x1.6602b15b7ecf2p9; static const double lntiny = -0x1.77af8ebeae354p9; static const double invln2 = 0x1.71547652b82fep0; #if 0 DLLEXPORT double exp(x) double x; { double z,hi,lo,c; int k; #if !defined(vax)&&!defined(tahoe) if(x!=x) return(x); /* x is NaN */ #endif /* !defined(vax)&&!defined(tahoe) */ if( x <= lnhuge ) { if( x >= lntiny ) { /* argument reduction : x --> x - k*ln2 */ k=invln2*x+copysign(0.5,x); /* k=NINT(x/ln2) */ /* express x-k*ln2 as hi-lo and let x=hi-lo rounded */ hi=x-k*ln2hi; x=hi-(lo=k*ln2lo); /* return 2^k*[1+x+x*c/(2+c)] */ z=x*x; c= x - z*(p1+z*(p2+z*(p3+z*(p4+z*p5)))); return scalb(1.0+(hi-(lo-(x*c)/(2.0-c))),k); } /* end of x > lntiny */ else /* exp(-big#) underflows to zero */ if(finite(x)) return(scalb(1.0,-5000)); /* exp(-INF) is zero */ else return(0.0); } /* end of x < lnhuge */ else /* exp(INF) is INF, exp(+big#) overflows to INF */ return( finite(x) ? scalb(1.0,5000) : x); } #endif /* returns exp(r = x + c) for |c| < |x| with no overlap. */ double __exp__D(x, c) double x, c; { double z,hi,lo; int k; if (x != x) /* x is NaN */ return(x); if ( x <= lnhuge ) { if ( x >= lntiny ) { /* argument reduction : x --> x - k*ln2 */ z = invln2*x; k = z + copysign(.5, x); /* express (x+c)-k*ln2 as hi-lo and let x=hi-lo rounded */ hi=(x-k*ln2hi); /* Exact. */ x= hi - (lo = k*ln2lo-c); /* return 2^k*[1+x+x*c/(2+c)] */ z=x*x; c= x - z*(p1+z*(p2+z*(p3+z*(p4+z*p5)))); c = (x*c)/(2.0-c); return scalbn(1.+(hi-(lo - c)), k); } /* end of x > lntiny */ else /* exp(-big#) underflows to zero */ if(isfinite(x)) return(scalbn(1.0,-5000)); /* exp(-INF) is zero */ else return(0.0); } /* end of x < lnhuge */ else /* exp(INF) is INF, exp(+big#) overflows to INF */ return( isfinite(x) ? scalbn(1.0,5000) : x); } openlibm-0.5.0/bsdsrc/b_log.c000066400000000000000000000327521266752446200160560ustar00rootroot00000000000000/* * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* @(#)log.c 8.2 (Berkeley) 11/30/93 */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/bsdsrc/b_log.c,v 1.9 2008/02/22 02:26:51 das Exp $"); #include #include "mathimpl.h" /* Table-driven natural logarithm. * * This code was derived, with minor modifications, from: * Peter Tang, "Table-Driven Implementation of the * Logarithm in IEEE Floating-Point arithmetic." ACM Trans. * Math Software, vol 16. no 4, pp 378-400, Dec 1990). * * Calculates log(2^m*F*(1+f/F)), |f/j| <= 1/256, * where F = j/128 for j an integer in [0, 128]. * * log(2^m) = log2_hi*m + log2_tail*m * since m is an integer, the dominant term is exact. * m has at most 10 digits (for subnormal numbers), * and log2_hi has 11 trailing zero bits. * * log(F) = logF_hi[j] + logF_lo[j] is in tabular form in log_table.h * logF_hi[] + 512 is exact. * * log(1+f/F) = 2*f/(2*F + f) + 1/12 * (2*f/(2*F + f))**3 + ... * the leading term is calculated to extra precision in two * parts, the larger of which adds exactly to the dominant * m and F terms. * There are two cases: * 1. when m, j are non-zero (m | j), use absolute * precision for the leading term. * 2. when m = j = 0, |1-x| < 1/256, and log(x) ~= (x-1). * In this case, use a relative precision of 24 bits. * (This is done differently in the original paper) * * Special cases: * 0 return signalling -Inf * neg return signalling NaN * +Inf return +Inf */ #define N 128 /* Table of log(Fj) = logF_head[j] + logF_tail[j], for Fj = 1+j/128. * Used for generation of extend precision logarithms. * The constant 35184372088832 is 2^45, so the divide is exact. * It ensures correct reading of logF_head, even for inaccurate * decimal-to-binary conversion routines. (Everybody gets the * right answer for integers less than 2^53.) * Values for log(F) were generated using error < 10^-57 absolute * with the bc -l package. */ static double A1 = .08333333333333178827; static double A2 = .01250000000377174923; static double A3 = .002232139987919447809; static double A4 = .0004348877777076145742; static double logF_head[N+1] = { 0., .007782140442060381246, .015504186535963526694, .023167059281547608406, .030771658666765233647, .038318864302141264488, .045809536031242714670, .053244514518837604555, .060624621816486978786, .067950661908525944454, .075223421237524235039, .082443669210988446138, .089612158689760690322, .096729626458454731618, .103796793681567578460, .110814366340264314203, .117783035656430001836, .124703478501032805070, .131576357788617315236, .138402322859292326029, .145182009844575077295, .151916042025732167530, .158605030176659056451, .165249572895390883786, .171850256926518341060, .178407657472689606947, .184922338493834104156, .191394852999565046047, .197825743329758552135, .204215541428766300668, .210564769107350002741, .216873938300523150246, .223143551314024080056, .229374101064877322642, .235566071312860003672, .241719936886966024758, .247836163904594286577, .253915209980732470285, .259957524436686071567, .265963548496984003577, .271933715484010463114, .277868451003087102435, .283768173130738432519, .289633292582948342896, .295464212893421063199, .301261330578199704177, .307025035294827830512, .312755710004239517729, .318453731118097493890, .324119468654316733591, .329753286372579168528, .335355541920762334484, .340926586970454081892, .346466767346100823488, .351976423156884266063, .357455888922231679316, .362905493689140712376, .368325561158599157352, .373716409793814818840, .379078352934811846353, .384411698910298582632, .389716751140440464951, .394993808240542421117, .400243164127459749579, .405465108107819105498, .410659924985338875558, .415827895143593195825, .420969294644237379543, .426084395310681429691, .431173464818130014464, .436236766774527495726, .441274560805140936281, .446287102628048160113, .451274644139630254358, .456237433481874177232, .461175715122408291790, .466089729924533457960, .470979715219073113985, .475845904869856894947, .480688529345570714212, .485507815781602403149, .490303988045525329653, .495077266798034543171, .499827869556611403822, .504556010751912253908, .509261901790523552335, .513945751101346104405, .518607764208354637958, .523248143765158602036, .527867089620485785417, .532464798869114019908, .537041465897345915436, .541597282432121573947, .546132437597407260909, .550647117952394182793, .555141507540611200965, .559615787935399566777, .564070138285387656651, .568504735352689749561, .572919753562018740922, .577315365035246941260, .581691739635061821900, .586049045003164792433, .590387446602107957005, .594707107746216934174, .599008189645246602594, .603290851438941899687, .607555250224322662688, .611801541106615331955, .616029877215623855590, .620240409751204424537, .624433288012369303032, .628608659422752680256, .632766669570628437213, .636907462236194987781, .641031179420679109171, .645137961373620782978, .649227946625615004450, .653301272011958644725, .657358072709030238911, .661398482245203922502, .665422632544505177065, .669430653942981734871, .673422675212350441142, .677398823590920073911, .681359224807238206267, .685304003098281100392, .689233281238557538017, .693147180560117703862 }; static double logF_tail[N+1] = { 0., -.00000000000000543229938420049, .00000000000000172745674997061, -.00000000000001323017818229233, -.00000000000001154527628289872, -.00000000000000466529469958300, .00000000000005148849572685810, -.00000000000002532168943117445, -.00000000000005213620639136504, -.00000000000001819506003016881, .00000000000006329065958724544, .00000000000008614512936087814, -.00000000000007355770219435028, .00000000000009638067658552277, .00000000000007598636597194141, .00000000000002579999128306990, -.00000000000004654729747598444, -.00000000000007556920687451336, .00000000000010195735223708472, -.00000000000017319034406422306, -.00000000000007718001336828098, .00000000000010980754099855238, -.00000000000002047235780046195, -.00000000000008372091099235912, .00000000000014088127937111135, .00000000000012869017157588257, .00000000000017788850778198106, .00000000000006440856150696891, .00000000000016132822667240822, -.00000000000007540916511956188, -.00000000000000036507188831790, .00000000000009120937249914984, .00000000000018567570959796010, -.00000000000003149265065191483, -.00000000000009309459495196889, .00000000000017914338601329117, -.00000000000001302979717330866, .00000000000023097385217586939, .00000000000023999540484211737, .00000000000015393776174455408, -.00000000000036870428315837678, .00000000000036920375082080089, -.00000000000009383417223663699, .00000000000009433398189512690, .00000000000041481318704258568, -.00000000000003792316480209314, .00000000000008403156304792424, -.00000000000034262934348285429, .00000000000043712191957429145, -.00000000000010475750058776541, -.00000000000011118671389559323, .00000000000037549577257259853, .00000000000013912841212197565, .00000000000010775743037572640, .00000000000029391859187648000, -.00000000000042790509060060774, .00000000000022774076114039555, .00000000000010849569622967912, -.00000000000023073801945705758, .00000000000015761203773969435, .00000000000003345710269544082, -.00000000000041525158063436123, .00000000000032655698896907146, -.00000000000044704265010452446, .00000000000034527647952039772, -.00000000000007048962392109746, .00000000000011776978751369214, -.00000000000010774341461609578, .00000000000021863343293215910, .00000000000024132639491333131, .00000000000039057462209830700, -.00000000000026570679203560751, .00000000000037135141919592021, -.00000000000017166921336082431, -.00000000000028658285157914353, -.00000000000023812542263446809, .00000000000006576659768580062, -.00000000000028210143846181267, .00000000000010701931762114254, .00000000000018119346366441110, .00000000000009840465278232627, -.00000000000033149150282752542, -.00000000000018302857356041668, -.00000000000016207400156744949, .00000000000048303314949553201, -.00000000000071560553172382115, .00000000000088821239518571855, -.00000000000030900580513238244, -.00000000000061076551972851496, .00000000000035659969663347830, .00000000000035782396591276383, -.00000000000046226087001544578, .00000000000062279762917225156, .00000000000072838947272065741, .00000000000026809646615211673, -.00000000000010960825046059278, .00000000000002311949383800537, -.00000000000058469058005299247, -.00000000000002103748251144494, -.00000000000023323182945587408, -.00000000000042333694288141916, -.00000000000043933937969737844, .00000000000041341647073835565, .00000000000006841763641591466, .00000000000047585534004430641, .00000000000083679678674757695, -.00000000000085763734646658640, .00000000000021913281229340092, -.00000000000062242842536431148, -.00000000000010983594325438430, .00000000000065310431377633651, -.00000000000047580199021710769, -.00000000000037854251265457040, .00000000000040939233218678664, .00000000000087424383914858291, .00000000000025218188456842882, -.00000000000003608131360422557, -.00000000000050518555924280902, .00000000000078699403323355317, -.00000000000067020876961949060, .00000000000016108575753932458, .00000000000058527188436251509, -.00000000000035246757297904791, -.00000000000018372084495629058, .00000000000088606689813494916, .00000000000066486268071468700, .00000000000063831615170646519, .00000000000025144230728376072, -.00000000000017239444525614834 }; #if 0 DLLEXPORT double #ifdef _ANSI_SOURCE log(double x) #else log(x) double x; #endif { int m, j; double F, f, g, q, u, u2, v, zero = 0.0, one = 1.0; volatile double u1; /* Catch special cases */ if (x <= 0) if (x == zero) /* log(0) = -Inf */ return (-one/zero); else /* log(neg) = NaN */ return (zero/zero); else if (!finite(x)) return (x+x); /* x = NaN, Inf */ /* Argument reduction: 1 <= g < 2; x/2^m = g; */ /* y = F*(1 + f/F) for |f| <= 2^-8 */ m = logb(x); g = ldexp(x, -m); if (m == -1022) { j = logb(g), m += j; g = ldexp(g, -j); } j = N*(g-1) + .5; F = (1.0/N) * j + 1; /* F*128 is an integer in [128, 512] */ f = g - F; /* Approximate expansion for log(1+f/F) ~= u + q */ g = 1/(2*F+f); u = 2*f*g; v = u*u; q = u*v*(A1 + v*(A2 + v*(A3 + v*A4))); /* case 1: u1 = u rounded to 2^-43 absolute. Since u < 2^-8, * u1 has at most 35 bits, and F*u1 is exact, as F has < 8 bits. * It also adds exactly to |m*log2_hi + log_F_head[j] | < 750 */ if (m | j) u1 = u + 513, u1 -= 513; /* case 2: |1-x| < 1/256. The m- and j- dependent terms are zero; * u1 = u to 24 bits. */ else u1 = u, TRUNC(u1); u2 = (2.0*(f - F*u1) - u1*f) * g; /* u1 + u2 = 2f/(2F+f) to extra precision. */ /* log(x) = log(2^m*F*(1+f/F)) = */ /* (m*log2_hi+logF_head[j]+u1) + (m*log2_lo+logF_tail[j]+q); */ /* (exact) + (tiny) */ u1 += m*logF_head[N] + logF_head[j]; /* exact */ u2 = (u2 + logF_tail[j]) + q; /* tiny */ u2 += logF_tail[N]*m; return (u1 + u2); } #endif /* * Extra precision variant, returning struct {double a, b;}; * log(x) = a+b to 63 bits, with a rounded to 26 bits. */ struct Double #ifdef _ANSI_SOURCE __log__D(double x) #else __log__D(x) double x; #endif { int m, j; double F, f, g, q, u, v, u2; volatile double u1; struct Double r; /* Argument reduction: 1 <= g < 2; x/2^m = g; */ /* y = F*(1 + f/F) for |f| <= 2^-8 */ m = logb(x); g = ldexp(x, -m); if (m == -1022) { j = logb(g), m += j; g = ldexp(g, -j); } j = N*(g-1) + .5; F = (1.0/N) * j + 1; f = g - F; g = 1/(2*F+f); u = 2*f*g; v = u*u; q = u*v*(A1 + v*(A2 + v*(A3 + v*A4))); if (m | j) u1 = u + 513, u1 -= 513; else u1 = u, TRUNC(u1); u2 = (2.0*(f - F*u1) - u1*f) * g; u1 += m*logF_head[N] + logF_head[j]; u2 += logF_tail[j]; u2 += q; u2 += logF_tail[N]*m; r.a = u1 + u2; /* Only difference is here */ TRUNC(r.a); r.b = (u1 - r.a) + u2; return (r); } openlibm-0.5.0/bsdsrc/b_tgamma.c000066400000000000000000000210701266752446200165320ustar00rootroot00000000000000/*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* @(#)gamma.c 8.1 (Berkeley) 6/4/93 */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/bsdsrc/b_tgamma.c,v 1.10 2008/02/22 02:26:51 das Exp $"); /* * This code by P. McIlroy, Oct 1992; * * The financial support of UUNET Communications Services is greatfully * acknowledged. */ #include #include "mathimpl.h" /* METHOD: * x < 0: Use reflection formula, G(x) = pi/(sin(pi*x)*x*G(x)) * At negative integers, return NaN and raise invalid. * * x < 6.5: * Use argument reduction G(x+1) = xG(x) to reach the * range [1.066124,2.066124]. Use a rational * approximation centered at the minimum (x0+1) to * ensure monotonicity. * * x >= 6.5: Use the asymptotic approximation (Stirling's formula) * adjusted for equal-ripples: * * log(G(x)) ~= (x-.5)*(log(x)-1) + .5(log(2*pi)-1) + 1/x*P(1/(x*x)) * * Keep extra precision in multiplying (x-.5)(log(x)-1), to * avoid premature round-off. * * Special values: * -Inf: return NaN and raise invalid; * negative integer: return NaN and raise invalid; * other x ~< 177.79: return +-0 and raise underflow; * +-0: return +-Inf and raise divide-by-zero; * finite x ~> 171.63: return +Inf and raise overflow; * +Inf: return +Inf; * NaN: return NaN. * * Accuracy: tgamma(x) is accurate to within * x > 0: error provably < 0.9ulp. * Maximum observed in 1,000,000 trials was .87ulp. * x < 0: * Maximum observed error < 4ulp in 1,000,000 trials. */ static double neg_gam(double); static double small_gam(double); static double smaller_gam(double); static struct Double large_gam(double); static struct Double ratfun_gam(double, double); /* * Rational approximation, A0 + x*x*P(x)/Q(x), on the interval * [1.066.., 2.066..] accurate to 4.25e-19. */ #define LEFT -.3955078125 /* left boundary for rat. approx */ #define x0 .461632144968362356785 /* xmin - 1 */ #define a0_hi 0.88560319441088874992 #define a0_lo -.00000000000000004996427036469019695 #define P0 6.21389571821820863029017800727e-01 #define P1 2.65757198651533466104979197553e-01 #define P2 5.53859446429917461063308081748e-03 #define P3 1.38456698304096573887145282811e-03 #define P4 2.40659950032711365819348969808e-03 #define Q0 1.45019531250000000000000000000e+00 #define Q1 1.06258521948016171343454061571e+00 #define Q2 -2.07474561943859936441469926649e-01 #define Q3 -1.46734131782005422506287573015e-01 #define Q4 3.07878176156175520361557573779e-02 #define Q5 5.12449347980666221336054633184e-03 #define Q6 -1.76012741431666995019222898833e-03 #define Q7 9.35021023573788935372153030556e-05 #define Q8 6.13275507472443958924745652239e-06 /* * Constants for large x approximation (x in [6, Inf]) * (Accurate to 2.8*10^-19 absolute) */ #define lns2pi_hi 0.418945312500000 #define lns2pi_lo -.000006779295327258219670263595 #define Pa0 8.33333333333333148296162562474e-02 #define Pa1 -2.77777777774548123579378966497e-03 #define Pa2 7.93650778754435631476282786423e-04 #define Pa3 -5.95235082566672847950717262222e-04 #define Pa4 8.41428560346653702135821806252e-04 #define Pa5 -1.89773526463879200348872089421e-03 #define Pa6 5.69394463439411649408050664078e-03 #define Pa7 -1.44705562421428915453880392761e-02 static const double zero = 0., one = 1.0, tiny = 1e-300; DLLEXPORT double tgamma(x) double x; { struct Double u; if (x >= 6) { if(x > 171.63) return (x / zero); u = large_gam(x); return(__exp__D(u.a, u.b)); } else if (x >= 1.0 + LEFT + x0) return (small_gam(x)); else if (x > 1.e-17) return (smaller_gam(x)); else if (x > -1.e-17) { if (x != 0.0) u.a = one - tiny; /* raise inexact */ return (one/x); } else if (!isfinite(x)) return (x - x); /* x is NaN or -Inf */ else return (neg_gam(x)); } /* * Accurate to max(ulp(1/128) absolute, 2^-66 relative) error. */ static struct Double large_gam(x) double x; { double z, p; struct Double t, u, v; z = one/(x*x); p = Pa0+z*(Pa1+z*(Pa2+z*(Pa3+z*(Pa4+z*(Pa5+z*(Pa6+z*Pa7)))))); p = p/x; u = __log__D(x); u.a -= one; v.a = (x -= .5); TRUNC(v.a); v.b = x - v.a; t.a = v.a*u.a; /* t = (x-.5)*(log(x)-1) */ t.b = v.b*u.a + x*u.b; /* return t.a + t.b + lns2pi_hi + lns2pi_lo + p */ t.b += lns2pi_lo; t.b += p; u.a = lns2pi_hi + t.b; u.a += t.a; u.b = t.a - u.a; u.b += lns2pi_hi; u.b += t.b; return (u); } /* * Good to < 1 ulp. (provably .90 ulp; .87 ulp on 1,000,000 runs.) * It also has correct monotonicity. */ static double small_gam(x) double x; { double y, ym1, t; struct Double yy, r; y = x - one; ym1 = y - one; if (y <= 1.0 + (LEFT + x0)) { yy = ratfun_gam(y - x0, 0); return (yy.a + yy.b); } r.a = y; TRUNC(r.a); yy.a = r.a - one; y = ym1; yy.b = r.b = y - yy.a; /* Argument reduction: G(x+1) = x*G(x) */ for (ym1 = y-one; ym1 > LEFT + x0; y = ym1--, yy.a--) { t = r.a*yy.a; r.b = r.a*yy.b + y*r.b; r.a = t; TRUNC(r.a); r.b += (t - r.a); } /* Return r*tgamma(y). */ yy = ratfun_gam(y - x0, 0); y = r.b*(yy.a + yy.b) + r.a*yy.b; y += yy.a*r.a; return (y); } /* * Good on (0, 1+x0+LEFT]. Accurate to 1ulp. */ static double smaller_gam(x) double x; { double t, d; struct Double r, xx; if (x < x0 + LEFT) { t = x, TRUNC(t); d = (t+x)*(x-t); t *= t; xx.a = (t + x), TRUNC(xx.a); xx.b = x - xx.a; xx.b += t; xx.b += d; t = (one-x0); t += x; d = (one-x0); d -= t; d += x; x = xx.a + xx.b; } else { xx.a = x, TRUNC(xx.a); xx.b = x - xx.a; t = x - x0; d = (-x0 -t); d += x; } r = ratfun_gam(t, d); d = r.a/x, TRUNC(d); r.a -= d*xx.a; r.a -= d*xx.b; r.a += r.b; return (d + r.a/x); } /* * returns (z+c)^2 * P(z)/Q(z) + a0 */ static struct Double ratfun_gam(z, c) double z, c; { double p, q; struct Double r, t; q = Q0 +z*(Q1+z*(Q2+z*(Q3+z*(Q4+z*(Q5+z*(Q6+z*(Q7+z*Q8))))))); p = P0 + z*(P1 + z*(P2 + z*(P3 + z*P4))); /* return r.a + r.b = a0 + (z+c)^2*p/q, with r.a truncated to 26 bits. */ p = p/q; t.a = z, TRUNC(t.a); /* t ~= z + c */ t.b = (z - t.a) + c; t.b *= (t.a + z); q = (t.a *= t.a); /* t = (z+c)^2 */ TRUNC(t.a); t.b += (q - t.a); r.a = p, TRUNC(r.a); /* r = P/Q */ r.b = p - r.a; t.b = t.b*p + t.a*r.b + a0_lo; t.a *= r.a; /* t = (z+c)^2*(P/Q) */ r.a = t.a + a0_hi, TRUNC(r.a); r.b = ((a0_hi-r.a) + t.a) + t.b; return (r); /* r = a0 + t */ } static double neg_gam(x) double x; { int sgn = 1; struct Double lg, lsine; double y, z; y = ceil(x); if (y == x) /* Negative integer. */ return ((x - x) / zero); z = y - x; if (z > 0.5) z = one - z; y = 0.5 * y; if (y == ceil(y)) sgn = -1; if (z < .25) z = sin(M_PI*z); else z = cos(M_PI*(0.5-z)); /* Special case: G(1-x) = Inf; G(x) may be nonzero. */ if (x < -170) { if (x < -190) return ((double)sgn*tiny*tiny); y = one - x; /* exact: 128 < |x| < 255 */ lg = large_gam(y); lsine = __log__D(M_PI/z); /* = TRUNC(log(u)) + small */ lg.a -= lsine.a; /* exact (opposite signs) */ lg.b -= lsine.b; y = -(lg.a + lg.b); z = (y + lg.a) + lg.b; y = __exp__D(y, z); if (sgn < 0) y = -y; return (y); } y = one-x; if (one-y == x) y = tgamma(y); else /* 1-x is inexact */ y = -x*tgamma(-x); if (sgn < 0) y = -y; return (M_PI / (y*z)); } openlibm-0.5.0/bsdsrc/mathimpl.h000066400000000000000000000047651266752446200166170ustar00rootroot00000000000000/* * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)mathimpl.h 8.1 (Berkeley) 6/4/93 * $FreeBSD: src/lib/msun/bsdsrc/mathimpl.h,v 1.7 2005/11/18 05:03:12 bde Exp $ */ #ifndef _MATHIMPL_H_ #define _MATHIMPL_H_ #include "cdefs-compat.h" #include "math_private.h" /* * TRUNC() is a macro that sets the trailing 27 bits in the mantissa of an * IEEE double variable to zero. It must be expression-like for syntactic * reasons, and we implement this expression using an inline function * instead of a pure macro to avoid depending on the gcc feature of * statement-expressions. */ #define TRUNC(d) (_b_trunc(&(d))) static __inline void _b_trunc(volatile double *_dp) { //VBS //u_int32_t _lw; u_int32_t _lw; GET_LOW_WORD(_lw, *_dp); SET_LOW_WORD(*_dp, _lw & 0xf8000000); } struct Double { double a; double b; }; /* * Functions internal to the math package, yet not static. */ double __exp__D(double, double); struct Double __log__D(double); #endif /* !_MATHIMPL_H_ */ openlibm-0.5.0/i387/000077500000000000000000000000001266752446200140315ustar00rootroot00000000000000openlibm-0.5.0/i387/Make.files000066400000000000000000000012531266752446200157330ustar00rootroot00000000000000$(CUR_SRCS) = e_exp.S e_fmod.S e_log.S e_log10.S \ e_remainder.S e_sqrt.S s_ceil.S s_copysign.S \ s_floor.S s_llrint.S s_logb.S s_lrint.S \ s_remquo.S s_rint.S s_tan.S s_trunc.S ifneq ($(OS), WINNT) $(CUR_SRCS) += s_scalbn.S s_scalbnf.S s_scalbnl.S endif # float counterparts $(CUR_SRCS)+= e_log10f.S e_logf.S e_remainderf.S \ e_sqrtf.S s_ceilf.S s_copysignf.S s_floorf.S \ s_llrintf.S s_logbf.S s_lrintf.S \ s_remquof.S s_rintf.S s_truncf.S # long double counterparts $(CUR_SRCS)+= e_remainderl.S e_sqrtl.S s_ceill.S s_copysignl.S \ s_floorl.S s_llrintl.S \ s_logbl.S s_lrintl.S s_remquol.S s_rintl.S s_truncl.S $(CUR_SRCS)+= fenv.c openlibm-0.5.0/i387/bsd_asm.h000066400000000000000000000073641266752446200156240ustar00rootroot00000000000000/*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * William Jolitz. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * from: @(#)DEFS.h 5.1 (Berkeley) 4/23/90 * $FreeBSD: src/sys/i386/include/asm.h,v 1.14 2007/08/22 04:26:07 jkoshy Exp $ */ #ifndef _MACHINE_ASM_H_ #define _MACHINE_ASM_H_ #if defined(__APPLE__) #include "osx_asm.h" #define CNAME(x) EXT(x) #else #include "cdefs-compat.h" #ifdef PIC #define PIC_PROLOGUE \ pushl %ebx; \ call 1f; \ 1: \ popl %ebx; \ addl $_GLOBAL_OFFSET_TABLE_+[.-1b],%ebx #define PIC_EPILOGUE \ popl %ebx #define PIC_PLT(x) x@PLT #define PIC_GOT(x) x@GOT(%ebx) #else #define PIC_PROLOGUE #define PIC_EPILOGUE #define PIC_PLT(x) x #define PIC_GOT(x) x #endif /* * CNAME and HIDENAME manage the relationship between symbol names in C * and the equivalent assembly language names. CNAME is given a name as * it would be used in a C program. It expands to the equivalent assembly * language name. HIDENAME is given an assembly-language name, and expands * to a possibly-modified form that will be invisible to C programs. */ /* XXX should use .p2align 4,0x90 for -m486. */ #define _START_ENTRY .p2align 2,0x90 #if defined(__ELF__) #define CNAME(csym) csym #define HIDENAME(asmsym) .asmsym #define _ENTRY(x) .text; _START_ENTRY; \ .globl CNAME(x); .type CNAME(x),@function; CNAME(x): #define END(x) .size x, . - x #elif defined(_WIN32) #ifndef _MSC_VER #define END(x) .end #define _START_ENTRY_WIN .text; _START_ENTRY #else #define END(x) end #define _START_ENTRY_WIN .code; _START_ENTRY #endif #define CNAME(csym) _##csym #define HIDENAME(asmsym) .asmsym #define _ENTRY(x) _START_ENTRY_WIN; \ .globl CNAME(x); .section .drectve; .ascii " -export:" #x; \ .section .text; .def CNAME(x); .scl 2; .type 32; .endef; CNAME(x): #endif #ifdef PROF #define ALTENTRY(x) _ENTRY(x); \ pushl %ebp; movl %esp,%ebp; \ call PIC_PLT(HIDENAME(mcount)); \ popl %ebp; \ jmp 9f #define ENTRY(x) _ENTRY(x); \ pushl %ebp; movl %esp,%ebp; \ call PIC_PLT(HIDENAME(mcount)); \ popl %ebp; \ 9: #else #define ALTENTRY(x) _ENTRY(x) #define ENTRY(x) _ENTRY(x) #endif #define RCSID(x) .text; .asciz x #undef __FBSDID #define __FBSDID(s) /* nothing */ #endif #endif /* !_MACHINE_ASM_H_ */ openlibm-0.5.0/i387/bsd_ieeefp.h000066400000000000000000000153311266752446200162720ustar00rootroot00000000000000/*- * Copyright (c) 2003 Peter Wemm. * Copyright (c) 1990 Andrew Moore, Talke Studio * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * from: @(#) ieeefp.h 1.0 (Berkeley) 9/23/93 * $FreeBSD$ */ #ifndef _MACHINE_IEEEFP_H_ #define _MACHINE_IEEEFP_H_ /* * Deprecated historical FPU control interface * * IEEE floating point type, constant and function definitions. * XXX: FP*FLD and FP*OFF are undocumented pollution. */ /* VBS #ifndef _SYS_CDEFS_H_ #error this file needs sys/cdefs.h as a prerequisite #endif */ /* * Rounding modes. */ typedef enum { FP_RN=0, /* round to nearest */ FP_RM, /* round down towards minus infinity */ FP_RP, /* round up towards plus infinity */ FP_RZ /* truncate */ } fp_rnd_t; /* * Precision (i.e., rounding precision) modes. */ typedef enum { FP_PS=0, /* 24 bit (single-precision) */ FP_PRS, /* reserved */ FP_PD, /* 53 bit (double-precision) */ FP_PE /* 64 bit (extended-precision) */ } fp_prec_t; #define fp_except_t int /* * Exception bit masks. */ #define FP_X_INV 0x01 /* invalid operation */ #define FP_X_DNML 0x02 /* denormal */ #define FP_X_DZ 0x04 /* zero divide */ #define FP_X_OFL 0x08 /* overflow */ #define FP_X_UFL 0x10 /* underflow */ #define FP_X_IMP 0x20 /* (im)precision */ #define FP_X_STK 0x40 /* stack fault */ /* * FPU control word bit-field masks. */ #define FP_MSKS_FLD 0x3f /* exception masks field */ #define FP_PRC_FLD 0x300 /* precision control field */ #define FP_RND_FLD 0xc00 /* rounding control field */ /* * FPU status word bit-field masks. */ #define FP_STKY_FLD 0x3f /* sticky flags field */ /* * FPU control word bit-field offsets (shift counts). */ #define FP_MSKS_OFF 0 /* exception masks offset */ #define FP_PRC_OFF 8 /* precision control offset */ #define FP_RND_OFF 10 /* rounding control offset */ /* * FPU status word bit-field offsets (shift counts). */ #define FP_STKY_OFF 0 /* sticky flags offset */ //VBS //#ifdef __GNUCLIKE_ASM #define __fldcw(addr) __asm __volatile("fldcw %0" : : "m" (*(addr))) #define __fldenv(addr) __asm __volatile("fldenv %0" : : "m" (*(addr))) #define __fnclex() __asm __volatile("fnclex") #define __fnstcw(addr) __asm __volatile("fnstcw %0" : "=m" (*(addr))) #define __fnstenv(addr) __asm __volatile("fnstenv %0" : "=m" (*(addr))) #define __fnstsw(addr) __asm __volatile("fnstsw %0" : "=m" (*(addr))) /* * Load the control word. Be careful not to trap if there is a currently * unmasked exception (ones that will become freshly unmasked are not a * problem). This case must be handled by a save/restore of the * environment or even of the full x87 state. Accessing the environment * is very inefficient, so only do it when necessary. */ static __inline void __fnldcw(unsigned short _cw, unsigned short _newcw) { struct { unsigned _cw; unsigned _other[6]; } _env; unsigned short _sw; if ((_cw & FP_MSKS_FLD) != FP_MSKS_FLD) { __fnstsw(&_sw); if (((_sw & ~_cw) & FP_STKY_FLD) != 0) { __fnstenv(&_env); _env._cw = _newcw; __fldenv(&_env); return; } } __fldcw(&_newcw); } static __inline fp_rnd_t fpgetround(void) { unsigned short _cw; __fnstcw(&_cw); return ((fp_rnd_t)((_cw & FP_RND_FLD) >> FP_RND_OFF)); } static __inline fp_rnd_t fpsetround(fp_rnd_t _m) { fp_rnd_t _p; unsigned short _cw, _newcw; __fnstcw(&_cw); _p = (fp_rnd_t)((_cw & FP_RND_FLD) >> FP_RND_OFF); _newcw = _cw & ~FP_RND_FLD; _newcw |= (_m << FP_RND_OFF) & FP_RND_FLD; __fnldcw(_cw, _newcw); return (_p); } //static __inline fp_prec_t DLLEXPORT fp_prec_t fpgetprec(void) { unsigned short _cw; __fnstcw(&_cw); return ((fp_prec_t)((_cw & FP_PRC_FLD) >> FP_PRC_OFF)); } //static __inline fp_prec_t DLLEXPORT fp_prec_t fpsetprec(fp_prec_t _m) { fp_prec_t _p; unsigned short _cw, _newcw; __fnstcw(&_cw); _p = (fp_prec_t)((_cw & FP_PRC_FLD) >> FP_PRC_OFF); _newcw = _cw & ~FP_PRC_FLD; _newcw |= (_m << FP_PRC_OFF) & FP_PRC_FLD; __fnldcw(_cw, _newcw); return (_p); } /* * Get or set the exception mask. * Note that the x87 mask bits are inverted by the API -- a mask bit of 1 * means disable for x87 and SSE, but for fp*mask() it means enable. */ static __inline fp_except_t fpgetmask(void) { unsigned short _cw; __fnstcw(&_cw); return ((~_cw & FP_MSKS_FLD) >> FP_MSKS_OFF); } static __inline fp_except_t fpsetmask(fp_except_t _m) { fp_except_t _p; unsigned short _cw, _newcw; __fnstcw(&_cw); _p = (~_cw & FP_MSKS_FLD) >> FP_MSKS_OFF; _newcw = _cw & ~FP_MSKS_FLD; _newcw |= (~_m << FP_MSKS_OFF) & FP_MSKS_FLD; __fnldcw(_cw, _newcw); return (_p); } static __inline fp_except_t fpgetsticky(void) { unsigned _ex; unsigned short _sw; __fnstsw(&_sw); _ex = (_sw & FP_STKY_FLD) >> FP_STKY_OFF; return ((fp_except_t)_ex); } static __inline fp_except_t fpresetsticky(fp_except_t _m) { struct { unsigned _cw; unsigned _sw; unsigned _other[5]; } _env; fp_except_t _p; _m &= FP_STKY_FLD >> FP_STKY_OFF; _p = fpgetsticky(); if ((_p & ~_m) == _p) return (_p); if ((_p & ~_m) == 0) { __fnclex(); return (_p); } __fnstenv(&_env); _env._sw &= ~_m; __fldenv(&_env); return (_p); } //#endif /* __GNUCLIKE_ASM */ #endif /* !_MACHINE_IEEEFP_H_ */ openlibm-0.5.0/i387/bsd_npx.h000066400000000000000000000127571266752446200156530ustar00rootroot00000000000000/*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * William Jolitz. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * from: @(#)npx.h 5.3 (Berkeley) 1/18/91 * $FreeBSD: src/sys/i386/include/npx.h,v 1.29.2.1 2006/07/01 00:57:55 davidxu Exp $ */ /* * 287/387 NPX Coprocessor Data Structures and Constants * W. Jolitz 1/90 */ #ifndef _MACHINE_NPX_H_ #define _MACHINE_NPX_H_ /* Environment information of floating point unit */ struct env87 { long en_cw; /* control word (16bits) */ long en_sw; /* status word (16bits) */ long en_tw; /* tag word (16bits) */ long en_fip; /* floating point instruction pointer */ unsigned short en_fcs; /* floating code segment selector */ unsigned short en_opcode; /* opcode last executed (11 bits ) */ long en_foo; /* floating operand offset */ long en_fos; /* floating operand segment selector */ }; /* Contents of each floating point accumulator */ struct fpacc87 { #ifdef dontdef /* too unportable */ unsigned long fp_mantlo; /* mantissa low (31:0) */ unsigned long fp_manthi; /* mantissa high (63:32) */ int fp_exp:15; /* exponent */ int fp_sgn:1; /* mantissa sign */ #else unsigned char fp_bytes[10]; #endif }; /* Floating point context */ struct save87 { struct env87 sv_env; /* floating point control/status */ struct fpacc87 sv_ac[8]; /* accumulator contents, 0-7 */ unsigned char sv_pad0[4]; /* padding for (now unused) saved status word */ /* * Bogus padding for emulators. Emulators should use their own * struct and arrange to store into this struct (ending here) * before it is inspected for ptracing or for core dumps. Some * emulators overwrite the whole struct. We have no good way of * knowing how much padding to leave. Leave just enough for the * GPL emulator's i387_union (176 bytes total). */ unsigned char sv_pad[64]; /* padding; used by emulators */ }; struct envxmm { uint16_t en_cw; /* control word (16bits) */ uint16_t en_sw; /* status word (16bits) */ uint16_t en_tw; /* tag word (16bits) */ uint16_t en_opcode; /* opcode last executed (11 bits ) */ uint32_t en_fip; /* floating point instruction pointer */ uint16_t en_fcs; /* floating code segment selector */ uint16_t en_pad0; /* padding */ uint32_t en_foo; /* floating operand offset */ uint16_t en_fos; /* floating operand segment selector */ uint16_t en_pad1; /* padding */ uint32_t en_mxcsr; /* SSE sontorol/status register */ uint32_t en_mxcsr_mask; /* valid bits in mxcsr */ }; /* Contents of each SSE extended accumulator */ struct xmmacc { unsigned char xmm_bytes[16]; }; struct savexmm { struct envxmm sv_env; struct { struct fpacc87 fp_acc; unsigned char fp_pad[6]; /* padding */ } sv_fp[8]; struct xmmacc sv_xmm[8]; unsigned char sv_pad[224]; } __attribute__((__aligned__(16))); union savefpu { struct save87 sv_87; struct savexmm sv_xmm; }; /* * The hardware default control word for i387's and later coprocessors is * 0x37F, giving: * * round to nearest * 64-bit precision * all exceptions masked. * * We modify the affine mode bit and precision bits in this to give: * * affine mode for 287's (if they work at all) (1 in bitfield 1<<12) * 53-bit precision (2 in bitfield 3<<8) * * 64-bit precision often gives bad results with high level languages * because it makes the results of calculations depend on whether * intermediate values are stored in memory or in FPU registers. */ #define __INITIAL_NPXCW__ 0x127F #define __INITIAL_MXCSR__ 0x1F80 #ifdef _KERNEL #define IO_NPX 0x0F0 /* Numeric Coprocessor */ #define IO_NPXSIZE 16 /* 80387/80487 NPX registers */ #define IRQ_NPX 13 /* full reset on some systems, NOP on others */ #define npx_full_reset() outb(IO_NPX + 1, 0) int npxdna(void); void npxdrop(void); void npxexit(struct thread *td); int npxformat(void); int npxgetregs(struct thread *td, union savefpu *addr); void npxinit(unsigned short control); void npxsave(union savefpu *addr); void npxsetregs(struct thread *td, union savefpu *addr); int npxtrap(void); #endif #endif /* !_MACHINE_NPX_H_ */openlibm-0.5.0/i387/e_exp.S000066400000000000000000000027331266752446200152620ustar00rootroot00000000000000/* * Written by: * J.T. Conklin (jtc@netbsd.org) * Public domain. */ #include /* e^x = 2^(x * log2(e)) */ ENTRY(exp) /* * If x is +-Inf, then the subtraction would give Inf-Inf = NaN. * Avoid this. Also avoid it if x is NaN for convenience. */ movl 8(%esp),%eax andl $0x7fffffff,%eax cmpl $0x7ff00000,%eax jae x_Inf_or_NaN fldl 4(%esp) /* * Extended precision is needed to reduce the maximum error from * hundreds of ulps to less than 1 ulp. Switch to it if necessary. * We may as well set the rounding mode to to-nearest and mask traps * if we switch. */ fstcw 4(%esp) movl 4(%esp),%eax andl $0x0300,%eax cmpl $0x0300,%eax /* RC == 0 && PC == 3? */ je 1f /* jump if mode is good */ movl $0x137f,8(%esp) fldcw 8(%esp) 1: fldl2e fmulp /* x * log2(e) */ fst %st(1) frndint /* int(x * log2(e)) */ fst %st(2) fsubrp /* fract(x * log2(e)) */ f2xm1 /* 2^(fract(x * log2(e))) - 1 */ fld1 faddp /* 2^(fract(x * log2(e))) */ fscale /* e^x */ fstp %st(1) je 1f fldcw 4(%esp) 1: ret x_Inf_or_NaN: /* * Return 0 if x is -Inf. Otherwise just return x; when x is Inf * this gives Inf, and when x is a NaN this gives the same result * as (x + x) (x quieted). */ cmpl $0xfff00000,8(%esp) jne x_not_minus_Inf cmpl $0,4(%esp) jne x_not_minus_Inf fldz ret x_not_minus_Inf: fldl 4(%esp) ret END(exp) // /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/e_fmod.S000066400000000000000000000006061266752446200154100ustar00rootroot00000000000000/* * Written by: * J.T. Conklin (jtc@netbsd.org) * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/e_fmod.S,v 1.11 2011/01/07 16:13:12 kib Exp $") ENTRY(fmod) fldl 12(%esp) fldl 4(%esp) 1: fprem fstsw %ax sahf jp 1b fstp %st(1) ret END(fmod) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/e_log.S000066400000000000000000000005251266752446200152440ustar00rootroot00000000000000/* * Written by: * J.T. Conklin (jtc@netbsd.org) * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/e_log.S,v 1.10 2011/01/07 16:13:12 kib Exp $") ENTRY(log) fldln2 fldl 4(%esp) fyl2x ret END(log) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/e_log10.S000066400000000000000000000005331266752446200154040ustar00rootroot00000000000000/* * Written by: * J.T. Conklin (jtc@netbsd.org) * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/e_log10.S,v 1.10 2011/01/07 16:13:12 kib Exp $") ENTRY(log10) fldlg2 fldl 4(%esp) fyl2x ret END(log10) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/e_log10f.S000066400000000000000000000006431266752446200155540ustar00rootroot00000000000000/* * Written by J.T. Conklin . * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/e_log10f.S,v 1.4 2011/01/07 16:13:12 kib Exp $"); /* RCSID("$NetBSD: e_log10f.S,v 1.1 1996/07/03 16:50:22 jtc Exp $") */ ENTRY(log10f) fldlg2 flds 4(%esp) fyl2x ret END(log10f) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/e_logf.S000066400000000000000000000006211266752446200154070ustar00rootroot00000000000000/* * Written by J.T. Conklin . * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/e_logf.S,v 1.3 2011/01/07 16:13:12 kib Exp $"); /* RCSID("$NetBSD: e_logf.S,v 1.2 1996/07/06 00:15:45 jtc Exp $") */ ENTRY(logf) fldln2 flds 4(%esp) fyl2x ret /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/e_remainder.S000066400000000000000000000006261266752446200164330ustar00rootroot00000000000000/* * Written by: * J.T. Conklin (jtc@netbsd.org) * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/e_remainder.S,v 1.11 2011/01/07 16:13:12 kib Exp $") ENTRY(remainder) fldl 12(%esp) fldl 4(%esp) 1: fprem1 fstsw %ax sahf jp 1b fstp %st(1) ret END(remainder) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/e_remainderf.S000066400000000000000000000007411266752446200165770ustar00rootroot00000000000000/* * Written by J.T. Conklin . * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/e_remainderf.S,v 1.4 2011/01/07 16:13:12 kib Exp $"); /* RCSID("$NetBSD: e_remainderf.S,v 1.2 1995/05/08 23:49:47 jtc Exp $") */ ENTRY(remainderf) flds 8(%esp) flds 4(%esp) 1: fprem1 fstsw %ax sahf jp 1b fstp %st(1) ret END(remainderf) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/e_remainderl.S000066400000000000000000000006111266752446200166010ustar00rootroot00000000000000/* * Written by: * J.T. Conklin (jtc@netbsd.org) * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/e_remainderl.S,v 1.2 2011/01/07 16:13:12 kib Exp $") ENTRY(remainderl) fldt 16(%esp) fldt 4(%esp) 1: fprem1 fstsw %ax sahf jp 1b fstp %st(1) ret /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/e_sqrt.S000066400000000000000000000005201266752446200154470ustar00rootroot00000000000000/* * Written by: * J.T. Conklin (jtc@netbsd.org) * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/e_sqrt.S,v 1.10 2011/01/07 16:13:12 kib Exp $") ENTRY(sqrt) fldl 4(%esp) fsqrt ret END(sqrt) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/e_sqrtf.S000066400000000000000000000006271266752446200156250ustar00rootroot00000000000000/* * Written by J.T. Conklin . * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/e_sqrtf.S,v 1.4 2011/01/07 16:13:12 kib Exp $"); /* RCSID("$NetBSD: e_sqrtf.S,v 1.2 1995/05/08 23:50:14 jtc Exp $") */ ENTRY(sqrtf) flds 4(%esp) fsqrt ret END(sqrtf) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/e_sqrtl.S000066400000000000000000000005071266752446200156300ustar00rootroot00000000000000/* * Written by: * J.T. Conklin (jtc@netbsd.org) * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/e_sqrtl.S,v 1.3 2011/01/07 16:13:12 kib Exp $") ENTRY(sqrtl) fldt 4(%esp) fsqrt ret /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/fenv.c000066400000000000000000000122321266752446200151330ustar00rootroot00000000000000/*- * Copyright (c) 2004-2005 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/lib/msun/i387/fenv.c,v 1.8 2011/10/21 06:25:31 das Exp $ */ #include "cdefs-compat.h" #include "types-compat.h" #include "math_private.h" #include "i387/bsd_npx.h" #define __fenv_static #include #ifdef __GNUC_GNU_INLINE__ #error "This file must be compiled with C99 'inline' semantics" #endif const fenv_t __fe_dfl_env = { __INITIAL_NPXCW__, 0x0000, 0x0000, 0x1f80, 0xffffffff, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff } }; enum __sse_support __has_sse = #ifdef __SSE__ __SSE_YES; #else __SSE_UNK; #endif #define getfl(x) __asm __volatile("pushfl\n\tpopl %0" : "=mr" (*(x))) #define setfl(x) __asm __volatile("pushl %0\n\tpopfl" : : "g" (x)) #define cpuid_dx(x) __asm __volatile("pushl %%ebx\n\tmovl $1, %%eax\n\t" \ "cpuid\n\tpopl %%ebx" \ : "=d" (*(x)) : : "eax", "ecx") /* * Test for SSE support on this processor. We need to do this because * we need to use ldmxcsr/stmxcsr to get correct results if any part * of the program was compiled to use SSE floating-point, but we can't * use SSE on older processors. */ int __test_sse(void) { int flag, nflag; int dx_features; /* Am I a 486? */ getfl(&flag); nflag = flag ^ 0x200000; setfl(nflag); getfl(&nflag); if (flag != nflag) { /* Not a 486, so CPUID should work. */ cpuid_dx(&dx_features); if (dx_features & 0x2000000) { __has_sse = __SSE_YES; return (1); } } __has_sse = __SSE_NO; return (0); } extern inline DLLEXPORT int feclearexcept(int __excepts); extern inline DLLEXPORT int fegetexceptflag(fexcept_t *__flagp, int __excepts); DLLEXPORT int fesetexceptflag(const fexcept_t *flagp, int excepts) { fenv_t env; uint32_t mxcsr; __fnstenv(&env); env.__status &= ~excepts; env.__status |= *flagp & excepts; __fldenv(env); if (__HAS_SSE()) { __stmxcsr(&mxcsr); mxcsr &= ~excepts; mxcsr |= *flagp & excepts; __ldmxcsr(mxcsr); } return (0); } DLLEXPORT int feraiseexcept(int excepts) { fexcept_t ex = excepts; fesetexceptflag(&ex, excepts); __fwait(); return (0); } extern inline DLLEXPORT int fetestexcept(int __excepts); extern inline DLLEXPORT int fegetround(void); extern inline DLLEXPORT int fesetround(int __round); int fegetenv(fenv_t *envp) { uint32_t mxcsr; __fnstenv(envp); /* * fnstenv masks all exceptions, so we need to restore * the old control word to avoid this side effect. */ __fldcw(envp->__control); if (__HAS_SSE()) { __stmxcsr(&mxcsr); __set_mxcsr(*envp, mxcsr); } return (0); } int feholdexcept(fenv_t *envp) { uint32_t mxcsr; __fnstenv(envp); __fnclex(); if (__HAS_SSE()) { __stmxcsr(&mxcsr); __set_mxcsr(*envp, mxcsr); mxcsr &= ~FE_ALL_EXCEPT; mxcsr |= FE_ALL_EXCEPT << _SSE_EMASK_SHIFT; __ldmxcsr(mxcsr); } return (0); } extern inline DLLEXPORT int fesetenv(const fenv_t *__envp); DLLEXPORT int feupdateenv(const fenv_t *envp) { uint32_t mxcsr; uint16_t status; __fnstsw(&status); if (__HAS_SSE()) __stmxcsr(&mxcsr); else mxcsr = 0; fesetenv(envp); feraiseexcept((mxcsr | status) & FE_ALL_EXCEPT); return (0); } int feenableexcept(int mask) { uint32_t mxcsr, omask; uint16_t control; mask &= FE_ALL_EXCEPT; __fnstcw(&control); if (__HAS_SSE()) __stmxcsr(&mxcsr); else mxcsr = 0; omask = ~(control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT; control &= ~mask; __fldcw(control); if (__HAS_SSE()) { mxcsr &= ~(mask << _SSE_EMASK_SHIFT); __ldmxcsr(mxcsr); } return (omask); } int fedisableexcept(int mask) { uint32_t mxcsr, omask; uint16_t control; mask &= FE_ALL_EXCEPT; __fnstcw(&control); if (__HAS_SSE()) __stmxcsr(&mxcsr); else mxcsr = 0; omask = ~(control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT; control |= mask; __fldcw(control); if (__HAS_SSE()) { mxcsr |= mask << _SSE_EMASK_SHIFT; __ldmxcsr(mxcsr); } return (omask); } openlibm-0.5.0/i387/invtrig.c000066400000000000000000000102271266752446200156610ustar00rootroot00000000000000/*- * Copyright (c) 2008 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/invtrig.c,v 1.1 2008/08/02 03:56:22 das Exp $"); #include #define STRUCT_DECLS #include "invtrig.h" /* * asinl() and acosl() */ const LONGDOUBLE pS0 = { 0xaaaaaaaaaaaaaaa8ULL, 0x3ffcU }, /* 1.66666666666666666631e-01L */ pS1 = { 0xd5271b6699b48bfaULL, 0xbffdU }, /* -4.16313987993683104320e-01L */ pS2 = { 0xbcf67ca9e9f669cfULL, 0x3ffdU }, /* 3.69068046323246813704e-01L */ pS3 = { 0x8b7baa3d15f9830dULL, 0xbffcU }, /* -1.36213932016738603108e-01L */ pS4 = { 0x92154b093a3bff1cULL, 0x3ff9U }, /* 1.78324189708471965733e-02L */ pS5 = { 0xe5dd76401964508cULL, 0xbff2U }, /* -2.19216428382605211588e-04L */ pS6 = { 0xee69c5b0fdb76951ULL, 0xbfedU }, /* -7.10526623669075243183e-06L */ qS1 = { 0xbcaa2159c01436a0ULL, 0xc000U }, /* -2.94788392796209867269e+00L */ qS2 = { 0xd17a73d1e1564c29ULL, 0x4000U }, /* 3.27309890266528636716e+00L */ qS3 = { 0xd767e411c9cf4c2cULL, 0xbfffU }, /* -1.68285799854822427013e+00L */ qS4 = { 0xc809c0dfb9b0d0b7ULL, 0x3ffdU }, /* 3.90699412641738801874e-01L */ qS5 = { 0x80c3a2197c8ced57ULL, 0xbffaU }; /* -3.14365703596053263322e-02L */ /* * atanl() */ const LONGDOUBLE atanhi[] = { { 0xed63382b0dda7b45ULL, 0x3ffdU }, /* 4.63647609000806116202e-01L */ { 0xc90fdaa22168c235ULL, 0x3ffeU }, /* 7.85398163397448309628e-01L */ { 0xfb985e940fb4d900ULL, 0x3ffeU }, /* 9.82793723247329067960e-01L */ { 0xc90fdaa22168c235ULL, 0x3fffU }, /* 1.57079632679489661926e+00L */ }; const LONGDOUBLE atanlo[] = { { 0xdfc88bd978751a07ULL, 0x3fbcU }, /* 1.18469937025062860669e-20L */ { 0xece675d1fc8f8cbbULL, 0xbfbcU }, /* -1.25413940316708300586e-20L */ { 0xf10f5e197793c283ULL, 0x3fbdU }, /* 2.55232234165405176172e-20L */ { 0xece675d1fc8f8cbbULL, 0xbfbdU }, /* -2.50827880633416601173e-20L */ }; const LONGDOUBLE aT[] = { { 0xaaaaaaaaaaaaaa9fULL, 0x3ffdU }, /* 3.33333333333333333017e-01L */ { 0xcccccccccccc62bcULL, 0xbffcU }, /* -1.99999999999999632011e-01L */ { 0x9249249248b81e3fULL, 0x3ffcU }, /* 1.42857142857046531280e-01L */ { 0xe38e38e3316f3de5ULL, 0xbffbU }, /* -1.11111111100562372733e-01L */ { 0xba2e8b8dc280726aULL, 0x3ffbU }, /* 9.09090902935647302252e-02L */ { 0x9d89d5b4c6847ec4ULL, 0xbffbU }, /* -7.69230552476207730353e-02L */ { 0x8888461d3099c677ULL, 0x3ffbU }, /* 6.66661718042406260546e-02L */ { 0xf0e8ee0f5328dc29ULL, 0xbffaU }, /* -5.88158892835030888692e-02L */ { 0xd73ea84d24bae54aULL, 0x3ffaU }, /* 5.25499891539726639379e-02L */ { 0xc08fa381dcd9213aULL, 0xbffaU }, /* -4.70119845393155721494e-02L */ { 0xa54a26f4095f2a3aULL, 0x3ffaU }, /* 4.03539201366454414072e-02L */ { 0xeea2d8d059ef3ad6ULL, 0xbff9U }, /* -2.91303858419364158725e-02L */ { 0xcc82292ab894b051ULL, 0x3ff8U }, /* 1.24822046299269234080e-02L */ }; const LONGDOUBLE pi_lo = { 0xece675d1fc8f8cbbULL, 0xbfbeU }; /* -5.01655761266833202345e-20L */ openlibm-0.5.0/i387/s_ceil.S000066400000000000000000000010701266752446200154110ustar00rootroot00000000000000/* * Written by: * J.T. Conklin (jtc@netbsd.org) * Public domain. */ #include ENTRY(ceil) pushl %ebp movl %esp,%ebp subl $8,%esp fstcw -4(%ebp) /* store fpu control word */ movw -4(%ebp),%dx orw $0x0800,%dx /* round towards +oo */ andw $0xfbff,%dx movw %dx,-8(%ebp) fldcw -8(%ebp) /* load modfied control word */ fldl 8(%ebp); /* round */ frndint fldcw -4(%ebp) /* restore original control word */ leave ret END(ceil) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_ceilf.S000066400000000000000000000013221266752446200155570ustar00rootroot00000000000000/* * Written by J.T. Conklin . * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_ceilf.S,v 1.4 2011/01/07 16:13:12 kib Exp $"); /* RCSID("$NetBSD: s_ceilf.S,v 1.3 1995/05/08 23:52:44 jtc Exp $") */ ENTRY(ceilf) pushl %ebp movl %esp,%ebp subl $8,%esp fstcw -4(%ebp) /* store fpu control word */ movw -4(%ebp),%dx orw $0x0800,%dx /* round towards +oo */ andw $0xfbff,%dx movw %dx,-8(%ebp) fldcw -8(%ebp) /* load modfied control word */ flds 8(%ebp); /* round */ frndint fldcw -4(%ebp) /* restore original control word */ leave ret END(ceilf) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_ceill.S000066400000000000000000000012311266752446200155640ustar00rootroot00000000000000/* * Based on code written by J.T. Conklin . * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_ceill.S,v 1.3 2011/01/07 16:13:12 kib Exp $") ENTRY(ceill) pushl %ebp movl %esp,%ebp subl $8,%esp fstcw -4(%ebp) /* store fpu control word */ movw -4(%ebp),%dx orw $0x0800,%dx /* round towards +oo */ andw $0xfbff,%dx movw %dx,-8(%ebp) fldcw -8(%ebp) /* load modfied control word */ fldt 8(%ebp) /* round */ frndint fldcw -4(%ebp) /* restore original control word */ leave ret END(ceill) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_copysign.S000066400000000000000000000007131266752446200163330ustar00rootroot00000000000000/* * Written by: * J.T. Conklin (jtc@netbsd.org) * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_copysign.S,v 1.9 2011/01/07 16:13:12 kib Exp $") ENTRY(copysign) movl 16(%esp),%edx andl $0x80000000,%edx movl 8(%esp),%eax andl $0x7fffffff,%eax orl %edx,%eax movl %eax,8(%esp) fldl 4(%esp) ret END(copysign) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_copysignf.S000066400000000000000000000010261266752446200164770ustar00rootroot00000000000000/* * Written by J.T. Conklin . * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_copysignf.S,v 1.3 2011/01/07 16:13:12 kib Exp $"); /* RCSID("$NetBSD: s_copysignf.S,v 1.3 1995/05/08 23:53:25 jtc Exp $") */ ENTRY(copysignf) movl 8(%esp),%edx andl $0x80000000,%edx movl 4(%esp),%eax andl $0x7fffffff,%eax orl %edx,%eax movl %eax,4(%esp) flds 4(%esp) ret END(copysignf) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_copysignl.S000066400000000000000000000007231266752446200165100ustar00rootroot00000000000000/* * Based on code written by J.T. Conklin . * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_copysignl.S,v 1.3 2011/01/07 16:13:12 kib Exp $") ENTRY(copysignl) movl 24(%esp),%edx andl $0x8000,%edx movl 12(%esp),%eax andl $0x7fff,%eax orl %edx,%eax movl %eax,12(%esp) fldt 4(%esp) ret END(copysignl) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_cos.S000066400000000000000000000007331266752446200152660ustar00rootroot00000000000000/* * Written by: * J.T. Conklin (jtc@netbsd.org) * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_cos.S,v 1.9 2011/01/07 16:13:12 kib Exp $") ENTRY(cos) fldl 4(%esp) fcos fnstsw %ax andw $0x400,%ax jnz 1f ret 1: fldpi fadd %st(0) fxch %st(1) 2: fprem1 fnstsw %ax andw $0x400,%ax jnz 2b fstp %st(1) fcos ret END(cos) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_floor.S000066400000000000000000000012161266752446200156200ustar00rootroot00000000000000/* * Written by: * J.T. Conklin (jtc@netbsd.org) * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_floor.S,v 1.10 2011/01/07 16:13:12 kib Exp $") ENTRY(floor) pushl %ebp movl %esp,%ebp subl $8,%esp fstcw -4(%ebp) /* store fpu control word */ movw -4(%ebp),%dx orw $0x0400,%dx /* round towards -oo */ andw $0xf7ff,%dx movw %dx,-8(%ebp) fldcw -8(%ebp) /* load modfied control word */ fldl 8(%ebp); /* round */ frndint fldcw -4(%ebp) /* restore original control word */ leave ret END(floor) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_floorf.S000066400000000000000000000013261266752446200157700ustar00rootroot00000000000000/* * Written by J.T. Conklin . * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_floorf.S,v 1.4 2011/01/07 16:13:12 kib Exp $"); /* RCSID("$NetBSD: s_floorf.S,v 1.3 1995/05/09 00:04:32 jtc Exp $") */ ENTRY(floorf) pushl %ebp movl %esp,%ebp subl $8,%esp fstcw -4(%ebp) /* store fpu control word */ movw -4(%ebp),%dx orw $0x0400,%dx /* round towards -oo */ andw $0xf7ff,%dx movw %dx,-8(%ebp) fldcw -8(%ebp) /* load modfied control word */ flds 8(%ebp); /* round */ frndint fldcw -4(%ebp) /* restore original control word */ leave ret END(floorf) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_floorl.S000066400000000000000000000012331266752446200157730ustar00rootroot00000000000000/* * Based on code written by J.T. Conklin . * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_floorl.S,v 1.3 2011/01/07 16:13:12 kib Exp $") ENTRY(floorl) pushl %ebp movl %esp,%ebp subl $8,%esp fstcw -4(%ebp) /* store fpu control word */ movw -4(%ebp),%dx orw $0x0400,%dx /* round towards -oo */ andw $0xf7ff,%dx movw %dx,-8(%ebp) fldcw -8(%ebp) /* load modfied control word */ fldt 8(%ebp) /* round */ frndint fldcw -4(%ebp) /* restore original control word */ leave ret END(floorl) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_llrint.S000066400000000000000000000032311266752446200160020ustar00rootroot00000000000000/*- * Copyright (c) 2005 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_llrint.S,v 1.3 2011/01/07 16:13:12 kib Exp $"); ENTRY(llrint) fldl 4(%esp) subl $8,%esp fistpll (%esp) popl %eax popl %edx ret END(llrint) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_llrintf.S000066400000000000000000000032321266752446200161510ustar00rootroot00000000000000/*- * Copyright (c) 2005 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_llrintf.S,v 1.3 2011/01/07 16:13:12 kib Exp $") ENTRY(llrintf) flds 4(%esp) subl $8,%esp fistpll (%esp) popl %eax popl %edx ret END(llrintf) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_llrintl.S000066400000000000000000000032171266752446200161620ustar00rootroot00000000000000/*- * Copyright (c) 2005 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_llrintl.S,v 1.2 2011/01/07 16:13:12 kib Exp $"); ENTRY(llrintl) fldt 4(%esp) subl $8,%esp fistpll (%esp) popl %eax popl %edx ret /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_logb.S000066400000000000000000000005341266752446200154240ustar00rootroot00000000000000/* * Written by: * J.T. Conklin (jtc@netbsd.org) * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_logb.S,v 1.10 2011/01/07 16:13:12 kib Exp $") ENTRY(logb) fldl 4(%esp) fxtract fstp %st ret END(logb) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_logbf.S000066400000000000000000000006431266752446200155730ustar00rootroot00000000000000/* * Written by J.T. Conklin . * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_logbf.S,v 1.3 2011/01/07 16:13:12 kib Exp $"); /* RCSID("$NetBSD: s_logbf.S,v 1.3 1995/05/09 00:15:12 jtc Exp $") */ ENTRY(logbf) flds 4(%esp) fxtract fstp %st ret END(logbf) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_logbl.S000066400000000000000000000005231266752446200155760ustar00rootroot00000000000000/* * Written by: * J.T. Conklin (jtc@netbsd.org) * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_logbl.S,v 1.3 2011/01/07 16:13:12 kib Exp $") ENTRY(logbl) fldt 4(%esp) fxtract fstp %st ret /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_lrint.S000066400000000000000000000032121266752446200156250ustar00rootroot00000000000000/*- * Copyright (c) 2005 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_lrint.S,v 1.3 2011/01/07 16:13:12 kib Exp $"); ENTRY(lrint) fldl 4(%esp) subl $4,%esp fistpl (%esp) popl %eax ret END(lrint) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_lrintf.S000066400000000000000000000032131266752446200157740ustar00rootroot00000000000000/*- * Copyright (c) 2005 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_lrintf.S,v 1.3 2011/01/07 16:13:12 kib Exp $") ENTRY(lrintf) flds 4(%esp) subl $4,%esp fistpl (%esp) popl %eax ret END(lrintf) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_lrintl.S000066400000000000000000000032011266752446200157770ustar00rootroot00000000000000/*- * Copyright (c) 2008 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_lrintl.S,v 1.2 2011/01/07 16:13:12 kib Exp $"); ENTRY(lrintl) fldt 4(%esp) subl $4,%esp fistpl (%esp) popl %eax ret /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_remquo.S000066400000000000000000000043041266752446200160100ustar00rootroot00000000000000/*- * Copyright (c) 2005 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Based on public-domain remainder routine by J.T. Conklin . */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_remquo.S,v 1.3 2011/01/07 16:13:12 kib Exp $"); ENTRY(remquo) fldl 12(%esp) fldl 4(%esp) 1: fprem1 fstsw %ax sahf jp 1b fstp %st(1) /* Extract the three low-order bits of the quotient from C0,C3,C1. */ shrl $6,%eax movl %eax,%ecx andl $0x108,%eax rorl $7,%eax orl %eax,%ecx roll $4,%eax orl %ecx,%eax andl $7,%eax /* Negate the quotient bits if x*y<0. Avoid using an unpredictable branch. */ movl 16(%esp),%ecx xorl 8(%esp),%ecx sarl $16,%ecx sarl $16,%ecx xorl %ecx,%eax andl $1,%ecx addl %ecx,%eax /* Store the quotient and return. */ movl 20(%esp),%ecx movl %eax,(%ecx) ret END(remquo) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_remquof.S000066400000000000000000000043051266752446200161570ustar00rootroot00000000000000/*- * Copyright (c) 2005 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Based on public-domain remainder routine by J.T. Conklin . */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_remquof.S,v 1.3 2011/01/07 16:13:12 kib Exp $"); ENTRY(remquof) flds 8(%esp) flds 4(%esp) 1: fprem1 fstsw %ax sahf jp 1b fstp %st(1) /* Extract the three low-order bits of the quotient from C0,C3,C1. */ shrl $6,%eax movl %eax,%ecx andl $0x108,%eax rorl $7,%eax orl %eax,%ecx roll $4,%eax orl %ecx,%eax andl $7,%eax /* Negate the quotient bits if x*y<0. Avoid using an unpredictable branch. */ movl 8(%esp),%ecx xorl 4(%esp),%ecx sarl $16,%ecx sarl $16,%ecx xorl %ecx,%eax andl $1,%ecx addl %ecx,%eax /* Store the quotient and return. */ movl 12(%esp),%ecx movl %eax,(%ecx) ret END(remquof) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_remquol.S000066400000000000000000000043201266752446200161620ustar00rootroot00000000000000/*- * Copyright (c) 2005-2008 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Based on public-domain remainder routine by J.T. Conklin . */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_remquol.S,v 1.2 2011/01/07 16:13:12 kib Exp $"); ENTRY(remquol) fldt 16(%esp) fldt 4(%esp) 1: fprem1 fstsw %ax sahf jp 1b fstp %st(1) /* Extract the three low-order bits of the quotient from C0,C3,C1. */ shrl $6,%eax movl %eax,%ecx andl $0x108,%eax rorl $7,%eax orl %eax,%ecx roll $4,%eax orl %ecx,%eax andl $7,%eax /* Negate the quotient bits if x*y<0. Avoid using an unpredictable branch. */ movl 24(%esp),%ecx xorl 12(%esp),%ecx movsx %cx,%ecx sarl $16,%ecx sarl $16,%ecx xorl %ecx,%eax andl $1,%ecx addl %ecx,%eax /* Store the quotient and return. */ movl 28(%esp),%ecx movl %eax,(%ecx) ret /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_rint.S000066400000000000000000000005211266752446200154510ustar00rootroot00000000000000/* * Written by: * J.T. Conklin (jtc@netbsd.org) * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_rint.S,v 1.9 2011/01/07 16:13:12 kib Exp $") ENTRY(rint) fldl 4(%esp) frndint ret END(rint) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_rintf.S000066400000000000000000000006311266752446200156210ustar00rootroot00000000000000/* * Written by J.T. Conklin . * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_rintf.S,v 1.3 2011/01/07 16:13:12 kib Exp $"); /* RCSID("$NetBSD: s_rintf.S,v 1.3 1995/05/09 00:17:22 jtc Exp $") */ ENTRY(rintf) flds 4(%esp) frndint ret END(rintf) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_rintl.S000066400000000000000000000005111266752446200156240ustar00rootroot00000000000000/* * Written by: * J.T. Conklin (jtc@netbsd.org) * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_rintl.S,v 1.3 2011/01/07 16:13:12 kib Exp $") ENTRY(rintl) fldt 4(%esp) frndint ret /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_scalbn.S000066400000000000000000000006501266752446200157420ustar00rootroot00000000000000/* * Written by: * J.T. Conklin (jtc@netbsd.org) * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_scalbn.S,v 1.10 2011/01/07 16:13:12 kib Exp $") ENTRY(scalbn) fildl 12(%esp) fldl 4(%esp) fscale fstp %st(1) ret END(scalbn) .globl CNAME(ldexp) .set CNAME(ldexp),CNAME(scalbn) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_scalbnf.S000066400000000000000000000010361266752446200161070ustar00rootroot00000000000000/* * Written by J.T. Conklin . * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_scalbnf.S,v 1.4 2011/01/07 16:13:12 kib Exp $"); /* RCSID("$NetBSD: s_scalbnf.S,v 1.4 1999/01/02 05:15:40 kristerw Exp $") */ ENTRY(scalbnf) fildl 8(%esp) flds 4(%esp) fscale fstp %st(1) /* bug fix for fp stack overflow */ ret END(scalbnf) .globl CNAME(ldexpf) .set CNAME(ldexpf),CNAME(scalbnf) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_scalbnl.S000066400000000000000000000007721266752446200161230ustar00rootroot00000000000000/* * Written by J.T. Conklin . * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_scalbnl.S,v 1.3 2011/01/07 16:13:12 kib Exp $"); /* RCSID("$NetBSD: s_scalbnf.S,v 1.4 1999/01/02 05:15:40 kristerw Exp $") */ ENTRY(scalbnl) fildl 16(%esp) fldt 4(%esp) fscale fstp %st(1) ret END(scalbnl) .globl CNAME(ldexpl) .set CNAME(ldexpl),CNAME(scalbnl) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_sin.S000066400000000000000000000007321266752446200152720ustar00rootroot00000000000000/* * Written by: * J.T. Conklin (jtc@netbsd.org) * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_sin.S,v 1.9 2011/01/07 16:13:12 kib Exp $") ENTRY(sin) fldl 4(%esp) fsin fnstsw %ax andw $0x400,%ax jnz 1f ret 1: fldpi fadd %st(0) fxch %st(1) 2: fprem1 fnstsw %ax andw $0x400,%ax jnz 2b fstp %st(1) fsin ret END(sin) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_tan.S000066400000000000000000000007651266752446200152710ustar00rootroot00000000000000/* * Written by: * J.T. Conklin (jtc@netbsd.org) * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_tan.S,v 1.9 2011/01/07 16:13:12 kib Exp $") ENTRY(tan) fldl 4(%esp) fptan fnstsw %ax andw $0x400,%ax jnz 1f fstp %st(0) ret 1: fldpi fadd %st(0) fxch %st(1) 2: fprem1 fstsw %ax andw $0x400,%ax jnz 2b fstp %st(1) fptan fstp %st(0) ret END(tan) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_trunc.S000066400000000000000000000012061266752446200156310ustar00rootroot00000000000000/* * Based on code written by J.T. Conklin . * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_trunc.S,v 1.3 2011/01/07 16:13:12 kib Exp $") ENTRY(trunc) pushl %ebp movl %esp,%ebp subl $8,%esp fstcw -4(%ebp) /* store fpu control word */ movw -4(%ebp),%dx orw $0x0c00,%dx /* round towards -oo */ movw %dx,-8(%ebp) fldcw -8(%ebp) /* load modfied control word */ fldl 8(%ebp) /* round */ frndint fldcw -4(%ebp) /* restore original control word */ leave ret END(trunc) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_truncf.S000066400000000000000000000012111266752446200157730ustar00rootroot00000000000000/* * Based on code written by J.T. Conklin . * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_truncf.S,v 1.4 2011/01/07 16:13:12 kib Exp $") ENTRY(truncf) pushl %ebp movl %esp,%ebp subl $8,%esp fstcw -4(%ebp) /* store fpu control word */ movw -4(%ebp),%dx orw $0x0c00,%dx /* round towards -oo */ movw %dx,-8(%ebp) fldcw -8(%ebp) /* load modfied control word */ flds 8(%ebp) /* round */ frndint fldcw -4(%ebp) /* restore original control word */ leave ret END(truncf) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/i387/s_truncl.S000066400000000000000000000012111266752446200160010ustar00rootroot00000000000000/* * Based on code written by J.T. Conklin . * Public domain. */ #include //__FBSDID("$FreeBSD: src/lib/msun/i387/s_truncl.S,v 1.3 2011/01/07 16:13:12 kib Exp $") ENTRY(truncl) pushl %ebp movl %esp,%ebp subl $8,%esp fstcw -4(%ebp) /* store fpu control word */ movw -4(%ebp),%dx orw $0x0c00,%dx /* round towards -oo */ movw %dx,-8(%ebp) fldcw -8(%ebp) /* load modfied control word */ fldt 8(%ebp) /* round */ frndint fldcw -4(%ebp) /* restore original control word */ leave ret END(truncl) /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif openlibm-0.5.0/include/000077500000000000000000000000001266752446200147625ustar00rootroot00000000000000openlibm-0.5.0/include/openlibm.h000066400000000000000000000002251266752446200167370ustar00rootroot00000000000000#ifndef OPENLIBM_H #define OPENLIBM_H #include #include #include #endif /* !OPENLIBM_H */ openlibm-0.5.0/include/openlibm_complex.h000066400000000000000000000135601266752446200204740ustar00rootroot00000000000000/* $OpenBSD: complex.h,v 1.5 2014/03/16 18:38:30 guenther Exp $ */ /* * Copyright (c) 2008 Martynas Venckus * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifdef OPENLIBM_USE_HOST_COMPLEX_H #include #else /* !OPENLIBM_USE_HOST_COMPLEX_H */ #ifndef OPENLIBM_COMPLEX_H #define OPENLIBM_COMPLEX_H #define complex _Complex #define _Complex_I 1.0fi #define I _Complex_I /* * Macros that can be used to construct complex values. * * The C99 standard intends x+I*y to be used for this, but x+I*y is * currently unusable in general since gcc introduces many overflow, * underflow, sign and efficiency bugs by rewriting I*y as * (0.0+I)*(y+0.0*I) and laboriously computing the full complex product. * In particular, I*Inf is corrupted to NaN+I*Inf, and I*-0 is corrupted * to -0.0+I*0.0. * * In C11, a CMPLX(x,y) macro was added to circumvent this limitation, * and gcc 4.7 added a __builtin_complex feature to simplify implementation * of CMPLX in libc, so we can take advantage of these features if they * are available. Clang simply allows complex values to be constructed * using a compound literal. * * If __builtin_complex is not available, resort to using inline * functions instead. These can unfortunately not be used to construct * compile-time constants. * * C99 specifies that complex numbers have the same representation as * an array of two elements, where the first element is the real part * and the second element is the imaginary part. */ #ifdef __clang__ # define CMPLXF(x, y) ((float complex){x, y}) # define CMPLX(x, y) ((double complex){x, y}) # define CMPLXL(x, y) ((long double complex){x, y}) #elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__INTEL_COMPILER) # define CMPLXF(x,y) __builtin_complex ((float) (x), (float) (y)) # define CMPLX(x,y) __builtin_complex ((double) (x), (double) (y)) # define CMPLXL(x,y) __builtin_complex ((long double) (x), (long double) (y)) #else static inline float complex CMPLXF(float x, float y) { union { float a[2]; float complex f; } z = {{ x, y }}; return (z.f); } static inline double complex CMPLX(double x, double y) { union { double a[2]; double complex f; } z = {{ x, y }}; return (z.f); } static inline long double complex CMPLXL(long double x, long double y) { union { long double a[2]; long double complex f; } z = {{ x, y }}; return (z.f); } #endif /* * Double versions of C99 functions */ double complex cacos(double complex); double complex casin(double complex); double complex catan(double complex); double complex ccos(double complex); double complex csin(double complex); double complex ctan(double complex); double complex cacosh(double complex); double complex casinh(double complex); double complex catanh(double complex); double complex ccosh(double complex); double complex csinh(double complex); double complex ctanh(double complex); double complex cexp(double complex); double complex clog(double complex); double cabs(double complex); double complex cpow(double complex, double complex); double complex csqrt(double complex); double carg(double complex); double cimag(double complex); double complex conj(double complex); double complex cproj(double complex); double creal(double complex); /* * Float versions of C99 functions */ float complex cacosf(float complex); float complex casinf(float complex); float complex catanf(float complex); float complex ccosf(float complex); float complex csinf(float complex); float complex ctanf(float complex); float complex cacoshf(float complex); float complex casinhf(float complex); float complex catanhf(float complex); float complex ccoshf(float complex); float complex csinhf(float complex); float complex ctanhf(float complex); float complex cexpf(float complex); float complex clogf(float complex); float cabsf(float complex); float complex cpowf(float complex, float complex); float complex csqrtf(float complex); float cargf(float complex); float cimagf(float complex); float complex conjf(float complex); float complex cprojf(float complex); float crealf(float complex); /* * Long double versions of C99 functions */ long double complex cacosl(long double complex); long double complex casinl(long double complex); long double complex catanl(long double complex); long double complex ccosl(long double complex); long double complex csinl(long double complex); long double complex ctanl(long double complex); long double complex cacoshl(long double complex); long double complex casinhl(long double complex); long double complex catanhl(long double complex); long double complex ccoshl(long double complex); long double complex csinhl(long double complex); long double complex ctanhl(long double complex); long double complex cexpl(long double complex); long double complex clogl(long double complex); long double cabsl(long double complex); long double complex cpowl(long double complex, long double complex); long double complex csqrtl(long double complex); long double cargl(long double complex); long double cimagl(long double complex); long double complex conjl(long double complex); long double complex cprojl(long double complex); long double creall(long double complex); #endif /* !OPENLIBM_COMPLEX_H */ #endif /* OPENLIBM_USE_HOST_COMPLEX_H */ openlibm-0.5.0/include/openlibm_fenv.h000066400000000000000000000006201266752446200177540ustar00rootroot00000000000000#ifdef OPENLIBM_USE_HOST_FENV_H #include #else /* !OPENLIBM_USE_HOST_FENV_H */ #if defined(__arm__) #include #elif defined(__x86_64__) #include #elif defined(__i386__) #include #elif defined(__powerpc__) #include #else #error "Unsupported platform" #endif #endif /* OPENLIBM_USE_HOST_FENV_H */ openlibm-0.5.0/include/openlibm_fenv_amd64.h000066400000000000000000000137171266752446200207620ustar00rootroot00000000000000/*- * Copyright (c) 2004-2005 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/lib/msun/amd64/fenv.h,v 1.8 2011/10/10 15:43:09 das Exp $ */ #ifndef _FENV_H_ #define _FENV_H_ #include "cdefs-compat.h" #include "types-compat.h" #include "math_private.h" #ifndef __fenv_static #define __fenv_static static #endif typedef struct { struct { uint32_t __control; uint32_t __status; uint32_t __tag; char __other[16]; } __x87; uint32_t __mxcsr; } fenv_t; typedef uint16_t fexcept_t; /* Exception flags */ #define FE_INVALID 0x01 #define FE_DENORMAL 0x02 #define FE_DIVBYZERO 0x04 #define FE_OVERFLOW 0x08 #define FE_UNDERFLOW 0x10 #define FE_INEXACT 0x20 #define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_DENORMAL | FE_INEXACT | \ FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW) /* Rounding modes */ #define FE_TONEAREST 0x0000 #define FE_DOWNWARD 0x0400 #define FE_UPWARD 0x0800 #define FE_TOWARDZERO 0x0c00 #define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \ FE_UPWARD | FE_TOWARDZERO) /* * As compared to the x87 control word, the SSE unit's control word * has the rounding control bits offset by 3 and the exception mask * bits offset by 7. */ #define _SSE_ROUND_SHIFT 3 #define _SSE_EMASK_SHIFT 7 __BEGIN_DECLS /* Default floating-point environment */ extern const fenv_t __fe_dfl_env; #define FE_DFL_ENV (&__fe_dfl_env) #define __fldcw(__cw) __asm __volatile("fldcw %0" : : "m" (__cw)) #define __fldenv(__env) __asm __volatile("fldenv %0" : : "m" (__env)) #define __fldenvx(__env) __asm __volatile("fldenv %0" : : "m" (__env) \ : "st", "st(1)", "st(2)", "st(3)", "st(4)", \ "st(5)", "st(6)", "st(7)") #define __fnclex() __asm __volatile("fnclex") #define __fnstenv(__env) __asm __volatile("fnstenv %0" : "=m" (*(__env))) #define __fnstcw(__cw) __asm __volatile("fnstcw %0" : "=m" (*(__cw))) #define __fnstsw(__sw) __asm __volatile("fnstsw %0" : "=am" (*(__sw))) #define __fwait() __asm __volatile("fwait") #define __ldmxcsr(__csr) __asm __volatile("ldmxcsr %0" : : "m" (__csr)) #define __stmxcsr(__csr) __asm __volatile("stmxcsr %0" : "=m" (*(__csr))) __fenv_static __attribute__((always_inline)) inline int feclearexcept(int __excepts) { fenv_t __env; if (__excepts == FE_ALL_EXCEPT) { __fnclex(); } else { __fnstenv(&__env.__x87); __env.__x87.__status &= ~__excepts; __fldenv(__env.__x87); } __stmxcsr(&__env.__mxcsr); __env.__mxcsr &= ~__excepts; __ldmxcsr(__env.__mxcsr); return (0); } __fenv_static inline int fegetexceptflag(fexcept_t *__flagp, int __excepts) { uint32_t __mxcsr; uint16_t __status; __stmxcsr(&__mxcsr); __fnstsw(&__status); *__flagp = (__mxcsr | __status) & __excepts; return (0); } int fesetexceptflag(const fexcept_t *__flagp, int __excepts); int feraiseexcept(int __excepts); __fenv_static __attribute__((always_inline)) inline int fetestexcept(int __excepts) { uint32_t __mxcsr; uint16_t __status; __stmxcsr(&__mxcsr); __fnstsw(&__status); return ((__status | __mxcsr) & __excepts); } __fenv_static inline int fegetround(void) { uint16_t __control; /* * We assume that the x87 and the SSE unit agree on the * rounding mode. Reading the control word on the x87 turns * out to be about 5 times faster than reading it on the SSE * unit on an Opteron 244. */ __fnstcw(&__control); return (__control & _ROUND_MASK); } __fenv_static inline int fesetround(int __round) { uint32_t __mxcsr; uint16_t __control; if (__round & ~_ROUND_MASK) return (-1); __fnstcw(&__control); __control &= ~_ROUND_MASK; __control |= __round; __fldcw(__control); __stmxcsr(&__mxcsr); __mxcsr &= ~(_ROUND_MASK << _SSE_ROUND_SHIFT); __mxcsr |= __round << _SSE_ROUND_SHIFT; __ldmxcsr(__mxcsr); return (0); } int fegetenv(fenv_t *__envp); int feholdexcept(fenv_t *__envp); __fenv_static inline int fesetenv(const fenv_t *__envp) { /* * XXX Using fldenvx() instead of fldenv() tells the compiler that this * instruction clobbers the i387 register stack. This happens because * we restore the tag word from the saved environment. Normally, this * would happen anyway and we wouldn't care, because the ABI allows * function calls to clobber the i387 regs. However, fesetenv() is * inlined, so we need to be more careful. */ __fldenvx(__envp->__x87); __ldmxcsr(__envp->__mxcsr); return (0); } int feupdateenv(const fenv_t *__envp); #if __BSD_VISIBLE int feenableexcept(int __mask); int fedisableexcept(int __mask); /* We currently provide no external definition of fegetexcept(). */ static inline int fegetexcept(void) { uint16_t __control; /* * We assume that the masks for the x87 and the SSE unit are * the same. */ __fnstcw(&__control); return (~__control & FE_ALL_EXCEPT); } #endif /* __BSD_VISIBLE */ __END_DECLS #endif /* !_FENV_H_ */ openlibm-0.5.0/include/openlibm_fenv_arm.h000066400000000000000000000116131266752446200206170ustar00rootroot00000000000000/*- * Copyright (c) 2004-2005 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/lib/msun/arm/fenv.h,v 1.6 2011/10/10 15:43:09 das Exp $ */ #ifndef _FENV_H_ #define _FENV_H_ #include #ifndef __fenv_static #define __fenv_static static #endif typedef uint32_t fenv_t; typedef uint32_t fexcept_t; /* Exception flags */ #define FE_INVALID 0x0001 #define FE_DIVBYZERO 0x0002 #define FE_OVERFLOW 0x0004 #define FE_UNDERFLOW 0x0008 #define FE_INEXACT 0x0010 #define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | \ FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW) /* Rounding modes */ #define FE_TONEAREST 0x0000 #define FE_TOWARDZERO 0x0001 #define FE_UPWARD 0x0002 #define FE_DOWNWARD 0x0003 #define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \ FE_UPWARD | FE_TOWARDZERO) __BEGIN_DECLS /* Default floating-point environment */ extern const fenv_t __fe_dfl_env; #define FE_DFL_ENV (&__fe_dfl_env) /* We need to be able to map status flag positions to mask flag positions */ #define _FPUSW_SHIFT 16 #define _ENABLE_MASK (FE_ALL_EXCEPT << _FPUSW_SHIFT) #ifdef ARM_HARD_FLOAT #define __rfs(__fpsr) __asm __volatile("rfs %0" : "=r" (*(__fpsr))) #define __wfs(__fpsr) __asm __volatile("wfs %0" : : "r" (__fpsr)) #else #define __rfs(__fpsr) #define __wfs(__fpsr) #endif __fenv_static inline int feclearexcept(int __excepts) { fexcept_t __fpsr; __rfs(&__fpsr); __fpsr &= ~__excepts; __wfs(__fpsr); return (0); } __fenv_static inline int fegetexceptflag(fexcept_t *__flagp, int __excepts) { fexcept_t __fpsr; __rfs(&__fpsr); *__flagp = __fpsr & __excepts; return (0); } __fenv_static inline int fesetexceptflag(const fexcept_t *__flagp, int __excepts) { fexcept_t __fpsr; __rfs(&__fpsr); __fpsr &= ~__excepts; __fpsr |= *__flagp & __excepts; __wfs(__fpsr); return (0); } __fenv_static inline int feraiseexcept(int __excepts) { fexcept_t __ex = __excepts; fesetexceptflag(&__ex, __excepts); /* XXX */ return (0); } __fenv_static inline int fetestexcept(int __excepts) { fexcept_t __fpsr; __rfs(&__fpsr); return (__fpsr & __excepts); } __fenv_static inline int fegetround(void) { /* * Apparently, the rounding mode is specified as part of the * instruction format on ARM, so the dynamic rounding mode is * indeterminate. Some FPUs may differ. */ return (-1); } __fenv_static inline int fesetround(int __round) { return (-1); } __fenv_static inline int fegetenv(fenv_t *__envp) { __rfs(__envp); return (0); } __fenv_static inline int feholdexcept(fenv_t *__envp) { fenv_t __env; __rfs(&__env); *__envp = __env; __env &= ~(FE_ALL_EXCEPT | _ENABLE_MASK); __wfs(__env); return (0); } __fenv_static inline int fesetenv(const fenv_t *__envp) { __wfs(*__envp); return (0); } __fenv_static inline int feupdateenv(const fenv_t *__envp) { fexcept_t __fpsr; __rfs(&__fpsr); __wfs(*__envp); feraiseexcept(__fpsr & FE_ALL_EXCEPT); return (0); } #if __BSD_VISIBLE /* We currently provide no external definitions of the functions below. */ static inline int feenableexcept(int __mask) { fenv_t __old_fpsr, __new_fpsr; __rfs(&__old_fpsr); __new_fpsr = __old_fpsr | (__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT; __wfs(__new_fpsr); return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT); } static inline int fedisableexcept(int __mask) { fenv_t __old_fpsr, __new_fpsr; __rfs(&__old_fpsr); __new_fpsr = __old_fpsr & ~((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT); __wfs(__new_fpsr); return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT); } static inline int fegetexcept(void) { fenv_t __fpsr; __rfs(&__fpsr); return ((__fpsr & _ENABLE_MASK) >> _FPUSW_SHIFT); } #endif /* __BSD_VISIBLE */ __END_DECLS #endif /* !_FENV_H_ */ openlibm-0.5.0/include/openlibm_fenv_i387.h000066400000000000000000000154571266752446200205440ustar00rootroot00000000000000/*- * Copyright (c) 2004-2005 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/lib/msun/i387/fenv.h,v 1.8 2011/10/10 15:43:09 das Exp $ */ #ifndef _FENV_H_ #define _FENV_H_ #include "cdefs-compat.h" #include "types-compat.h" #ifndef __fenv_static #define __fenv_static static #endif /* * To preserve binary compatibility with FreeBSD 5.3, we pack the * mxcsr into some reserved fields, rather than changing sizeof(fenv_t). */ typedef struct { uint16_t __control; uint16_t __mxcsr_hi; uint16_t __status; uint16_t __mxcsr_lo; uint32_t __tag; char __other[16]; } fenv_t; #define __get_mxcsr(env) (((env).__mxcsr_hi << 16) | \ ((env).__mxcsr_lo)) #define __set_mxcsr(env, x) do { \ (env).__mxcsr_hi = (uint32_t)(x) >> 16; \ (env).__mxcsr_lo = (uint16_t)(x); \ } while (0) typedef uint16_t fexcept_t; /* Exception flags */ #define FE_INVALID 0x01 #define FE_DENORMAL 0x02 #define FE_DIVBYZERO 0x04 #define FE_OVERFLOW 0x08 #define FE_UNDERFLOW 0x10 #define FE_INEXACT 0x20 #define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_DENORMAL | FE_INEXACT | \ FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW) /* Rounding modes */ #define FE_TONEAREST 0x0000 #define FE_DOWNWARD 0x0400 #define FE_UPWARD 0x0800 #define FE_TOWARDZERO 0x0c00 #define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \ FE_UPWARD | FE_TOWARDZERO) /* * As compared to the x87 control word, the SSE unit's control word * has the rounding control bits offset by 3 and the exception mask * bits offset by 7. */ #define _SSE_ROUND_SHIFT 3 #define _SSE_EMASK_SHIFT 7 __BEGIN_DECLS /* After testing for SSE support once, we cache the result in __has_sse. */ enum __sse_support { __SSE_YES, __SSE_NO, __SSE_UNK }; extern enum __sse_support __has_sse; int __test_sse(void); #ifdef __SSE__ #define __HAS_SSE() 1 #else #define __HAS_SSE() (__has_sse == __SSE_YES || \ (__has_sse == __SSE_UNK && __test_sse())) #endif /* Default floating-point environment */ extern const fenv_t __fe_dfl_env; #define FE_DFL_ENV (&__fe_dfl_env) #define __fldcw(__cw) __asm __volatile("fldcw %0" : : "m" (__cw)) #define __fldenv(__env) __asm __volatile("fldenv %0" : : "m" (__env)) #define __fldenvx(__env) __asm __volatile("fldenv %0" : : "m" (__env) \ : "st", "st(1)", "st(2)", "st(3)", "st(4)", \ "st(5)", "st(6)", "st(7)") #define __fnclex() __asm __volatile("fnclex") #define __fnstenv(__env) __asm __volatile("fnstenv %0" : "=m" (*(__env))) #define __fnstcw(__cw) __asm __volatile("fnstcw %0" : "=m" (*(__cw))) #define __fnstsw(__sw) __asm __volatile("fnstsw %0" : "=am" (*(__sw))) #define __fwait() __asm __volatile("fwait") #define __ldmxcsr(__csr) __asm __volatile("ldmxcsr %0" : : "m" (__csr)) #define __stmxcsr(__csr) __asm __volatile("stmxcsr %0" : "=m" (*(__csr))) __fenv_static inline int feclearexcept(int __excepts) { fenv_t __env; uint32_t __mxcsr; if (__excepts == FE_ALL_EXCEPT) { __fnclex(); } else { __fnstenv(&__env); __env.__status &= ~__excepts; __fldenv(__env); } if (__HAS_SSE()) { __stmxcsr(&__mxcsr); __mxcsr &= ~__excepts; __ldmxcsr(__mxcsr); } return (0); } __fenv_static inline int fegetexceptflag(fexcept_t *__flagp, int __excepts) { uint32_t __mxcsr; uint16_t __status; __fnstsw(&__status); if (__HAS_SSE()) __stmxcsr(&__mxcsr); else __mxcsr = 0; *__flagp = (__mxcsr | __status) & __excepts; return (0); } int fesetexceptflag(const fexcept_t *__flagp, int __excepts); int feraiseexcept(int __excepts); __fenv_static inline int fetestexcept(int __excepts) { uint32_t __mxcsr; uint16_t __status; __fnstsw(&__status); if (__HAS_SSE()) __stmxcsr(&__mxcsr); else __mxcsr = 0; return ((__status | __mxcsr) & __excepts); } __fenv_static inline int fegetround(void) { uint16_t __control; /* * We assume that the x87 and the SSE unit agree on the * rounding mode. Reading the control word on the x87 turns * out to be about 5 times faster than reading it on the SSE * unit on an Opteron 244. */ __fnstcw(&__control); return (__control & _ROUND_MASK); } __fenv_static inline int fesetround(int __round) { uint32_t __mxcsr; uint16_t __control; if (__round & ~_ROUND_MASK) return (-1); __fnstcw(&__control); __control &= ~_ROUND_MASK; __control |= __round; __fldcw(__control); if (__HAS_SSE()) { __stmxcsr(&__mxcsr); __mxcsr &= ~(_ROUND_MASK << _SSE_ROUND_SHIFT); __mxcsr |= __round << _SSE_ROUND_SHIFT; __ldmxcsr(__mxcsr); } return (0); } int fegetenv(fenv_t *__envp); int feholdexcept(fenv_t *__envp); __fenv_static inline int fesetenv(const fenv_t *__envp) { fenv_t __env = *__envp; uint32_t __mxcsr; __mxcsr = __get_mxcsr(__env); __set_mxcsr(__env, 0xffffffff); /* * XXX Using fldenvx() instead of fldenv() tells the compiler that this * instruction clobbers the i387 register stack. This happens because * we restore the tag word from the saved environment. Normally, this * would happen anyway and we wouldn't care, because the ABI allows * function calls to clobber the i387 regs. However, fesetenv() is * inlined, so we need to be more careful. */ __fldenvx(__env); if (__HAS_SSE()) __ldmxcsr(__mxcsr); return (0); } int feupdateenv(const fenv_t *__envp); #if __BSD_VISIBLE int feenableexcept(int __mask); int fedisableexcept(int __mask); /* We currently provide no external definition of fegetexcept(). */ static inline int fegetexcept(void) { uint16_t __control; /* * We assume that the masks for the x87 and the SSE unit are * the same. */ __fnstcw(&__control); return (~__control & FE_ALL_EXCEPT); } #endif /* __BSD_VISIBLE */ __END_DECLS #endif /* !_FENV_H_ */ openlibm-0.5.0/include/openlibm_fenv_powerpc.h000066400000000000000000000151771266752446200215300ustar00rootroot00000000000000/*- * Copyright (c) 2004-2005 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #ifndef _FENV_H_ #define _FENV_H_ #include #ifndef __fenv_static #define __fenv_static static #endif typedef __uint32_t fenv_t; typedef __uint32_t fexcept_t; /* Exception flags */ #define FE_INEXACT 0x02000000 #define FE_DIVBYZERO 0x04000000 #define FE_UNDERFLOW 0x08000000 #define FE_OVERFLOW 0x10000000 #define FE_INVALID 0x20000000 /* all types of invalid FP ops */ /* * The PowerPC architecture has extra invalid flags that indicate the * specific type of invalid operation occurred. These flags may be * tested, set, and cleared---but not masked---separately. All of * these bits are cleared when FE_INVALID is cleared, but only * FE_VXSOFT is set when FE_INVALID is explicitly set in software. */ #define FE_VXCVI 0x00000100 /* invalid integer convert */ #define FE_VXSQRT 0x00000200 /* square root of a negative */ #define FE_VXSOFT 0x00000400 /* software-requested exception */ #define FE_VXVC 0x00080000 /* ordered comparison involving NaN */ #define FE_VXIMZ 0x00100000 /* inf * 0 */ #define FE_VXZDZ 0x00200000 /* 0 / 0 */ #define FE_VXIDI 0x00400000 /* inf / inf */ #define FE_VXISI 0x00800000 /* inf - inf */ #define FE_VXSNAN 0x01000000 /* operation on a signalling NaN */ #define FE_ALL_INVALID (FE_VXCVI | FE_VXSQRT | FE_VXSOFT | FE_VXVC | \ FE_VXIMZ | FE_VXZDZ | FE_VXIDI | FE_VXISI | \ FE_VXSNAN | FE_INVALID) #define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | \ FE_ALL_INVALID | FE_OVERFLOW | FE_UNDERFLOW) /* Rounding modes */ #define FE_TONEAREST 0x0000 #define FE_TOWARDZERO 0x0001 #define FE_UPWARD 0x0002 #define FE_DOWNWARD 0x0003 #define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \ FE_UPWARD | FE_TOWARDZERO) __BEGIN_DECLS /* Default floating-point environment */ extern const fenv_t __fe_dfl_env; #define FE_DFL_ENV (&__fe_dfl_env) /* We need to be able to map status flag positions to mask flag positions */ #define _FPUSW_SHIFT 22 #define _ENABLE_MASK ((FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \ FE_OVERFLOW | FE_UNDERFLOW) >> _FPUSW_SHIFT) #ifndef _SOFT_FLOAT #define __mffs(__env) __asm __volatile("mffs %0" : "=f" (*(__env))) #define __mtfsf(__env) __asm __volatile("mtfsf 255,%0" : : "f" (__env)) #else #define __mffs(__env) #define __mtfsf(__env) #endif union __fpscr { double __d; struct { #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ fenv_t __reg; __uint32_t __junk; #else __uint32_t __junk; fenv_t __reg; #endif } __bits; }; __fenv_static inline int feclearexcept(int __excepts) { union __fpscr __r; if (__excepts & FE_INVALID) __excepts |= FE_ALL_INVALID; __mffs(&__r.__d); __r.__bits.__reg &= ~__excepts; __mtfsf(__r.__d); return (0); } __fenv_static inline int fegetexceptflag(fexcept_t *__flagp, int __excepts) { union __fpscr __r; __mffs(&__r.__d); *__flagp = __r.__bits.__reg & __excepts; return (0); } __fenv_static inline int fesetexceptflag(const fexcept_t *__flagp, int __excepts) { union __fpscr __r; if (__excepts & FE_INVALID) __excepts |= FE_ALL_EXCEPT; __mffs(&__r.__d); __r.__bits.__reg &= ~__excepts; __r.__bits.__reg |= *__flagp & __excepts; __mtfsf(__r.__d); return (0); } __fenv_static inline int feraiseexcept(int __excepts) { union __fpscr __r; if (__excepts & FE_INVALID) __excepts |= FE_VXSOFT; __mffs(&__r.__d); __r.__bits.__reg |= __excepts; __mtfsf(__r.__d); return (0); } __fenv_static inline int fetestexcept(int __excepts) { union __fpscr __r; __mffs(&__r.__d); return (__r.__bits.__reg & __excepts); } __fenv_static inline int fegetround(void) { union __fpscr __r; __mffs(&__r.__d); return (__r.__bits.__reg & _ROUND_MASK); } __fenv_static inline int fesetround(int __round) { union __fpscr __r; if (__round & ~_ROUND_MASK) return (-1); __mffs(&__r.__d); __r.__bits.__reg &= ~_ROUND_MASK; __r.__bits.__reg |= __round; __mtfsf(__r.__d); return (0); } __fenv_static inline int fegetenv(fenv_t *__envp) { union __fpscr __r; __mffs(&__r.__d); *__envp = __r.__bits.__reg; return (0); } __fenv_static inline int feholdexcept(fenv_t *__envp) { union __fpscr __r; __mffs(&__r.__d); *__envp = __r.__d; __r.__bits.__reg &= ~(FE_ALL_EXCEPT | _ENABLE_MASK); __mtfsf(__r.__d); return (0); } __fenv_static inline int fesetenv(const fenv_t *__envp) { union __fpscr __r; __r.__bits.__reg = *__envp; __mtfsf(__r.__d); return (0); } __fenv_static inline int feupdateenv(const fenv_t *__envp) { union __fpscr __r; __mffs(&__r.__d); __r.__bits.__reg &= FE_ALL_EXCEPT; __r.__bits.__reg |= *__envp; __mtfsf(__r.__d); return (0); } #if __BSD_VISIBLE /* We currently provide no external definitions of the functions below. */ static inline int feenableexcept(int __mask) { union __fpscr __r; fenv_t __oldmask; __mffs(&__r.__d); __oldmask = __r.__bits.__reg; __r.__bits.__reg |= (__mask & FE_ALL_EXCEPT) >> _FPUSW_SHIFT; __mtfsf(__r.__d); return ((__oldmask & _ENABLE_MASK) << _FPUSW_SHIFT); } static inline int fedisableexcept(int __mask) { union __fpscr __r; fenv_t __oldmask; __mffs(&__r.__d); __oldmask = __r.__bits.__reg; __r.__bits.__reg &= ~((__mask & FE_ALL_EXCEPT) >> _FPUSW_SHIFT); __mtfsf(__r.__d); return ((__oldmask & _ENABLE_MASK) << _FPUSW_SHIFT); } static inline int fegetexcept(void) { union __fpscr __r; __mffs(&__r.__d); return ((__r.__bits.__reg & _ENABLE_MASK) << _FPUSW_SHIFT); } #endif /* __BSD_VISIBLE */ __END_DECLS #endif /* !_FENV_H_ */ openlibm-0.5.0/include/openlibm_math.h000066400000000000000000000316101266752446200177520ustar00rootroot00000000000000/* * ==================================================== * 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. * ==================================================== */ /* * from: @(#)fdlibm.h 5.1 93/09/24 * $FreeBSD: src/lib/msun/src/openlibm.h,v 1.82 2011/11/12 19:55:48 theraven Exp $ */ #ifdef OPENLIBM_USE_HOST_MATH_H #include #else /* !OPENLIBM_USE_HOST_MATH_H */ #ifndef OPENLIBM_MATH_H #define OPENLIBM_MATH_H #if (defined(_WIN32) || defined (_MSC_VER)) && !defined(__WIN32__) #define __WIN32__ #endif #ifndef __arm__ #define LONG_DOUBLE #endif #ifndef __pure2 #define __pure2 #endif /* * ANSI/POSIX */ extern const union __infinity_un { unsigned char __uc[8]; double __ud; } __infinity; extern const union __nan_un { unsigned char __uc[sizeof(float)]; float __uf; } __nan; /* VBS #if __GNUC_PREREQ__(3, 3) || (defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 800) #define __MATH_BUILTIN_CONSTANTS #endif #if __GNUC_PREREQ__(3, 0) && !defined(__INTEL_COMPILER) #define __MATH_BUILTIN_RELOPS #endif */ //VBS begin #define __MATH_BUILTIN_CONSTANTS #define __MATH_BUILTIN_RELOPS #ifndef __ISO_C_VISIBLE #define __ISO_C_VISIBLE 1999 #endif //VBS end #ifdef __MATH_BUILTIN_CONSTANTS #define HUGE_VAL __builtin_huge_val() #else #define HUGE_VAL (__infinity.__ud) #endif #if __ISO_C_VISIBLE >= 1999 #define FP_ILOGB0 (-INT_MAX) #define FP_ILOGBNAN INT_MAX #ifdef __MATH_BUILTIN_CONSTANTS #define HUGE_VALF __builtin_huge_valf() #define HUGE_VALL __builtin_huge_vall() #define INFINITY __builtin_inff() #define NAN __builtin_nanf("") #else #define HUGE_VALF (float)HUGE_VAL #define HUGE_VALL (long double)HUGE_VAL #define INFINITY HUGE_VALF #define NAN (__nan.__uf) #endif /* __MATH_BUILTIN_CONSTANTS */ #define MATH_ERRNO 1 #define MATH_ERREXCEPT 2 #define math_errhandling MATH_ERREXCEPT #define FP_FAST_FMAF 1 #ifdef __ia64__ #define FP_FAST_FMA 1 #define FP_FAST_FMAL 1 #endif /* Symbolic constants to classify floating point numbers. */ #define FP_INFINITE 0x01 #define FP_NAN 0x02 #define FP_NORMAL 0x04 #define FP_SUBNORMAL 0x08 #define FP_ZERO 0x10 #define fpclassify(x) \ ((sizeof (x) == sizeof (float)) ? __fpclassifyf(x) \ : (sizeof (x) == sizeof (double)) ? __fpclassifyd(x) \ : __fpclassifyl(x)) #define isfinite(x) \ ((sizeof (x) == sizeof (float)) ? __isfinitef(x) \ : (sizeof (x) == sizeof (double)) ? __isfinite(x) \ : __isfinitel(x)) #define isinf(x) \ ((sizeof (x) == sizeof (float)) ? __isinff(x) \ : (sizeof (x) == sizeof (double)) ? isinf(x) \ : __isinfl(x)) #define isnan(x) \ ((sizeof (x) == sizeof (float)) ? __isnanf(x) \ : (sizeof (x) == sizeof (double)) ? isnan(x) \ : __isnanl(x)) #define isnormal(x) \ ((sizeof (x) == sizeof (float)) ? __isnormalf(x) \ : (sizeof (x) == sizeof (double)) ? __isnormal(x) \ : __isnormall(x)) #ifdef __MATH_BUILTIN_RELOPS #define isgreater(x, y) __builtin_isgreater((x), (y)) #define isgreaterequal(x, y) __builtin_isgreaterequal((x), (y)) #define isless(x, y) __builtin_isless((x), (y)) #define islessequal(x, y) __builtin_islessequal((x), (y)) #define islessgreater(x, y) __builtin_islessgreater((x), (y)) #define isunordered(x, y) __builtin_isunordered((x), (y)) #else #define isgreater(x, y) (!isunordered((x), (y)) && (x) > (y)) #define isgreaterequal(x, y) (!isunordered((x), (y)) && (x) >= (y)) #define isless(x, y) (!isunordered((x), (y)) && (x) < (y)) #define islessequal(x, y) (!isunordered((x), (y)) && (x) <= (y)) #define islessgreater(x, y) (!isunordered((x), (y)) && \ ((x) > (y) || (y) > (x))) #define isunordered(x, y) (isnan(x) || isnan(y)) #endif /* __MATH_BUILTIN_RELOPS */ #define signbit(x) \ ((sizeof (x) == sizeof (float)) ? __signbitf(x) \ : (sizeof (x) == sizeof (double)) ? __signbit(x) \ : __signbitl(x)) //VBS //typedef __double_t double_t; //typedef __float_t float_t; #endif /* __ISO_C_VISIBLE >= 1999 */ /* * XOPEN/SVID */ #if __BSD_VISIBLE || __XSI_VISIBLE #define M_E 2.7182818284590452354 /* e */ #define M_LOG2E 1.4426950408889634074 /* log 2e */ #define M_LOG10E 0.43429448190325182765 /* log 10e */ #define M_LN2 0.69314718055994530942 /* log e2 */ #define M_LN10 2.30258509299404568402 /* log e10 */ #define M_PI 3.14159265358979323846 /* pi */ #define M_PI_2 1.57079632679489661923 /* pi/2 */ #define M_PI_4 0.78539816339744830962 /* pi/4 */ #define M_1_PI 0.31830988618379067154 /* 1/pi */ #define M_2_PI 0.63661977236758134308 /* 2/pi */ #define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */ #define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ #define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ #define MAXFLOAT ((float)3.40282346638528860e+38) #ifndef OPENLIBM_ONLY_THREAD_SAFE extern int signgam; #endif #endif /* __BSD_VISIBLE || __XSI_VISIBLE */ #if __BSD_VISIBLE #if 0 /* Old value from 4.4BSD-Lite openlibm.h; this is probably better. */ #define HUGE HUGE_VAL #else #define HUGE MAXFLOAT #endif #endif /* __BSD_VISIBLE */ /* * Most of these functions depend on the rounding mode and have the side * effect of raising floating-point exceptions, so they are not declared * as __pure2. In C99, FENV_ACCESS affects the purity of these functions. */ #if defined(__cplusplus) extern "C" { #endif /* Symbol present when OpenLibm is used. */ int isopenlibm(void); /* * ANSI/POSIX */ int __fpclassifyd(double) __pure2; int __fpclassifyf(float) __pure2; int __fpclassifyl(long double) __pure2; int __isfinitef(float) __pure2; int __isfinite(double) __pure2; int __isfinitel(long double) __pure2; int __isinff(float) __pure2; int __isinfl(long double) __pure2; int __isnanf(float) __pure2; int __isnanl(long double) __pure2; int __isnormalf(float) __pure2; int __isnormal(double) __pure2; int __isnormall(long double) __pure2; int __signbit(double) __pure2; int __signbitf(float) __pure2; int __signbitl(long double) __pure2; double acos(double); double asin(double); double atan(double); double atan2(double, double); double cos(double); double sin(double); double tan(double); double cosh(double); double sinh(double); double tanh(double); double exp(double); double frexp(double, int *); /* fundamentally !__pure2 */ double ldexp(double, int); double log(double); double log10(double); double modf(double, double *); /* fundamentally !__pure2 */ double pow(double, double); double sqrt(double); double ceil(double); double fabs(double) __pure2; double floor(double); double fmod(double, double); /* * These functions are not in C90. */ #if __BSD_VISIBLE || __ISO_C_VISIBLE >= 1999 || __XSI_VISIBLE double acosh(double); double asinh(double); double atanh(double); double cbrt(double); double erf(double); double erfc(double); double exp2(double); double expm1(double); double fma(double, double, double); double hypot(double, double); int ilogb(double) __pure2; int (isinf)(double) __pure2; int (isnan)(double) __pure2; double lgamma(double); long long llrint(double); long long llround(double); double log1p(double); double log2(double); double logb(double); long lrint(double); long lround(double); double nan(const char *) __pure2; double nextafter(double, double); double remainder(double, double); double remquo(double, double, int *); double rint(double); #endif /* __BSD_VISIBLE || __ISO_C_VISIBLE >= 1999 || __XSI_VISIBLE */ #if __BSD_VISIBLE || __XSI_VISIBLE double j0(double); double j1(double); double jn(int, double); double y0(double); double y1(double); double yn(int, double); #endif /* __BSD_VISIBLE || __XSI_VISIBLE */ #if __BSD_VISIBLE || __ISO_C_VISIBLE >= 1999 double copysign(double, double) __pure2; double fdim(double, double); double fmax(double, double) __pure2; double fmin(double, double) __pure2; double nearbyint(double); double round(double); double scalbln(double, long); double scalbn(double, int); double tgamma(double); double trunc(double); #endif /* * BSD math library entry points */ #if __BSD_VISIBLE int isnanf(float) __pure2; /* * Reentrant version of lgamma; passes signgam back by reference as the * second argument; user must allocate space for signgam. */ double lgamma_r(double, int *); /* * Single sine/cosine function. */ void sincos(double, double *, double *); #endif /* __BSD_VISIBLE */ /* float versions of ANSI/POSIX functions */ #if __ISO_C_VISIBLE >= 1999 float acosf(float); float asinf(float); float atanf(float); float atan2f(float, float); float cosf(float); float sinf(float); float tanf(float); float coshf(float); float sinhf(float); float tanhf(float); float exp2f(float); float expf(float); float expm1f(float); float frexpf(float, int *); /* fundamentally !__pure2 */ int ilogbf(float) __pure2; float ldexpf(float, int); float log10f(float); float log1pf(float); float log2f(float); float logf(float); float modff(float, float *); /* fundamentally !__pure2 */ float powf(float, float); float sqrtf(float); float ceilf(float); float fabsf(float) __pure2; float floorf(float); float fmodf(float, float); float roundf(float); float erff(float); float erfcf(float); float hypotf(float, float); float lgammaf(float); float tgammaf(float); float acoshf(float); float asinhf(float); float atanhf(float); float cbrtf(float); float logbf(float); float copysignf(float, float) __pure2; long long llrintf(float); long long llroundf(float); long lrintf(float); long lroundf(float); float nanf(const char *) __pure2; float nearbyintf(float); float nextafterf(float, float); float remainderf(float, float); float remquof(float, float, int *); float rintf(float); float scalblnf(float, long); float scalbnf(float, int); float truncf(float); float fdimf(float, float); float fmaf(float, float, float); float fmaxf(float, float) __pure2; float fminf(float, float) __pure2; #endif /* * float versions of BSD math library entry points */ #if __BSD_VISIBLE float dremf(float, float); float j0f(float); float j1f(float); float jnf(int, float); float y0f(float); float y1f(float); float ynf(int, float); /* * Float versions of reentrant version of lgamma; passes signgam back by * reference as the second argument; user must allocate space for signgam. */ float lgammaf_r(float, int *); /* * Single sine/cosine function. */ void sincosf(float, float *, float *); #endif /* __BSD_VISIBLE */ /* * long double versions of ISO/POSIX math functions */ #if __ISO_C_VISIBLE >= 1999 long double acoshl(long double); long double acosl(long double); long double asinhl(long double); long double asinl(long double); long double atan2l(long double, long double); long double atanhl(long double); long double atanl(long double); long double cbrtl(long double); long double ceill(long double); long double copysignl(long double, long double) __pure2; long double coshl(long double); long double cosl(long double); long double erfcl(long double); long double erfl(long double); long double exp2l(long double); long double expl(long double); long double expm1l(long double); long double fabsl(long double) __pure2; long double fdiml(long double, long double); long double floorl(long double); long double fmal(long double, long double, long double); long double fmaxl(long double, long double) __pure2; long double fminl(long double, long double) __pure2; long double fmodl(long double, long double); long double frexpl(long double value, int *); /* fundamentally !__pure2 */ long double hypotl(long double, long double); int ilogbl(long double) __pure2; long double ldexpl(long double, int); long double lgammal(long double); long long llrintl(long double); long long llroundl(long double); long double log10l(long double); long double log1pl(long double); long double log2l(long double); long double logbl(long double); long double logl(long double); long lrintl(long double); long lroundl(long double); long double modfl(long double, long double *); /* fundamentally !__pure2 */ long double nanl(const char *) __pure2; long double nearbyintl(long double); long double nextafterl(long double, long double); double nexttoward(double, long double); float nexttowardf(float, long double); long double nexttowardl(long double, long double); long double powl(long double, long double); long double remainderl(long double, long double); long double remquol(long double, long double, int *); long double rintl(long double); long double roundl(long double); long double scalblnl(long double, long); long double scalbnl(long double, int); long double sinhl(long double); long double sinl(long double); long double sqrtl(long double); long double tanhl(long double); long double tanl(long double); long double tgammal(long double); long double truncl(long double); #endif /* __ISO_C_VISIBLE >= 1999 */ /* Reentrant version of lgammal. */ #if __BSD_VISIBLE long double lgammal_r(long double, int *); /* * Single sine/cosine function. */ void sincosl(long double, long double *, long double *); #endif /* __BSD_VISIBLE */ #if defined(__cplusplus) } #endif #endif /* !OPENLIBM_MATH_H */ #endif /* OPENLIBM_USE_HOST_MATH_H */ openlibm-0.5.0/ld128/000077500000000000000000000000001266752446200141715ustar00rootroot00000000000000openlibm-0.5.0/ld128/Make.files000066400000000000000000000001021266752446200160630ustar00rootroot00000000000000SRCS = invtrig.c k_cosl.c k_sinl.c k_tanl.c # s_nanl.c s_exp2l.c openlibm-0.5.0/ld128/e_acoshl.c000066400000000000000000000030471266752446200161160ustar00rootroot00000000000000/* @(#)e_acosh.c 5.1 93/09/24 */ /* * ==================================================== * 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. * ==================================================== */ /* acoshl(x) * Method : * Based on * acoshl(x) = logl [ x + sqrtl(x*x-1) ] * we have * acoshl(x) := logl(x)+ln2, if x is large; else * acoshl(x) := logl(2x-1/(sqrtl(x*x-1)+x)) if x>2; else * acoshl(x) := log1pl(t+sqrtl(2.0*t+t*t)); where t=x-1. * * Special cases: * acoshl(x) is NaN with signal if x<1. * acoshl(NaN) is NaN without signal. */ #include #include "math_private.h" static const long double one = 1.0, ln2 = 0.6931471805599453094172321214581766L; long double acoshl(long double x) { long double t; u_int64_t lx; int64_t hx; GET_LDOUBLE_WORDS64(hx,lx,x); if(hx<0x3fff000000000000LL) { /* x < 1 */ return (x-x)/(x-x); } else if(hx >=0x4035000000000000LL) { /* x > 2**54 */ if(hx >=0x7fff000000000000LL) { /* x is inf of NaN */ return x+x; } else return logl(x)+ln2; /* acoshl(huge)=logl(2x) */ } else if(((hx-0x3fff000000000000LL)|lx)==0) { return 0.0L; /* acosh(1) = 0 */ } else if (hx > 0x4000000000000000LL) { /* 2**28 > x > 2 */ t=x*x; return logl(2.0L*x-one/(x+sqrtl(t-one))); } else { /* 1=0.5 * 1 2x x * atanhl(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------) * 2 1 - x 1 - x * * For x<0.5 * atanhl(x) = 0.5*log1pl(2x+2x*x/(1-x)) * * Special cases: * atanhl(x) is NaN if |x| > 1 with signal; * atanhl(NaN) is that NaN with no signal; * atanhl(+-1) is +-INF with signal. * */ #include #include "math_private.h" static const long double one = 1.0L, huge = 1e4900L; static const long double zero = 0.0L; long double atanhl(long double x) { long double t; u_int32_t jx, ix; ieee_quad_shape_type u; u.value = x; jx = u.parts32.mswhi; ix = jx & 0x7fffffff; u.parts32.mswhi = ix; if (ix >= 0x3fff0000) /* |x| >= 1.0 or infinity or NaN */ { if (u.value == one) return x/zero; else return (x-x)/(x-x); } if(ix<0x3fc60000 && (huge+x)>zero) return x; /* x < 2^-57 */ if(ix<0x3ffe0000) { /* x < 0.5 */ t = u.value+u.value; t = 0.5*log1pl(t+t*u.value/(one-u.value)); } else t = 0.5*log1pl((u.value+u.value)/(one-u.value)); if(jx & 0x80000000) return -t; else return t; } openlibm-0.5.0/ld128/e_coshl.c000066400000000000000000000064301266752446200157540ustar00rootroot00000000000000/* * ==================================================== * 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. * ==================================================== */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* coshl(x) * Method : * mathematically coshl(x) if defined to be (exp(x)+exp(-x))/2 * 1. Replace x by |x| (coshl(x) = coshl(-x)). * 2. * [ exp(x) - 1 ]^2 * 0 <= x <= ln2/2 : coshl(x) := 1 + ------------------- * 2*exp(x) * * exp(x) + 1/exp(x) * ln2/2 <= x <= 22 : coshl(x) := ------------------- * 2 * 22 <= x <= lnovft : coshl(x) := expl(x)/2 * lnovft <= x <= ln2ovft: coshl(x) := expl(x/2)/2 * expl(x/2) * ln2ovft < x : coshl(x) := huge*huge (overflow) * * Special cases: * coshl(x) is |x| if x is +INF, -INF, or NaN. * only coshl(0)=1 is exact for finite x. */ #include #include "math_private.h" static const long double one = 1.0, half = 0.5, huge = 1.0e4900L, ovf_thresh = 1.1357216553474703894801348310092223067821E4L; long double coshl(long double x) { long double t, w; int32_t ex; ieee_quad_shape_type u; u.value = x; ex = u.parts32.mswhi & 0x7fffffff; /* Absolute value of x. */ u.parts32.mswhi = ex; /* x is INF or NaN */ if (ex >= 0x7fff0000) return x * x; /* |x| in [0,0.5*ln2], return 1+expm1l(|x|)^2/(2*expl(|x|)) */ if (ex < 0x3ffd62e4) /* 0.3465728759765625 */ { t = expm1l (u.value); w = one + t; if (ex < 0x3fb80000) /* |x| < 2^-116 */ return w; /* cosh(tiny) = 1 */ return one + (t * t) / (w + w); } /* |x| in [0.5*ln2,40], return (exp(|x|)+1/exp(|x|)/2; */ if (ex < 0x40044000) { t = expl (u.value); return half * t + half / t; } /* |x| in [22, ln(maxdouble)] return half*exp(|x|) */ if (ex <= 0x400c62e3) /* 11356.375 */ return half * expl (u.value); /* |x| in [log(maxdouble), overflowthresold] */ if (u.value <= ovf_thresh) { w = expl (half * u.value); t = half * w; return t * w; } /* |x| > overflowthresold, cosh(x) overflow */ return huge * huge; } openlibm-0.5.0/ld128/e_expl.c000066400000000000000000000103421266752446200156110ustar00rootroot00000000000000/* $OpenBSD: e_expl.c,v 1.3 2013/11/12 20:35:18 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* expl.c * * Exponential function, 128-bit long double precision * * * * SYNOPSIS: * * long double x, y, expl(); * * y = expl( x ); * * * * DESCRIPTION: * * Returns e (2.71828...) raised to the x power. * * Range reduction is accomplished by separating the argument * into an integer k and fraction f such that * * x k f * e = 2 e. * * A Pade' form of degree 2/3 is used to approximate exp(f) - 1 * in the basic range [-0.5 ln 2, 0.5 ln 2]. * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE +-MAXLOG 100,000 2.6e-34 8.6e-35 * * * Error amplification in the exponential function can be * a serious matter. The error propagation involves * exp( X(1+delta) ) = exp(X) ( 1 + X*delta + ... ), * which shows that a 1 lsb error in representing X produces * a relative error of X times 1 lsb in the function. * While the routine gives an accurate result for arguments * that are exactly represented by a long double precision * computer number, the result contains amplified roundoff * error for large arguments not exactly represented. * * * ERROR MESSAGES: * * message condition value returned * exp underflow x < MINLOG 0.0 * exp overflow x > MAXLOG MAXNUM * */ /* Exponential function */ #include #include #include "math_private.h" /* Pade' coefficients for exp(x) - 1 Theoretical peak relative error = 2.2e-37, relative peak error spread = 9.2e-38 */ static long double P[5] = { 3.279723985560247033712687707263393506266E-10L, 6.141506007208645008909088812338454698548E-7L, 2.708775201978218837374512615596512792224E-4L, 3.508710990737834361215404761139478627390E-2L, 9.999999999999999999999999999999999998502E-1L }; static long double Q[6] = { 2.980756652081995192255342779918052538681E-12L, 1.771372078166251484503904874657985291164E-8L, 1.504792651814944826817779302637284053660E-5L, 3.611828913847589925056132680618007270344E-3L, 2.368408864814233538909747618894558968880E-1L, 2.000000000000000000000000000000000000150E0L }; /* C1 + C2 = ln 2 */ static const long double C1 = -6.93145751953125E-1L; static const long double C2 = -1.428606820309417232121458176568075500134E-6L; static const long double LOG2EL = 1.442695040888963407359924681001892137426646L; static const long double MAXLOGL = 1.1356523406294143949491931077970764891253E4L; static const long double MINLOGL = -1.143276959615573793352782661133116431383730e4L; static const long double huge = 0x1p10000L; #if 0 /* XXX Prevent gcc from erroneously constant folding this. */ static const long double twom10000 = 0x1p-10000L; #else static volatile long double twom10000 = 0x1p-10000L; #endif long double expl(long double x) { long double px, xx; int n; if( x > MAXLOGL) return (huge*huge); /* overflow */ if( x < MINLOGL ) return (twom10000*twom10000); /* underflow */ /* Express e**x = e**g 2**n * = e**g e**( n loge(2) ) * = e**( g + n loge(2) ) */ px = floorl( LOG2EL * x + 0.5L ); /* floor() truncates toward -infinity. */ n = px; x += px * C1; x += px * C2; /* rational approximation for exponential * of the fractional part: * e**x = 1 + 2x P(x**2)/( Q(x**2) - P(x**2) ) */ xx = x * x; px = x * __polevll( xx, P, 4 ); xx = __polevll( xx, Q, 5 ); x = px/( xx - px ); x = 1.0L + x + x; x = ldexpl( x, n ); return(x); } openlibm-0.5.0/ld128/e_fmodl.c000066400000000000000000000064741266752446200157550ustar00rootroot00000000000000/* @(#)e_fmod.c 5.1 93/09/24 */ /* * ==================================================== * 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. * ==================================================== */ /* * fmodl(x,y) * Return x mod y in exact arithmetic * Method: shift and subtract */ #include #include "math_private.h" static const long double one = 1.0, Zero[] = {0.0, -0.0,}; long double fmodl(long double x, long double y) { int64_t n,hx,hy,hz,ix,iy,sx,i; u_int64_t lx,ly,lz; GET_LDOUBLE_WORDS64(hx,lx,x); GET_LDOUBLE_WORDS64(hy,ly,y); sx = hx&0x8000000000000000ULL; /* sign of x */ hx ^=sx; /* |x| */ hy &= 0x7fffffffffffffffLL; /* |y| */ /* purge off exception values */ if((hy|ly)==0||(hx>=0x7fff000000000000LL)|| /* y=0,or x not finite */ ((hy|((ly|-ly)>>63))>0x7fff000000000000LL)) /* or y is NaN */ return (x*y)/(x*y); if(hx<=hy) { if((hx>63]; /* |x|=|y| return x*0*/ } /* determine ix = ilogb(x) */ if(hx<0x0001000000000000LL) { /* subnormal x */ if(hx==0) { for (ix = -16431, i=lx; i>0; i<<=1) ix -=1; } else { for (ix = -16382, i=hx<<15; i>0; i<<=1) ix -=1; } } else ix = (hx>>48)-0x3fff; /* determine iy = ilogb(y) */ if(hy<0x0001000000000000LL) { /* subnormal y */ if(hy==0) { for (iy = -16431, i=ly; i>0; i<<=1) iy -=1; } else { for (iy = -16382, i=hy<<15; i>0; i<<=1) iy -=1; } } else iy = (hy>>48)-0x3fff; /* set up {hx,lx}, {hy,ly} and align y to x */ if(ix >= -16382) hx = 0x0001000000000000LL|(0x0000ffffffffffffLL&hx); else { /* subnormal x, shift x to normal */ n = -16382-ix; if(n<=63) { hx = (hx<>(64-n)); lx <<= n; } else { hx = lx<<(n-64); lx = 0; } } if(iy >= -16382) hy = 0x0001000000000000LL|(0x0000ffffffffffffLL&hy); else { /* subnormal y, shift y to normal */ n = -16382-iy; if(n<=63) { hy = (hy<>(64-n)); ly <<= n; } else { hy = ly<<(n-64); ly = 0; } } /* fix point fmod */ n = ix - iy; while(n--) { hz=hx-hy;lz=lx-ly; if(lx>63); lx = lx+lx;} else { if((hz|lz)==0) /* return sign(x)*0 */ return Zero[(u_int64_t)sx>>63]; hx = hz+hz+(lz>>63); lx = lz+lz; } } hz=hx-hy;lz=lx-ly; if(lx=0) {hx=hz;lx=lz;} /* convert back to floating value and restore the sign */ if((hx|lx)==0) /* return sign(x)*0 */ return Zero[(u_int64_t)sx>>63]; while(hx<0x0001000000000000LL) { /* normalize x */ hx = hx+hx+(lx>>63); lx = lx+lx; iy -= 1; } if(iy>= -16382) { /* normalize output */ hx = ((hx-0x0001000000000000LL)|((iy+16383)<<48)); SET_LDOUBLE_WORDS64(x,hx|sx,lx); } else { /* subnormal output */ n = -16382 - iy; if(n<=48) { lx = (lx>>n)|((u_int64_t)hx<<(64-n)); hx >>= n; } else if (n<=63) { lx = (hx<<(64-n))|(lx>>n); hx = sx; } else { lx = hx>>(n-64); hx = sx; } SET_LDOUBLE_WORDS64(x,hx|sx,lx); x *= one; /* create necessary signal */ } return x; /* exact output */ } openlibm-0.5.0/ld128/e_hypotl.c000066400000000000000000000065211266752446200161640ustar00rootroot00000000000000/* @(#)e_hypot.c 5.1 93/09/24 */ /* * ==================================================== * 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. * ==================================================== */ /* hypotl(x,y) * * Method : * If (assume round-to-nearest) z=x*x+y*y * has error less than sqrtl(2)/2 ulp, than * sqrtl(z) has error less than 1 ulp (exercise). * * So, compute sqrtl(x*x+y*y) with some care as * follows to get the error below 1 ulp: * * Assume x>y>0; * (if possible, set rounding to round-to-nearest) * 1. if x > 2y use * x1*x1+(y*y+(x2*(x+x1))) for x*x+y*y * where x1 = x with lower 64 bits cleared, x2 = x-x1; else * 2. if x <= 2y use * t1*yy1+((x-y)*(x-y)+(t1*y2+t2*y)) * where t1 = 2x with lower 64 bits cleared, t2 = 2x-t1, * yy1= y with lower 64 bits chopped, y2 = y-yy1. * * NOTE: scaling may be necessary if some argument is too * large or too tiny * * Special cases: * hypotl(x,y) is INF if x or y is +INF or -INF; else * hypotl(x,y) is NAN if x or y is NAN. * * Accuracy: * hypotl(x,y) returns sqrtl(x^2+y^2) with error less * than 1 ulps (units in the last place) */ #include #include "math_private.h" long double hypotl(long double x, long double y) { long double a,b,t1,t2,yy1,y2,w; int64_t j,k,ha,hb; GET_LDOUBLE_MSW64(ha,x); ha &= 0x7fffffffffffffffLL; GET_LDOUBLE_MSW64(hb,y); hb &= 0x7fffffffffffffffLL; if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;} SET_LDOUBLE_MSW64(a,ha); /* a <- |a| */ SET_LDOUBLE_MSW64(b,hb); /* b <- |b| */ if((ha-hb)>0x78000000000000LL) {return a+b;} /* x/y > 2**120 */ k=0; if(ha > 0x5f3f000000000000LL) { /* a>2**8000 */ if(ha >= 0x7fff000000000000LL) { /* Inf or NaN */ u_int64_t low; w = a+b; /* for sNaN */ GET_LDOUBLE_LSW64(low,a); if(((ha&0xffffffffffffLL)|low)==0) w = a; GET_LDOUBLE_LSW64(low,b); if(((hb^0x7fff000000000000LL)|low)==0) w = b; return w; } /* scale a and b by 2**-9600 */ ha -= 0x2580000000000000LL; hb -= 0x2580000000000000LL; k += 9600; SET_LDOUBLE_MSW64(a,ha); SET_LDOUBLE_MSW64(b,hb); } if(hb < 0x20bf000000000000LL) { /* b < 2**-8000 */ if(hb <= 0x0000ffffffffffffLL) { /* subnormal b or 0 */ u_int64_t low; GET_LDOUBLE_LSW64(low,b); if((hb|low)==0) return a; t1=0; SET_LDOUBLE_MSW64(t1,0x7ffd000000000000LL); /* t1=2^16382 */ b *= t1; a *= t1; k -= 16382; } else { /* scale a and b by 2^9600 */ ha += 0x2580000000000000LL; /* a *= 2^9600 */ hb += 0x2580000000000000LL; /* b *= 2^9600 */ k -= 9600; SET_LDOUBLE_MSW64(a,ha); SET_LDOUBLE_MSW64(b,hb); } } /* medium size a and b */ w = a-b; if (w>b) { t1 = 0; SET_LDOUBLE_MSW64(t1,ha); t2 = a-t1; w = sqrtl(t1*t1-(b*(-b)-t2*(a+t1))); } else { a = a+a; yy1 = 0; SET_LDOUBLE_MSW64(yy1,hb); y2 = b - yy1; t1 = 0; SET_LDOUBLE_MSW64(t1,ha+0x0001000000000000LL); t2 = a - t1; w = sqrtl(t1*yy1-(w*(-w)-(t1*y2+t2*b))); } if(k!=0) { u_int64_t high; t1 = 1.0L; GET_LDOUBLE_MSW64(high,t1); SET_LDOUBLE_MSW64(t1,high+(k<<48)); return t1*w; } else return w; } openlibm-0.5.0/ld128/e_lgammal_r.c000066400000000000000000000765371266752446200166160ustar00rootroot00000000000000/* $OpenBSD: e_lgammal.c,v 1.3 2011/07/09 05:29:06 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* lgammal_r * * Natural logarithm of gamma function * * * * SYNOPSIS: * * long double x, y, lgammal_r(); * int signgam; * * y = lgammal_r(x, &signgam); * * * * DESCRIPTION: * * Returns the base e (2.718...) logarithm of the absolute * value of the gamma function of the argument. * The sign (+1 or -1) of the gamma function is returned through signgamp. * * The positive domain is partitioned into numerous segments for approximation. * For x > 10, * log gamma(x) = (x - 0.5) log(x) - x + log sqrt(2 pi) + 1/x R(1/x^2) * Near the minimum at x = x0 = 1.46... the approximation is * log gamma(x0 + z) = log gamma(x0) + z^2 P(z)/Q(z) * for small z. * Elsewhere between 0 and 10, * log gamma(n + z) = log gamma(n) + z P(z)/Q(z) * for various selected n and small z. * * The cosecant reflection formula is employed for negative arguments. * * * * ACCURACY: * * * arithmetic domain # trials peak rms * Relative error: * IEEE 10, 30 100000 3.9e-34 9.8e-35 * IEEE 0, 10 100000 3.8e-34 5.3e-35 * Absolute error: * IEEE -10, 0 100000 8.0e-34 8.0e-35 * IEEE -30, -10 100000 4.4e-34 1.0e-34 * IEEE -100, 100 100000 1.0e-34 * * The absolute error criterion is the same as relative error * when the function magnitude is greater than one but it is absolute * when the magnitude is less than one. * */ #include #include "math_private.h" static const long double PIL = 3.1415926535897932384626433832795028841972E0L; static const long double MAXLGM = 1.0485738685148938358098967157129705071571E4928L; static const long double one = 1.0L; static const long double huge = 1.0e4000L; /* log gamma(x) = ( x - 0.5 ) * log(x) - x + LS2PI + 1/x P(1/x^2) 1/x <= 0.0741 (x >= 13.495...) Peak relative error 1.5e-36 */ static const long double ls2pi = 9.1893853320467274178032973640561763986140E-1L; #define NRASY 12 static const long double RASY[NRASY + 1] = { 8.333333333333333333333333333310437112111E-2L, -2.777777777777777777777774789556228296902E-3L, 7.936507936507936507795933938448586499183E-4L, -5.952380952380952041799269756378148574045E-4L, 8.417508417507928904209891117498524452523E-4L, -1.917526917481263997778542329739806086290E-3L, 6.410256381217852504446848671499409919280E-3L, -2.955064066900961649768101034477363301626E-2L, 1.796402955865634243663453415388336954675E-1L, -1.391522089007758553455753477688592767741E0L, 1.326130089598399157988112385013829305510E1L, -1.420412699593782497803472576479997819149E2L, 1.218058922427762808938869872528846787020E3L }; /* log gamma(x+13) = log gamma(13) + x P(x)/Q(x) -0.5 <= x <= 0.5 12.5 <= x+13 <= 13.5 Peak relative error 1.1e-36 */ static const long double lgam13a = 1.9987213134765625E1L; static const long double lgam13b = 1.3608962611495173623870550785125024484248E-6L; #define NRN13 7 static const long double RN13[NRN13 + 1] = { 8.591478354823578150238226576156275285700E11L, 2.347931159756482741018258864137297157668E11L, 2.555408396679352028680662433943000804616E10L, 1.408581709264464345480765758902967123937E9L, 4.126759849752613822953004114044451046321E7L, 6.133298899622688505854211579222889943778E5L, 3.929248056293651597987893340755876578072E3L, 6.850783280018706668924952057996075215223E0L }; #define NRD13 6 static const long double RD13[NRD13 + 1] = { 3.401225382297342302296607039352935541669E11L, 8.756765276918037910363513243563234551784E10L, 8.873913342866613213078554180987647243903E9L, 4.483797255342763263361893016049310017973E8L, 1.178186288833066430952276702931512870676E7L, 1.519928623743264797939103740132278337476E5L, 7.989298844938119228411117593338850892311E2L /* 1.0E0L */ }; /* log gamma(x+12) = log gamma(12) + x P(x)/Q(x) -0.5 <= x <= 0.5 11.5 <= x+12 <= 12.5 Peak relative error 4.1e-36 */ static const long double lgam12a = 1.75023040771484375E1L; static const long double lgam12b = 3.7687254483392876529072161996717039575982E-6L; #define NRN12 7 static const long double RN12[NRN12 + 1] = { 4.709859662695606986110997348630997559137E11L, 1.398713878079497115037857470168777995230E11L, 1.654654931821564315970930093932954900867E10L, 9.916279414876676861193649489207282144036E8L, 3.159604070526036074112008954113411389879E7L, 5.109099197547205212294747623977502492861E5L, 3.563054878276102790183396740969279826988E3L, 6.769610657004672719224614163196946862747E0L }; #define NRD12 6 static const long double RD12[NRD12 + 1] = { 1.928167007860968063912467318985802726613E11L, 5.383198282277806237247492369072266389233E10L, 5.915693215338294477444809323037871058363E9L, 3.241438287570196713148310560147925781342E8L, 9.236680081763754597872713592701048455890E6L, 1.292246897881650919242713651166596478850E5L, 7.366532445427159272584194816076600211171E2L /* 1.0E0L */ }; /* log gamma(x+11) = log gamma(11) + x P(x)/Q(x) -0.5 <= x <= 0.5 10.5 <= x+11 <= 11.5 Peak relative error 1.8e-35 */ static const long double lgam11a = 1.5104400634765625E1L; static const long double lgam11b = 1.1938309890295225709329251070371882250744E-5L; #define NRN11 7 static const long double RN11[NRN11 + 1] = { 2.446960438029415837384622675816736622795E11L, 7.955444974446413315803799763901729640350E10L, 1.030555327949159293591618473447420338444E10L, 6.765022131195302709153994345470493334946E8L, 2.361892792609204855279723576041468347494E7L, 4.186623629779479136428005806072176490125E5L, 3.202506022088912768601325534149383594049E3L, 6.681356101133728289358838690666225691363E0L }; #define NRD11 6 static const long double RD11[NRD11 + 1] = { 1.040483786179428590683912396379079477432E11L, 3.172251138489229497223696648369823779729E10L, 3.806961885984850433709295832245848084614E9L, 2.278070344022934913730015420611609620171E8L, 7.089478198662651683977290023829391596481E6L, 1.083246385105903533237139380509590158658E5L, 6.744420991491385145885727942219463243597E2L /* 1.0E0L */ }; /* log gamma(x+10) = log gamma(10) + x P(x)/Q(x) -0.5 <= x <= 0.5 9.5 <= x+10 <= 10.5 Peak relative error 5.4e-37 */ static const long double lgam10a = 1.280181884765625E1L; static const long double lgam10b = 8.6324252196112077178745667061642811492557E-6L; #define NRN10 7 static const long double RN10[NRN10 + 1] = { -1.239059737177249934158597996648808363783E14L, -4.725899566371458992365624673357356908719E13L, -7.283906268647083312042059082837754850808E12L, -5.802855515464011422171165179767478794637E11L, -2.532349691157548788382820303182745897298E10L, -5.884260178023777312587193693477072061820E8L, -6.437774864512125749845840472131829114906E6L, -2.350975266781548931856017239843273049384E4L }; #define NRD10 7 static const long double RD10[NRD10 + 1] = { -5.502645997581822567468347817182347679552E13L, -1.970266640239849804162284805400136473801E13L, -2.819677689615038489384974042561531409392E12L, -2.056105863694742752589691183194061265094E11L, -8.053670086493258693186307810815819662078E9L, -1.632090155573373286153427982504851867131E8L, -1.483575879240631280658077826889223634921E6L, -4.002806669713232271615885826373550502510E3L /* 1.0E0L */ }; /* log gamma(x+9) = log gamma(9) + x P(x)/Q(x) -0.5 <= x <= 0.5 8.5 <= x+9 <= 9.5 Peak relative error 3.6e-36 */ static const long double lgam9a = 1.06045989990234375E1L; static const long double lgam9b = 3.9037218127284172274007216547549861681400E-6L; #define NRN9 7 static const long double RN9[NRN9 + 1] = { -4.936332264202687973364500998984608306189E13L, -2.101372682623700967335206138517766274855E13L, -3.615893404644823888655732817505129444195E12L, -3.217104993800878891194322691860075472926E11L, -1.568465330337375725685439173603032921399E10L, -4.073317518162025744377629219101510217761E8L, -4.983232096406156139324846656819246974500E6L, -2.036280038903695980912289722995505277253E4L }; #define NRD9 7 static const long double RD9[NRD9 + 1] = { -2.306006080437656357167128541231915480393E13L, -9.183606842453274924895648863832233799950E12L, -1.461857965935942962087907301194381010380E12L, -1.185728254682789754150068652663124298303E11L, -5.166285094703468567389566085480783070037E9L, -1.164573656694603024184768200787835094317E8L, -1.177343939483908678474886454113163527909E6L, -3.529391059783109732159524500029157638736E3L /* 1.0E0L */ }; /* log gamma(x+8) = log gamma(8) + x P(x)/Q(x) -0.5 <= x <= 0.5 7.5 <= x+8 <= 8.5 Peak relative error 2.4e-37 */ static const long double lgam8a = 8.525146484375E0L; static const long double lgam8b = 1.4876690414300165531036347125050759667737E-5L; #define NRN8 8 static const long double RN8[NRN8 + 1] = { 6.600775438203423546565361176829139703289E11L, 3.406361267593790705240802723914281025800E11L, 7.222460928505293914746983300555538432830E10L, 8.102984106025088123058747466840656458342E9L, 5.157620015986282905232150979772409345927E8L, 1.851445288272645829028129389609068641517E7L, 3.489261702223124354745894067468953756656E5L, 2.892095396706665774434217489775617756014E3L, 6.596977510622195827183948478627058738034E0L }; #define NRD8 7 static const long double RD8[NRD8 + 1] = { 3.274776546520735414638114828622673016920E11L, 1.581811207929065544043963828487733970107E11L, 3.108725655667825188135393076860104546416E10L, 3.193055010502912617128480163681842165730E9L, 1.830871482669835106357529710116211541839E8L, 5.790862854275238129848491555068073485086E6L, 9.305213264307921522842678835618803553589E4L, 6.216974105861848386918949336819572333622E2L /* 1.0E0L */ }; /* log gamma(x+7) = log gamma(7) + x P(x)/Q(x) -0.5 <= x <= 0.5 6.5 <= x+7 <= 7.5 Peak relative error 3.2e-36 */ static const long double lgam7a = 6.5792388916015625E0L; static const long double lgam7b = 1.2320408538495060178292903945321122583007E-5L; #define NRN7 8 static const long double RN7[NRN7 + 1] = { 2.065019306969459407636744543358209942213E11L, 1.226919919023736909889724951708796532847E11L, 2.996157990374348596472241776917953749106E10L, 3.873001919306801037344727168434909521030E9L, 2.841575255593761593270885753992732145094E8L, 1.176342515359431913664715324652399565551E7L, 2.558097039684188723597519300356028511547E5L, 2.448525238332609439023786244782810774702E3L, 6.460280377802030953041566617300902020435E0L }; #define NRD7 7 static const long double RD7[NRD7 + 1] = { 1.102646614598516998880874785339049304483E11L, 6.099297512712715445879759589407189290040E10L, 1.372898136289611312713283201112060238351E10L, 1.615306270420293159907951633566635172343E9L, 1.061114435798489135996614242842561967459E8L, 3.845638971184305248268608902030718674691E6L, 7.081730675423444975703917836972720495507E4L, 5.423122582741398226693137276201344096370E2L /* 1.0E0L */ }; /* log gamma(x+6) = log gamma(6) + x P(x)/Q(x) -0.5 <= x <= 0.5 5.5 <= x+6 <= 6.5 Peak relative error 6.2e-37 */ static const long double lgam6a = 4.7874908447265625E0L; static const long double lgam6b = 8.9805548349424770093452324304839959231517E-7L; #define NRN6 8 static const long double RN6[NRN6 + 1] = { -3.538412754670746879119162116819571823643E13L, -2.613432593406849155765698121483394257148E13L, -8.020670732770461579558867891923784753062E12L, -1.322227822931250045347591780332435433420E12L, -1.262809382777272476572558806855377129513E11L, -7.015006277027660872284922325741197022467E9L, -2.149320689089020841076532186783055727299E8L, -3.167210585700002703820077565539658995316E6L, -1.576834867378554185210279285358586385266E4L }; #define NRD6 8 static const long double RD6[NRD6 + 1] = { -2.073955870771283609792355579558899389085E13L, -1.421592856111673959642750863283919318175E13L, -4.012134994918353924219048850264207074949E12L, -6.013361045800992316498238470888523722431E11L, -5.145382510136622274784240527039643430628E10L, -2.510575820013409711678540476918249524123E9L, -6.564058379709759600836745035871373240904E7L, -7.861511116647120540275354855221373571536E5L, -2.821943442729620524365661338459579270561E3L /* 1.0E0L */ }; /* log gamma(x+5) = log gamma(5) + x P(x)/Q(x) -0.5 <= x <= 0.5 4.5 <= x+5 <= 5.5 Peak relative error 3.4e-37 */ static const long double lgam5a = 3.17803955078125E0L; static const long double lgam5b = 1.4279566695619646941601297055408873990961E-5L; #define NRN5 9 static const long double RN5[NRN5 + 1] = { 2.010952885441805899580403215533972172098E11L, 1.916132681242540921354921906708215338584E11L, 7.679102403710581712903937970163206882492E10L, 1.680514903671382470108010973615268125169E10L, 2.181011222911537259440775283277711588410E9L, 1.705361119398837808244780667539728356096E8L, 7.792391565652481864976147945997033946360E6L, 1.910741381027985291688667214472560023819E5L, 2.088138241893612679762260077783794329559E3L, 6.330318119566998299106803922739066556550E0L }; #define NRD5 8 static const long double RD5[NRD5 + 1] = { 1.335189758138651840605141370223112376176E11L, 1.174130445739492885895466097516530211283E11L, 4.308006619274572338118732154886328519910E10L, 8.547402888692578655814445003283720677468E9L, 9.934628078575618309542580800421370730906E8L, 6.847107420092173812998096295422311820672E7L, 2.698552646016599923609773122139463150403E6L, 5.526516251532464176412113632726150253215E4L, 4.772343321713697385780533022595450486932E2L /* 1.0E0L */ }; /* log gamma(x+4) = log gamma(4) + x P(x)/Q(x) -0.5 <= x <= 0.5 3.5 <= x+4 <= 4.5 Peak relative error 6.7e-37 */ static const long double lgam4a = 1.791748046875E0L; static const long double lgam4b = 1.1422353055000812477358380702272722990692E-5L; #define NRN4 9 static const long double RN4[NRN4 + 1] = { -1.026583408246155508572442242188887829208E13L, -1.306476685384622809290193031208776258809E13L, -7.051088602207062164232806511992978915508E12L, -2.100849457735620004967624442027793656108E12L, -3.767473790774546963588549871673843260569E11L, -4.156387497364909963498394522336575984206E10L, -2.764021460668011732047778992419118757746E9L, -1.036617204107109779944986471142938641399E8L, -1.895730886640349026257780896972598305443E6L, -1.180509051468390914200720003907727988201E4L }; #define NRD4 9 static const long double RD4[NRD4 + 1] = { -8.172669122056002077809119378047536240889E12L, -9.477592426087986751343695251801814226960E12L, -4.629448850139318158743900253637212801682E12L, -1.237965465892012573255370078308035272942E12L, -1.971624313506929845158062177061297598956E11L, -1.905434843346570533229942397763361493610E10L, -1.089409357680461419743730978512856675984E9L, -3.416703082301143192939774401370222822430E7L, -4.981791914177103793218433195857635265295E5L, -2.192507743896742751483055798411231453733E3L /* 1.0E0L */ }; /* log gamma(x+3) = log gamma(3) + x P(x)/Q(x) -0.25 <= x <= 0.5 2.75 <= x+3 <= 3.5 Peak relative error 6.0e-37 */ static const long double lgam3a = 6.93145751953125E-1L; static const long double lgam3b = 1.4286068203094172321214581765680755001344E-6L; #define NRN3 9 static const long double RN3[NRN3 + 1] = { -4.813901815114776281494823863935820876670E11L, -8.425592975288250400493910291066881992620E11L, -6.228685507402467503655405482985516909157E11L, -2.531972054436786351403749276956707260499E11L, -6.170200796658926701311867484296426831687E10L, -9.211477458528156048231908798456365081135E9L, -8.251806236175037114064561038908691305583E8L, -4.147886355917831049939930101151160447495E7L, -1.010851868928346082547075956946476932162E6L, -8.333374463411801009783402800801201603736E3L }; #define NRD3 9 static const long double RD3[NRD3 + 1] = { -5.216713843111675050627304523368029262450E11L, -8.014292925418308759369583419234079164391E11L, -5.180106858220030014546267824392678611990E11L, -1.830406975497439003897734969120997840011E11L, -3.845274631904879621945745960119924118925E10L, -4.891033385370523863288908070309417710903E9L, -3.670172254411328640353855768698287474282E8L, -1.505316381525727713026364396635522516989E7L, -2.856327162923716881454613540575964890347E5L, -1.622140448015769906847567212766206894547E3L /* 1.0E0L */ }; /* log gamma(x+2.5) = log gamma(2.5) + x P(x)/Q(x) -0.125 <= x <= 0.25 2.375 <= x+2.5 <= 2.75 */ static const long double lgam2r5a = 2.8466796875E-1L; static const long double lgam2r5b = 1.4901722919159632494669682701924320137696E-5L; #define NRN2r5 8 static const long double RN2r5[NRN2r5 + 1] = { -4.676454313888335499356699817678862233205E9L, -9.361888347911187924389905984624216340639E9L, -7.695353600835685037920815799526540237703E9L, -3.364370100981509060441853085968900734521E9L, -8.449902011848163568670361316804900559863E8L, -1.225249050950801905108001246436783022179E8L, -9.732972931077110161639900388121650470926E6L, -3.695711763932153505623248207576425983573E5L, -4.717341584067827676530426007495274711306E3L }; #define NRD2r5 8 static const long double RD2r5[NRD2r5 + 1] = { -6.650657966618993679456019224416926875619E9L, -1.099511409330635807899718829033488771623E10L, -7.482546968307837168164311101447116903148E9L, -2.702967190056506495988922973755870557217E9L, -5.570008176482922704972943389590409280950E8L, -6.536934032192792470926310043166993233231E7L, -4.101991193844953082400035444146067511725E6L, -1.174082735875715802334430481065526664020E5L, -9.932840389994157592102947657277692978511E2L /* 1.0E0L */ }; /* log gamma(x+2) = x P(x)/Q(x) -0.125 <= x <= +0.375 1.875 <= x+2 <= 2.375 Peak relative error 4.6e-36 */ #define NRN2 9 static const long double RN2[NRN2 + 1] = { -3.716661929737318153526921358113793421524E9L, -1.138816715030710406922819131397532331321E10L, -1.421017419363526524544402598734013569950E10L, -9.510432842542519665483662502132010331451E9L, -3.747528562099410197957514973274474767329E9L, -8.923565763363912474488712255317033616626E8L, -1.261396653700237624185350402781338231697E8L, -9.918402520255661797735331317081425749014E6L, -3.753996255897143855113273724233104768831E5L, -4.778761333044147141559311805999540765612E3L }; #define NRD2 9 static const long double RD2[NRD2 + 1] = { -8.790916836764308497770359421351673950111E9L, -2.023108608053212516399197678553737477486E10L, -1.958067901852022239294231785363504458367E10L, -1.035515043621003101254252481625188704529E10L, -3.253884432621336737640841276619272224476E9L, -6.186383531162456814954947669274235815544E8L, -6.932557847749518463038934953605969951466E7L, -4.240731768287359608773351626528479703758E6L, -1.197343995089189188078944689846348116630E5L, -1.004622911670588064824904487064114090920E3L /* 1.0E0 */ }; /* log gamma(x+1.75) = log gamma(1.75) + x P(x)/Q(x) -0.125 <= x <= +0.125 1.625 <= x+1.75 <= 1.875 Peak relative error 9.2e-37 */ static const long double lgam1r75a = -8.441162109375E-2L; static const long double lgam1r75b = 1.0500073264444042213965868602268256157604E-5L; #define NRN1r75 8 static const long double RN1r75[NRN1r75 + 1] = { -5.221061693929833937710891646275798251513E7L, -2.052466337474314812817883030472496436993E8L, -2.952718275974940270675670705084125640069E8L, -2.132294039648116684922965964126389017840E8L, -8.554103077186505960591321962207519908489E7L, -1.940250901348870867323943119132071960050E7L, -2.379394147112756860769336400290402208435E6L, -1.384060879999526222029386539622255797389E5L, -2.698453601378319296159355612094598695530E3L }; #define NRD1r75 8 static const long double RD1r75[NRD1r75 + 1] = { -2.109754689501705828789976311354395393605E8L, -5.036651829232895725959911504899241062286E8L, -4.954234699418689764943486770327295098084E8L, -2.589558042412676610775157783898195339410E8L, -7.731476117252958268044969614034776883031E7L, -1.316721702252481296030801191240867486965E7L, -1.201296501404876774861190604303728810836E6L, -5.007966406976106636109459072523610273928E4L, -6.155817990560743422008969155276229018209E2L /* 1.0E0L */ }; /* log gamma(x+x0) = y0 + x^2 P(x)/Q(x) -0.0867 <= x <= +0.1634 1.374932... <= x+x0 <= 1.625032... Peak relative error 4.0e-36 */ static const long double x0a = 1.4616241455078125L; static const long double x0b = 7.9994605498412626595423257213002588621246E-6L; static const long double y0a = -1.21490478515625E-1L; static const long double y0b = 4.1879797753919044854428223084178486438269E-6L; #define NRN1r5 8 static const long double RN1r5[NRN1r5 + 1] = { 6.827103657233705798067415468881313128066E5L, 1.910041815932269464714909706705242148108E6L, 2.194344176925978377083808566251427771951E6L, 1.332921400100891472195055269688876427962E6L, 4.589080973377307211815655093824787123508E5L, 8.900334161263456942727083580232613796141E4L, 9.053840838306019753209127312097612455236E3L, 4.053367147553353374151852319743594873771E2L, 5.040631576303952022968949605613514584950E0L }; #define NRD1r5 8 static const long double RD1r5[NRD1r5 + 1] = { 1.411036368843183477558773688484699813355E6L, 4.378121767236251950226362443134306184849E6L, 5.682322855631723455425929877581697918168E6L, 3.999065731556977782435009349967042222375E6L, 1.653651390456781293163585493620758410333E6L, 4.067774359067489605179546964969435858311E5L, 5.741463295366557346748361781768833633256E4L, 4.226404539738182992856094681115746692030E3L, 1.316980975410327975566999780608618774469E2L, /* 1.0E0L */ }; /* log gamma(x+1.25) = log gamma(1.25) + x P(x)/Q(x) -.125 <= x <= +.125 1.125 <= x+1.25 <= 1.375 Peak relative error = 4.9e-36 */ static const long double lgam1r25a = -9.82818603515625E-2L; static const long double lgam1r25b = 1.0023929749338536146197303364159774377296E-5L; #define NRN1r25 9 static const long double RN1r25[NRN1r25 + 1] = { -9.054787275312026472896002240379580536760E4L, -8.685076892989927640126560802094680794471E4L, 2.797898965448019916967849727279076547109E5L, 6.175520827134342734546868356396008898299E5L, 5.179626599589134831538516906517372619641E5L, 2.253076616239043944538380039205558242161E5L, 5.312653119599957228630544772499197307195E4L, 6.434329437514083776052669599834938898255E3L, 3.385414416983114598582554037612347549220E2L, 4.907821957946273805080625052510832015792E0L }; #define NRD1r25 8 static const long double RD1r25[NRD1r25 + 1] = { 3.980939377333448005389084785896660309000E5L, 1.429634893085231519692365775184490465542E6L, 2.145438946455476062850151428438668234336E6L, 1.743786661358280837020848127465970357893E6L, 8.316364251289743923178092656080441655273E5L, 2.355732939106812496699621491135458324294E5L, 3.822267399625696880571810137601310855419E4L, 3.228463206479133236028576845538387620856E3L, 1.152133170470059555646301189220117965514E2L /* 1.0E0L */ }; /* log gamma(x + 1) = x P(x)/Q(x) 0.0 <= x <= +0.125 1.0 <= x+1 <= 1.125 Peak relative error 1.1e-35 */ #define NRN1 8 static const long double RN1[NRN1 + 1] = { -9.987560186094800756471055681088744738818E3L, -2.506039379419574361949680225279376329742E4L, -1.386770737662176516403363873617457652991E4L, 1.439445846078103202928677244188837130744E4L, 2.159612048879650471489449668295139990693E4L, 1.047439813638144485276023138173676047079E4L, 2.250316398054332592560412486630769139961E3L, 1.958510425467720733041971651126443864041E2L, 4.516830313569454663374271993200291219855E0L }; #define NRD1 7 static const long double RD1[NRD1 + 1] = { 1.730299573175751778863269333703788214547E4L, 6.807080914851328611903744668028014678148E4L, 1.090071629101496938655806063184092302439E5L, 9.124354356415154289343303999616003884080E4L, 4.262071638655772404431164427024003253954E4L, 1.096981664067373953673982635805821283581E4L, 1.431229503796575892151252708527595787588E3L, 7.734110684303689320830401788262295992921E1L /* 1.0E0 */ }; /* log gamma(x + 1) = x P(x)/Q(x) -0.125 <= x <= 0 0.875 <= x+1 <= 1.0 Peak relative error 7.0e-37 */ #define NRNr9 8 static const long double RNr9[NRNr9 + 1] = { 4.441379198241760069548832023257571176884E5L, 1.273072988367176540909122090089580368732E6L, 9.732422305818501557502584486510048387724E5L, -5.040539994443998275271644292272870348684E5L, -1.208719055525609446357448132109723786736E6L, -7.434275365370936547146540554419058907156E5L, -2.075642969983377738209203358199008185741E5L, -2.565534860781128618589288075109372218042E4L, -1.032901669542994124131223797515913955938E3L, }; #define NRDr9 8 static const long double RDr9[NRDr9 + 1] = { -7.694488331323118759486182246005193998007E5L, -3.301918855321234414232308938454112213751E6L, -5.856830900232338906742924836032279404702E6L, -5.540672519616151584486240871424021377540E6L, -3.006530901041386626148342989181721176919E6L, -9.350378280513062139466966374330795935163E5L, -1.566179100031063346901755685375732739511E5L, -1.205016539620260779274902967231510804992E4L, -2.724583156305709733221564484006088794284E2L /* 1.0E0 */ }; /* Evaluate P[n] x^n + P[n-1] x^(n-1) + ... + P[0] */ static long double neval (long double x, const long double *p, int n) { long double y; p += n; y = *p--; do { y = y * x + *p--; } while (--n > 0); return y; } /* Evaluate x^n+1 + P[n] x^(n) + P[n-1] x^(n-1) + ... + P[0] */ static long double deval (long double x, const long double *p, int n) { long double y; p += n; y = x + *p--; do { y = y * x + *p--; } while (--n > 0); return y; } long double lgammal_r(long double x, int *signgamp) { long double p, q, w, z, nx; int i, nn; *signgamp = 1; if (!isfinite (x)) return x * x; if (x == 0.0L) { if (signbit (x)) *signgamp = -1; return one / fabsl (x); } if (x < 0.0L) { q = -x; p = floorl (q); if (p == q) return (one / (p - p)); i = p; if ((i & 1) == 0) *signgamp = -1; else *signgamp = 1; z = q - p; if (z > 0.5L) { p += 1.0L; z = p - q; } z = q * sinl (PIL * z); if (z == 0.0L) return (*signgamp * huge * huge); w = lgammal (q); z = logl (PIL / z) - w; return (z); } if (x < 13.5L) { p = 0.0L; nx = floorl (x + 0.5L); nn = nx; switch (nn) { case 0: /* log gamma (x + 1) = log(x) + log gamma(x) */ if (x <= 0.125) { p = x * neval (x, RN1, NRN1) / deval (x, RD1, NRD1); } else if (x <= 0.375) { z = x - 0.25L; p = z * neval (z, RN1r25, NRN1r25) / deval (z, RD1r25, NRD1r25); p += lgam1r25b; p += lgam1r25a; } else if (x <= 0.625) { z = x + (1.0L - x0a); z = z - x0b; p = neval (z, RN1r5, NRN1r5) / deval (z, RD1r5, NRD1r5); p = p * z * z; p = p + y0b; p = p + y0a; } else if (x <= 0.875) { z = x - 0.75L; p = z * neval (z, RN1r75, NRN1r75) / deval (z, RD1r75, NRD1r75); p += lgam1r75b; p += lgam1r75a; } else { z = x - 1.0L; p = z * neval (z, RN2, NRN2) / deval (z, RD2, NRD2); } p = p - logl (x); break; case 1: if (x < 0.875L) { if (x <= 0.625) { z = x + (1.0L - x0a); z = z - x0b; p = neval (z, RN1r5, NRN1r5) / deval (z, RD1r5, NRD1r5); p = p * z * z; p = p + y0b; p = p + y0a; } else if (x <= 0.875) { z = x - 0.75L; p = z * neval (z, RN1r75, NRN1r75) / deval (z, RD1r75, NRD1r75); p += lgam1r75b; p += lgam1r75a; } else { z = x - 1.0L; p = z * neval (z, RN2, NRN2) / deval (z, RD2, NRD2); } p = p - logl (x); } else if (x < 1.0L) { z = x - 1.0L; p = z * neval (z, RNr9, NRNr9) / deval (z, RDr9, NRDr9); } else if (x == 1.0L) p = 0.0L; else if (x <= 1.125L) { z = x - 1.0L; p = z * neval (z, RN1, NRN1) / deval (z, RD1, NRD1); } else if (x <= 1.375) { z = x - 1.25L; p = z * neval (z, RN1r25, NRN1r25) / deval (z, RD1r25, NRD1r25); p += lgam1r25b; p += lgam1r25a; } else { /* 1.375 <= x+x0 <= 1.625 */ z = x - x0a; z = z - x0b; p = neval (z, RN1r5, NRN1r5) / deval (z, RD1r5, NRD1r5); p = p * z * z; p = p + y0b; p = p + y0a; } break; case 2: if (x < 1.625L) { z = x - x0a; z = z - x0b; p = neval (z, RN1r5, NRN1r5) / deval (z, RD1r5, NRD1r5); p = p * z * z; p = p + y0b; p = p + y0a; } else if (x < 1.875L) { z = x - 1.75L; p = z * neval (z, RN1r75, NRN1r75) / deval (z, RD1r75, NRD1r75); p += lgam1r75b; p += lgam1r75a; } else if (x == 2.0L) p = 0.0L; else if (x < 2.375L) { z = x - 2.0L; p = z * neval (z, RN2, NRN2) / deval (z, RD2, NRD2); } else { z = x - 2.5L; p = z * neval (z, RN2r5, NRN2r5) / deval (z, RD2r5, NRD2r5); p += lgam2r5b; p += lgam2r5a; } break; case 3: if (x < 2.75) { z = x - 2.5L; p = z * neval (z, RN2r5, NRN2r5) / deval (z, RD2r5, NRD2r5); p += lgam2r5b; p += lgam2r5a; } else { z = x - 3.0L; p = z * neval (z, RN3, NRN3) / deval (z, RD3, NRD3); p += lgam3b; p += lgam3a; } break; case 4: z = x - 4.0L; p = z * neval (z, RN4, NRN4) / deval (z, RD4, NRD4); p += lgam4b; p += lgam4a; break; case 5: z = x - 5.0L; p = z * neval (z, RN5, NRN5) / deval (z, RD5, NRD5); p += lgam5b; p += lgam5a; break; case 6: z = x - 6.0L; p = z * neval (z, RN6, NRN6) / deval (z, RD6, NRD6); p += lgam6b; p += lgam6a; break; case 7: z = x - 7.0L; p = z * neval (z, RN7, NRN7) / deval (z, RD7, NRD7); p += lgam7b; p += lgam7a; break; case 8: z = x - 8.0L; p = z * neval (z, RN8, NRN8) / deval (z, RD8, NRD8); p += lgam8b; p += lgam8a; break; case 9: z = x - 9.0L; p = z * neval (z, RN9, NRN9) / deval (z, RD9, NRD9); p += lgam9b; p += lgam9a; break; case 10: z = x - 10.0L; p = z * neval (z, RN10, NRN10) / deval (z, RD10, NRD10); p += lgam10b; p += lgam10a; break; case 11: z = x - 11.0L; p = z * neval (z, RN11, NRN11) / deval (z, RD11, NRD11); p += lgam11b; p += lgam11a; break; case 12: z = x - 12.0L; p = z * neval (z, RN12, NRN12) / deval (z, RD12, NRD12); p += lgam12b; p += lgam12a; break; case 13: z = x - 13.0L; p = z * neval (z, RN13, NRN13) / deval (z, RD13, NRD13); p += lgam13b; p += lgam13a; break; } return p; } if (x > MAXLGM) return (*signgamp * huge * huge); q = ls2pi - x; q = (x - 0.5L) * logl (x) + q; if (x > 1.0e18L) return (q); p = 1.0L / (x * x); q += neval (p, RASY, NRASY) / x; return (q); } openlibm-0.5.0/ld128/e_log10l.c000066400000000000000000000144251266752446200157450ustar00rootroot00000000000000/* $OpenBSD: e_log10l.c,v 1.1 2011/07/06 00:02:42 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* log10l.c * * Common logarithm, 128-bit long double precision * * * * SYNOPSIS: * * long double x, y, log10l(); * * y = log10l( x ); * * * * DESCRIPTION: * * Returns the base 10 logarithm of x. * * The argument is separated into its exponent and fractional * parts. If the exponent is between -1 and +1, the logarithm * of the fraction is approximated by * * log(1+x) = x - 0.5 x^2 + x^3 P(x)/Q(x). * * Otherwise, setting z = 2(x-1)/x+1), * * log(x) = z + z^3 P(z)/Q(z). * * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE 0.5, 2.0 30000 2.3e-34 4.9e-35 * IEEE exp(+-10000) 30000 1.0e-34 4.1e-35 * * In the tests over the interval exp(+-10000), the logarithms * of the random arguments were uniformly distributed over * [-10000, +10000]. * */ #include #include "math_private.h" /* Coefficients for ln(1+x) = x - x**2/2 + x**3 P(x)/Q(x) * 1/sqrt(2) <= x < sqrt(2) * Theoretical peak relative error = 5.3e-37, * relative peak error spread = 2.3e-14 */ static const long double P[13] = { 1.313572404063446165910279910527789794488E4L, 7.771154681358524243729929227226708890930E4L, 2.014652742082537582487669938141683759923E5L, 3.007007295140399532324943111654767187848E5L, 2.854829159639697837788887080758954924001E5L, 1.797628303815655343403735250238293741397E5L, 7.594356839258970405033155585486712125861E4L, 2.128857716871515081352991964243375186031E4L, 3.824952356185897735160588078446136783779E3L, 4.114517881637811823002128927449878962058E2L, 2.321125933898420063925789532045674660756E1L, 4.998469661968096229986658302195402690910E-1L, 1.538612243596254322971797716843006400388E-6L }; static const long double Q[12] = { 3.940717212190338497730839731583397586124E4L, 2.626900195321832660448791748036714883242E5L, 7.777690340007566932935753241556479363645E5L, 1.347518538384329112529391120390701166528E6L, 1.514882452993549494932585972882995548426E6L, 1.158019977462989115839826904108208787040E6L, 6.132189329546557743179177159925690841200E5L, 2.248234257620569139969141618556349415120E5L, 5.605842085972455027590989944010492125825E4L, 9.147150349299596453976674231612674085381E3L, 9.104928120962988414618126155557301584078E2L, 4.839208193348159620282142911143429644326E1L /* 1.000000000000000000000000000000000000000E0L, */ }; /* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2), * where z = 2(x-1)/(x+1) * 1/sqrt(2) <= x < sqrt(2) * Theoretical peak relative error = 1.1e-35, * relative peak error spread 1.1e-9 */ static const long double R[6] = { 1.418134209872192732479751274970992665513E5L, -8.977257995689735303686582344659576526998E4L, 2.048819892795278657810231591630928516206E4L, -2.024301798136027039250415126250455056397E3L, 8.057002716646055371965756206836056074715E1L, -8.828896441624934385266096344596648080902E-1L }; static const long double S[6] = { 1.701761051846631278975701529965589676574E6L, -1.332535117259762928288745111081235577029E6L, 4.001557694070773974936904547424676279307E5L, -5.748542087379434595104154610899551484314E4L, 3.998526750980007367835804959888064681098E3L, -1.186359407982897997337150403816839480438E2L /* 1.000000000000000000000000000000000000000E0L, */ }; static const long double /* log10(2) */ L102A = 0.3125L, L102B = -1.14700043360188047862611052755069732318101185E-2L, /* log10(e) */ L10EA = 0.5L, L10EB = -6.570551809674817234887108108339491770560299E-2L, /* sqrt(2)/2 */ SQRTH = 7.071067811865475244008443621048490392848359E-1L; /* Evaluate P[n] x^n + P[n-1] x^(n-1) + ... + P[0] */ static long double neval (long double x, const long double *p, int n) { long double y; p += n; y = *p--; do { y = y * x + *p--; } while (--n > 0); return y; } /* Evaluate x^n+1 + P[n] x^(n) + P[n-1] x^(n-1) + ... + P[0] */ static long double deval (long double x, const long double *p, int n) { long double y; p += n; y = x + *p--; do { y = y * x + *p--; } while (--n > 0); return y; } long double log10l(long double x) { long double z; long double y; int e; int64_t hx, lx; /* Test for domain */ GET_LDOUBLE_WORDS64 (hx, lx, x); if (((hx & 0x7fffffffffffffffLL) | lx) == 0) return (-1.0L / (x - x)); if (hx < 0) return (x - x) / (x - x); if (hx >= 0x7fff000000000000LL) return (x + x); /* separate mantissa from exponent */ /* Note, frexp is used so that denormal numbers * will be handled properly. */ x = frexpl (x, &e); /* logarithm using log(x) = z + z**3 P(z)/Q(z), * where z = 2(x-1)/x+1) */ if ((e > 2) || (e < -2)) { if (x < SQRTH) { /* 2( 2x-1 )/( 2x+1 ) */ e -= 1; z = x - 0.5L; y = 0.5L * z + 0.5L; } else { /* 2 (x-1)/(x+1) */ z = x - 0.5L; z -= 0.5L; y = 0.5L * x + 0.5L; } x = z / y; z = x * x; y = x * (z * neval (z, R, 5) / deval (z, S, 5)); goto done; } /* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */ if (x < SQRTH) { e -= 1; x = 2.0 * x - 1.0L; /* 2x - 1 */ } else { x = x - 1.0L; } z = x * x; y = x * (z * neval (x, P, 12) / deval (x, Q, 11)); y = y - 0.5 * z; done: /* Multiply log of fraction by log10(e) * and base 2 exponent by log10(2). */ z = y * L10EB; z += x * L10EB; z += e * L102B; z += y * L10EA; z += x * L10EA; z += e * L102A; return (z); } openlibm-0.5.0/ld128/e_log2l.c000066400000000000000000000142531266752446200156650ustar00rootroot00000000000000/* $OpenBSD: e_log2l.c,v 1.1 2011/07/06 00:02:42 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* log2l.c * Base 2 logarithm, 128-bit long double precision * * * * SYNOPSIS: * * long double x, y, log2l(); * * y = log2l( x ); * * * * DESCRIPTION: * * Returns the base 2 logarithm of x. * * The argument is separated into its exponent and fractional * parts. If the exponent is between -1 and +1, the (natural) * logarithm of the fraction is approximated by * * log(1+x) = x - 0.5 x^2 + x^3 P(x)/Q(x). * * Otherwise, setting z = 2(x-1)/x+1), * * log(x) = z + z^3 P(z)/Q(z). * * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE 0.5, 2.0 100,000 2.6e-34 4.9e-35 * IEEE exp(+-10000) 100,000 9.6e-35 4.0e-35 * * In the tests over the interval exp(+-10000), the logarithms * of the random arguments were uniformly distributed over * [-10000, +10000]. * */ #include #include "math_private.h" /* Coefficients for ln(1+x) = x - x**2/2 + x**3 P(x)/Q(x) * 1/sqrt(2) <= x < sqrt(2) * Theoretical peak relative error = 5.3e-37, * relative peak error spread = 2.3e-14 */ static const long double P[13] = { 1.313572404063446165910279910527789794488E4L, 7.771154681358524243729929227226708890930E4L, 2.014652742082537582487669938141683759923E5L, 3.007007295140399532324943111654767187848E5L, 2.854829159639697837788887080758954924001E5L, 1.797628303815655343403735250238293741397E5L, 7.594356839258970405033155585486712125861E4L, 2.128857716871515081352991964243375186031E4L, 3.824952356185897735160588078446136783779E3L, 4.114517881637811823002128927449878962058E2L, 2.321125933898420063925789532045674660756E1L, 4.998469661968096229986658302195402690910E-1L, 1.538612243596254322971797716843006400388E-6L }; static const long double Q[12] = { 3.940717212190338497730839731583397586124E4L, 2.626900195321832660448791748036714883242E5L, 7.777690340007566932935753241556479363645E5L, 1.347518538384329112529391120390701166528E6L, 1.514882452993549494932585972882995548426E6L, 1.158019977462989115839826904108208787040E6L, 6.132189329546557743179177159925690841200E5L, 2.248234257620569139969141618556349415120E5L, 5.605842085972455027590989944010492125825E4L, 9.147150349299596453976674231612674085381E3L, 9.104928120962988414618126155557301584078E2L, 4.839208193348159620282142911143429644326E1L /* 1.000000000000000000000000000000000000000E0L, */ }; /* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2), * where z = 2(x-1)/(x+1) * 1/sqrt(2) <= x < sqrt(2) * Theoretical peak relative error = 1.1e-35, * relative peak error spread 1.1e-9 */ static const long double R[6] = { 1.418134209872192732479751274970992665513E5L, -8.977257995689735303686582344659576526998E4L, 2.048819892795278657810231591630928516206E4L, -2.024301798136027039250415126250455056397E3L, 8.057002716646055371965756206836056074715E1L, -8.828896441624934385266096344596648080902E-1L }; static const long double S[6] = { 1.701761051846631278975701529965589676574E6L, -1.332535117259762928288745111081235577029E6L, 4.001557694070773974936904547424676279307E5L, -5.748542087379434595104154610899551484314E4L, 3.998526750980007367835804959888064681098E3L, -1.186359407982897997337150403816839480438E2L /* 1.000000000000000000000000000000000000000E0L, */ }; static const long double /* log2(e) - 1 */ LOG2EA = 4.4269504088896340735992468100189213742664595E-1L, /* sqrt(2)/2 */ SQRTH = 7.071067811865475244008443621048490392848359E-1L; /* Evaluate P[n] x^n + P[n-1] x^(n-1) + ... + P[0] */ static long double neval (long double x, const long double *p, int n) { long double y; p += n; y = *p--; do { y = y * x + *p--; } while (--n > 0); return y; } /* Evaluate x^n+1 + P[n] x^(n) + P[n-1] x^(n-1) + ... + P[0] */ static long double deval (long double x, const long double *p, int n) { long double y; p += n; y = x + *p--; do { y = y * x + *p--; } while (--n > 0); return y; } long double log2l(long double x) { long double z; long double y; int e; int64_t hx, lx; /* Test for domain */ GET_LDOUBLE_WORDS64 (hx, lx, x); if (((hx & 0x7fffffffffffffffLL) | lx) == 0) return (-1.0L / (x - x)); if (hx < 0) return (x - x) / (x - x); if (hx >= 0x7fff000000000000LL) return (x + x); /* separate mantissa from exponent */ /* Note, frexp is used so that denormal numbers * will be handled properly. */ x = frexpl (x, &e); /* logarithm using log(x) = z + z**3 P(z)/Q(z), * where z = 2(x-1)/x+1) */ if ((e > 2) || (e < -2)) { if (x < SQRTH) { /* 2( 2x-1 )/( 2x+1 ) */ e -= 1; z = x - 0.5L; y = 0.5L * z + 0.5L; } else { /* 2 (x-1)/(x+1) */ z = x - 0.5L; z -= 0.5L; y = 0.5L * x + 0.5L; } x = z / y; z = x * x; y = x * (z * neval (z, R, 5) / deval (z, S, 5)); goto done; } /* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */ if (x < SQRTH) { e -= 1; x = 2.0 * x - 1.0L; /* 2x - 1 */ } else { x = x - 1.0L; } z = x * x; y = x * (z * neval (x, P, 12) / deval (x, Q, 11)); y = y - 0.5 * z; done: /* Multiply log of fraction by log2(e) * and base 2 exponent by 1 */ z = y * LOG2EA; z += x * LOG2EA; z += y; z += x; z += e; return (z); } openlibm-0.5.0/ld128/e_logl.c000066400000000000000000000231011266752446200155730ustar00rootroot00000000000000/* $OpenBSD: e_logl.c,v 1.1 2011/07/06 00:02:42 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* logl.c * * Natural logarithm for 128-bit long double precision. * * * * SYNOPSIS: * * long double x, y, logl(); * * y = logl( x ); * * * * DESCRIPTION: * * Returns the base e (2.718...) logarithm of x. * * The argument is separated into its exponent and fractional * parts. Use of a lookup table increases the speed of the routine. * The program uses logarithms tabulated at intervals of 1/128 to * cover the domain from approximately 0.7 to 1.4. * * On the interval [-1/128, +1/128] the logarithm of 1+x is approximated by * log(1+x) = x - 0.5 x^2 + x^3 P(x) . * * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE 0.875, 1.125 100000 1.2e-34 4.1e-35 * IEEE 0.125, 8 100000 1.2e-34 4.1e-35 * * * WARNING: * * This program uses integer operations on bit fields of floating-point * numbers. It does not work with data structures other than the * structure assumed. * */ #include #include "math_private.h" /* log(1+x) = x - .5 x^2 + x^3 l(x) -.0078125 <= x <= +.0078125 peak relative error 1.2e-37 */ static const long double l3 = 3.333333333333333333333333333333336096926E-1L, l4 = -2.499999999999999999999999999486853077002E-1L, l5 = 1.999999999999999999999999998515277861905E-1L, l6 = -1.666666666666666666666798448356171665678E-1L, l7 = 1.428571428571428571428808945895490721564E-1L, l8 = -1.249999999999999987884655626377588149000E-1L, l9 = 1.111111111111111093947834982832456459186E-1L, l10 = -1.000000000000532974938900317952530453248E-1L, l11 = 9.090909090915566247008015301349979892689E-2L, l12 = -8.333333211818065121250921925397567745734E-2L, l13 = 7.692307559897661630807048686258659316091E-2L, l14 = -7.144242754190814657241902218399056829264E-2L, l15 = 6.668057591071739754844678883223432347481E-2L; /* Lookup table of ln(t) - (t-1) t = 0.5 + (k+26)/128) k = 0, ..., 91 */ static const long double logtbl[92] = { -5.5345593589352099112142921677820359632418E-2L, -5.2108257402767124761784665198737642086148E-2L, -4.8991686870576856279407775480686721935120E-2L, -4.5993270766361228596215288742353061431071E-2L, -4.3110481649613269682442058976885699556950E-2L, -4.0340872319076331310838085093194799765520E-2L, -3.7682072451780927439219005993827431503510E-2L, -3.5131785416234343803903228503274262719586E-2L, -3.2687785249045246292687241862699949178831E-2L, -3.0347913785027239068190798397055267411813E-2L, -2.8110077931525797884641940838507561326298E-2L, -2.5972247078357715036426583294246819637618E-2L, -2.3932450635346084858612873953407168217307E-2L, -2.1988775689981395152022535153795155900240E-2L, -2.0139364778244501615441044267387667496733E-2L, -1.8382413762093794819267536615342902718324E-2L, -1.6716169807550022358923589720001638093023E-2L, -1.5138929457710992616226033183958974965355E-2L, -1.3649036795397472900424896523305726435029E-2L, -1.2244881690473465543308397998034325468152E-2L, -1.0924898127200937840689817557742469105693E-2L, -9.6875626072830301572839422532631079809328E-3L, -8.5313926245226231463436209313499745894157E-3L, -7.4549452072765973384933565912143044991706E-3L, -6.4568155251217050991200599386801665681310E-3L, -5.5356355563671005131126851708522185605193E-3L, -4.6900728132525199028885749289712348829878E-3L, -3.9188291218610470766469347968659624282519E-3L, -3.2206394539524058873423550293617843896540E-3L, -2.5942708080877805657374888909297113032132E-3L, -2.0385211375711716729239156839929281289086E-3L, -1.5522183228760777967376942769773768850872E-3L, -1.1342191863606077520036253234446621373191E-3L, -7.8340854719967065861624024730268350459991E-4L, -4.9869831458030115699628274852562992756174E-4L, -2.7902661731604211834685052867305795169688E-4L, -1.2335696813916860754951146082826952093496E-4L, -3.0677461025892873184042490943581654591817E-5L, #define ZERO logtbl[38] 0.0000000000000000000000000000000000000000E0L, -3.0359557945051052537099938863236321874198E-5L, -1.2081346403474584914595395755316412213151E-4L, -2.7044071846562177120083903771008342059094E-4L, -4.7834133324631162897179240322783590830326E-4L, -7.4363569786340080624467487620270965403695E-4L, -1.0654639687057968333207323853366578860679E-3L, -1.4429854811877171341298062134712230604279E-3L, -1.8753781835651574193938679595797367137975E-3L, -2.3618380914922506054347222273705859653658E-3L, -2.9015787624124743013946600163375853631299E-3L, -3.4938307889254087318399313316921940859043E-3L, -4.1378413103128673800485306215154712148146E-3L, -4.8328735414488877044289435125365629849599E-3L, -5.5782063183564351739381962360253116934243E-3L, -6.3731336597098858051938306767880719015261E-3L, -7.2169643436165454612058905294782949315193E-3L, -8.1090214990427641365934846191367315083867E-3L, -9.0486422112807274112838713105168375482480E-3L, -1.0035177140880864314674126398350812606841E-2L, -1.1067990155502102718064936259435676477423E-2L, -1.2146457974158024928196575103115488672416E-2L, -1.3269969823361415906628825374158424754308E-2L, -1.4437927104692837124388550722759686270765E-2L, -1.5649743073340777659901053944852735064621E-2L, -1.6904842527181702880599758489058031645317E-2L, -1.8202661505988007336096407340750378994209E-2L, -1.9542647000370545390701192438691126552961E-2L, -2.0924256670080119637427928803038530924742E-2L, -2.2346958571309108496179613803760727786257E-2L, -2.3810230892650362330447187267648486279460E-2L, -2.5313561699385640380910474255652501521033E-2L, -2.6856448685790244233704909690165496625399E-2L, -2.8438398935154170008519274953860128449036E-2L, -3.0058928687233090922411781058956589863039E-2L, -3.1717563112854831855692484086486099896614E-2L, -3.3413836095418743219397234253475252001090E-2L, -3.5147290019036555862676702093393332533702E-2L, -3.6917475563073933027920505457688955423688E-2L, -3.8723951502862058660874073462456610731178E-2L, -4.0566284516358241168330505467000838017425E-2L, -4.2444048996543693813649967076598766917965E-2L, -4.4356826869355401653098777649745233339196E-2L, -4.6304207416957323121106944474331029996141E-2L, -4.8285787106164123613318093945035804818364E-2L, -5.0301169421838218987124461766244507342648E-2L, -5.2349964705088137924875459464622098310997E-2L, -5.4431789996103111613753440311680967840214E-2L, -5.6546268881465384189752786409400404404794E-2L, -5.8693031345788023909329239565012647817664E-2L, -6.0871713627532018185577188079210189048340E-2L, -6.3081958078862169742820420185833800925568E-2L, -6.5323413029406789694910800219643791556918E-2L, -6.7595732653791419081537811574227049288168E-2L }; /* ln(2) = ln2a + ln2b with extended precision. */ static const long double ln2a = 6.93145751953125e-1L, ln2b = 1.4286068203094172321214581765680755001344E-6L; long double logl(long double x) { long double z, y, w; ieee_quad_shape_type u, t; unsigned int m; int k, e; u.value = x; m = u.parts32.mswhi; /* Check for IEEE special cases. */ k = m & 0x7fffffff; /* log(0) = -infinity. */ if ((k | u.parts32.mswlo | u.parts32.lswhi | u.parts32.lswlo) == 0) { return -0.5L / ZERO; } /* log ( x < 0 ) = NaN */ if (m & 0x80000000) { return (x - x) / ZERO; } /* log (infinity or NaN) */ if (k >= 0x7fff0000) { return x + x; } /* Extract exponent and reduce domain to 0.703125 <= u < 1.40625 */ e = (int) (m >> 16) - (int) 0x3ffe; m &= 0xffff; u.parts32.mswhi = m | 0x3ffe0000; m |= 0x10000; /* Find lookup table index k from high order bits of the significand. */ if (m < 0x16800) { k = (m - 0xff00) >> 9; /* t is the argument 0.5 + (k+26)/128 of the nearest item to u in the lookup table. */ t.parts32.mswhi = 0x3fff0000 + (k << 9); t.parts32.mswlo = 0; t.parts32.lswhi = 0; t.parts32.lswlo = 0; u.parts32.mswhi += 0x10000; e -= 1; k += 64; } else { k = (m - 0xfe00) >> 10; t.parts32.mswhi = 0x3ffe0000 + (k << 10); t.parts32.mswlo = 0; t.parts32.lswhi = 0; t.parts32.lswlo = 0; } /* On this interval the table is not used due to cancellation error. */ if ((x <= 1.0078125L) && (x >= 0.9921875L)) { z = x - 1.0L; k = 64; t.value = 1.0L; e = 0; } else { /* log(u) = log( t u/t ) = log(t) + log(u/t) log(t) is tabulated in the lookup table. Express log(u/t) = log(1+z), where z = u/t - 1 = (u-t)/t. cf. Cody & Waite. */ z = (u.value - t.value) / t.value; } /* Series expansion of log(1+z). */ w = z * z; y = ((((((((((((l15 * z + l14) * z + l13) * z + l12) * z + l11) * z + l10) * z + l9) * z + l8) * z + l7) * z + l6) * z + l5) * z + l4) * z + l3) * z * w; y -= 0.5 * w; y += e * ln2b; /* Base 2 exponent offset times ln(2). */ y += z; y += logtbl[k-26]; /* log(t) - (t-1) */ y += (t.value - 1.0L); y += e * ln2a; return y; } openlibm-0.5.0/ld128/e_powl.c000066400000000000000000000272261266752446200156330ustar00rootroot00000000000000/* * ==================================================== * 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. * ==================================================== */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* powl(x,y) return x**y * * n * Method: Let x = 2 * (1+f) * 1. Compute and return log2(x) in two pieces: * log2(x) = w1 + w2, * where w1 has 113-53 = 60 bit trailing zeros. * 2. Perform y*log2(x) = n+y' by simulating muti-precision * arithmetic, where |y'|<=0.5. * 3. Return x**y = 2**n*exp(y'*log2) * * Special cases: * 1. (anything) ** 0 is 1 * 2. (anything) ** 1 is itself * 3. (anything) ** NAN is NAN * 4. NAN ** (anything except 0) is NAN * 5. +-(|x| > 1) ** +INF is +INF * 6. +-(|x| > 1) ** -INF is +0 * 7. +-(|x| < 1) ** +INF is +0 * 8. +-(|x| < 1) ** -INF is +INF * 9. +-1 ** +-INF is NAN * 10. +0 ** (+anything except 0, NAN) is +0 * 11. -0 ** (+anything except 0, NAN, odd integer) is +0 * 12. +0 ** (-anything except 0, NAN) is +INF * 13. -0 ** (-anything except 0, NAN, odd integer) is +INF * 14. -0 ** (odd integer) = -( +0 ** (odd integer) ) * 15. +INF ** (+anything except 0,NAN) is +INF * 16. +INF ** (-anything except 0,NAN) is +0 * 17. -INF ** (anything) = -0 ** (-anything) * 18. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer) * 19. (-anything except 0 and inf) ** (non-integer) is NAN * */ #include #include "math_private.h" static const long double bp[] = { 1.0L, 1.5L, }; /* log_2(1.5) */ static const long double dp_h[] = { 0.0, 5.8496250072115607565592654282227158546448E-1L }; /* Low part of log_2(1.5) */ static const long double dp_l[] = { 0.0, 1.0579781240112554492329533686862998106046E-16L }; static const long double zero = 0.0L, one = 1.0L, two = 2.0L, two113 = 1.0384593717069655257060992658440192E34L, huge = 1.0e3000L, tiny = 1.0e-3000L; /* 3/2 log x = 3 z + z^3 + z^3 (z^2 R(z^2)) z = (x-1)/(x+1) 1 <= x <= 1.25 Peak relative error 2.3e-37 */ static const long double LN[] = { -3.0779177200290054398792536829702930623200E1L, 6.5135778082209159921251824580292116201640E1L, -4.6312921812152436921591152809994014413540E1L, 1.2510208195629420304615674658258363295208E1L, -9.9266909031921425609179910128531667336670E-1L }; static const long double LD[] = { -5.129862866715009066465422805058933131960E1L, 1.452015077564081884387441590064272782044E2L, -1.524043275549860505277434040464085593165E2L, 7.236063513651544224319663428634139768808E1L, -1.494198912340228235853027849917095580053E1L /* 1.0E0 */ }; /* exp(x) = 1 + x - x / (1 - 2 / (x - x^2 R(x^2))) 0 <= x <= 0.5 Peak relative error 5.7e-38 */ static const long double PN[] = { 5.081801691915377692446852383385968225675E8L, 9.360895299872484512023336636427675327355E6L, 4.213701282274196030811629773097579432957E4L, 5.201006511142748908655720086041570288182E1L, 9.088368420359444263703202925095675982530E-3L, }; static const long double PD[] = { 3.049081015149226615468111430031590411682E9L, 1.069833887183886839966085436512368982758E8L, 8.259257717868875207333991924545445705394E5L, 1.872583833284143212651746812884298360922E3L, /* 1.0E0 */ }; static const long double /* ln 2 */ lg2 = 6.9314718055994530941723212145817656807550E-1L, lg2_h = 6.9314718055994528622676398299518041312695E-1L, lg2_l = 2.3190468138462996154948554638754786504121E-17L, ovt = 8.0085662595372944372e-0017L, /* 2/(3*log(2)) */ cp = 9.6179669392597560490661645400126142495110E-1L, cp_h = 9.6179669392597555432899980587535537779331E-1L, cp_l = 5.0577616648125906047157785230014751039424E-17L; long double powl(long double x, long double y) { long double z, ax, z_h, z_l, p_h, p_l; long double yy1, t1, t2, r, s, t, u, v, w; long double s2, s_h, s_l, t_h, t_l; int32_t i, j, k, yisint, n; u_int32_t ix, iy; int32_t hx, hy; ieee_quad_shape_type o, p, q; p.value = x; hx = p.parts32.mswhi; ix = hx & 0x7fffffff; q.value = y; hy = q.parts32.mswhi; iy = hy & 0x7fffffff; /* y==zero: x**0 = 1 */ if ((iy | q.parts32.mswlo | q.parts32.lswhi | q.parts32.lswlo) == 0) return one; /* 1.0**y = 1; -1.0**+-Inf = 1 */ if (x == one) return one; if (x == -1.0L && iy == 0x7fff0000 && (q.parts32.mswlo | q.parts32.lswhi | q.parts32.lswlo) == 0) return one; /* +-NaN return x+y */ if ((ix > 0x7fff0000) || ((ix == 0x7fff0000) && ((p.parts32.mswlo | p.parts32.lswhi | p.parts32.lswlo) != 0)) || (iy > 0x7fff0000) || ((iy == 0x7fff0000) && ((q.parts32.mswlo | q.parts32.lswhi | q.parts32.lswlo) != 0))) return x + y; /* determine if y is an odd int when x < 0 * yisint = 0 ... y is not an integer * yisint = 1 ... y is an odd int * yisint = 2 ... y is an even int */ yisint = 0; if (hx < 0) { if (iy >= 0x40700000) /* 2^113 */ yisint = 2; /* even integer y */ else if (iy >= 0x3fff0000) /* 1.0 */ { if (floorl (y) == y) { z = 0.5 * y; if (floorl (z) == z) yisint = 2; else yisint = 1; } } } /* special value of y */ if ((q.parts32.mswlo | q.parts32.lswhi | q.parts32.lswlo) == 0) { if (iy == 0x7fff0000) /* y is +-inf */ { if (((ix - 0x3fff0000) | p.parts32.mswlo | p.parts32.lswhi | p.parts32.lswlo) == 0) return y - y; /* +-1**inf is NaN */ else if (ix >= 0x3fff0000) /* (|x|>1)**+-inf = inf,0 */ return (hy >= 0) ? y : zero; else /* (|x|<1)**-,+inf = inf,0 */ return (hy < 0) ? -y : zero; } if (iy == 0x3fff0000) { /* y is +-1 */ if (hy < 0) return one / x; else return x; } if (hy == 0x40000000) return x * x; /* y is 2 */ if (hy == 0x3ffe0000) { /* y is 0.5 */ if (hx >= 0) /* x >= +0 */ return sqrtl (x); } } ax = fabsl (x); /* special value of x */ if ((p.parts32.mswlo | p.parts32.lswhi | p.parts32.lswlo) == 0) { if (ix == 0x7fff0000 || ix == 0 || ix == 0x3fff0000) { z = ax; /*x is +-0,+-inf,+-1 */ if (hy < 0) z = one / z; /* z = (1/|x|) */ if (hx < 0) { if (((ix - 0x3fff0000) | yisint) == 0) { z = (z - z) / (z - z); /* (-1)**non-int is NaN */ } else if (yisint == 1) z = -z; /* (x<0)**odd = -(|x|**odd) */ } return z; } } /* (x<0)**(non-int) is NaN */ if (((((u_int32_t) hx >> 31) - 1) | yisint) == 0) return (x - x) / (x - x); /* |y| is huge. 2^-16495 = 1/2 of smallest representable value. If (1 - 1/131072)^y underflows, y > 1.4986e9 */ if (iy > 0x401d654b) { /* if (1 - 2^-113)^y underflows, y > 1.1873e38 */ if (iy > 0x407d654b) { if (ix <= 0x3ffeffff) return (hy < 0) ? huge * huge : tiny * tiny; if (ix >= 0x3fff0000) return (hy > 0) ? huge * huge : tiny * tiny; } /* over/underflow if x is not close to one */ if (ix < 0x3ffeffff) return (hy < 0) ? huge * huge : tiny * tiny; if (ix > 0x3fff0000) return (hy > 0) ? huge * huge : tiny * tiny; } n = 0; /* take care subnormal number */ if (ix < 0x00010000) { ax *= two113; n -= 113; o.value = ax; ix = o.parts32.mswhi; } n += ((ix) >> 16) - 0x3fff; j = ix & 0x0000ffff; /* determine interval */ ix = j | 0x3fff0000; /* normalize ix */ if (j <= 0x3988) k = 0; /* |x|> 31) - 1) | (yisint - 1)) == 0) s = -one; /* (-ve)**(odd int) */ /* split up y into yy1+y2 and compute (yy1+y2)*(t1+t2) */ yy1 = y; o.value = yy1; o.parts32.lswlo = 0; o.parts32.lswhi &= 0xf8000000; yy1 = o.value; p_l = (y - yy1) * t1 + y * t2; p_h = yy1 * t1; z = p_l + p_h; o.value = z; j = o.parts32.mswhi; if (j >= 0x400d0000) /* z >= 16384 */ { /* if z > 16384 */ if (((j - 0x400d0000) | o.parts32.mswlo | o.parts32.lswhi | o.parts32.lswlo) != 0) return s * huge * huge; /* overflow */ else { if (p_l + ovt > z - p_h) return s * huge * huge; /* overflow */ } } else if ((j & 0x7fffffff) >= 0x400d01b9) /* z <= -16495 */ { /* z < -16495 */ if (((j - 0xc00d01bc) | o.parts32.mswlo | o.parts32.lswhi | o.parts32.lswlo) != 0) return s * tiny * tiny; /* underflow */ else { if (p_l <= z - p_h) return s * tiny * tiny; /* underflow */ } } /* compute 2**(p_h+p_l) */ i = j & 0x7fffffff; k = (i >> 16) - 0x3fff; n = 0; if (i > 0x3ffe0000) { /* if |z| > 0.5, set n = [z+0.5] */ n = floorl (z + 0.5L); t = n; p_h -= t; } t = p_l + p_h; o.value = t; o.parts32.lswlo = 0; o.parts32.lswhi &= 0xf8000000; t = o.value; u = t * lg2_h; v = (p_l - (t - p_h)) * lg2 + t * lg2_l; z = u + v; w = v - (z - u); /* exp(z) */ t = z * z; u = PN[0] + t * (PN[1] + t * (PN[2] + t * (PN[3] + t * PN[4]))); v = PD[0] + t * (PD[1] + t * (PD[2] + t * (PD[3] + t))); t1 = z - t * u / v; r = (z * t1) / (t1 - two) - (w + z * w); z = one - (r - z); o.value = z; j = o.parts32.mswhi; j += (n << 16); if ((j >> 16) <= 0) z = scalbnl (z, n); /* subnormal output */ else { o.parts32.mswhi = j; z = o.value; } return s * z; } openlibm-0.5.0/ld128/e_rem_pio2l.h000066400000000000000000000102521266752446200165360ustar00rootroot00000000000000/* From: @(#)e_rem_pio2.c 1.4 95/01/18 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== * * Optimized by Bruce D. Evans. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/ld128/e_rem_pio2l.h,v 1.2 2011/05/30 19:41:28 kargl Exp $"); /* ld128 version of __ieee754_rem_pio2l(x,y) * * return the remainder of x rem pi/2 in y[0]+y[1] * use __kernel_rem_pio2() */ #include #include #include "math_private.h" #include "fpmath.h" #define BIAS (LDBL_MAX_EXP - 1) /* * XXX need to verify that nonzero integer multiples of pi/2 within the * range get no closer to a long double than 2**-140, or that * ilogb(x) + ilogb(min_delta) < 45 - -140. */ /* * invpio2: 113 bits of 2/pi * pio2_1: first 68 bits of pi/2 * pio2_1t: pi/2 - pio2_1 * pio2_2: second 68 bits of pi/2 * pio2_2t: pi/2 - (pio2_1+pio2_2) * pio2_3: third 68 bits of pi/2 * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) */ static const double zero = 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ two24 = 1.67772160000000000000e+07; /* 0x41700000, 0x00000000 */ static const long double invpio2 = 6.3661977236758134307553505349005747e-01L, /* 0x145f306dc9c882a53f84eafa3ea6a.0p-113 */ pio2_1 = 1.5707963267948966192292994253909555e+00L, /* 0x1921fb54442d18469800000000000.0p-112 */ pio2_1t = 2.0222662487959507323996846200947577e-21L, /* 0x13198a2e03707344a4093822299f3.0p-181 */ pio2_2 = 2.0222662487959507323994779168837751e-21L, /* 0x13198a2e03707344a400000000000.0p-181 */ pio2_2t = 2.0670321098263988236496903051604844e-43L, /* 0x127044533e63a0105df531d89cd91.0p-254 */ pio2_3 = 2.0670321098263988236499468110329591e-43L, /* 0x127044533e63a0105e00000000000.0p-254 */ pio2_3t = -2.5650587247459238361625433492959285e-65L; /* -0x159c4ec64ddaeb5f78671cbfb2210.0p-327 */ //VBS //static inline __always_inline int //__ieee754_rem_pio2l(long double x, long double *y) static inline int __ieee754_rem_pio2l(long double x, long double *y) { union IEEEl2bits u,u1; long double z,w,t,r,fn; double tx[5],ty[3]; int64_t n; int e0,ex,i,j,nx; int16_t expsign; u.e = x; expsign = u.xbits.expsign; ex = expsign & 0x7fff; if (ex < BIAS + 45 || ex == BIAS + 45 && u.bits.manh < 0x921fb54442d1LL) { /* |x| ~< 2^45*(pi/2), medium size */ /* Use a specialized rint() to get fn. Assume round-to-nearest. */ fn = x*invpio2+0x1.8p112; fn = fn-0x1.8p112; #ifdef HAVE_EFFICIENT_I64RINT n = i64rint(fn); #else n = fn; #endif r = x-fn*pio2_1; w = fn*pio2_1t; /* 1st round good to 180 bit */ { union IEEEl2bits u2; int ex1; j = ex; y[0] = r-w; u2.e = y[0]; ex1 = u2.xbits.expsign & 0x7fff; i = j-ex1; if(i>51) { /* 2nd iteration needed, good to 248 */ t = r; w = fn*pio2_2; r = t-w; w = fn*pio2_2t-((t-r)-w); y[0] = r-w; u2.e = y[0]; ex1 = u2.xbits.expsign & 0x7fff; i = j-ex1; if(i>119) { /* 3rd iteration need, 316 bits acc */ t = r; /* will cover all possible cases */ w = fn*pio2_3; r = t-w; w = fn*pio2_3t-((t-r)-w); y[0] = r-w; } } } y[1] = (r-y[0])-w; return n; } /* * all other (large) arguments */ if(ex==0x7fff) { /* x is inf or NaN */ y[0]=y[1]=x-x; return 0; } /* set z = scalbn(|x|,ilogb(x)-23) */ u1.e = x; e0 = ex - BIAS - 23; /* e0 = ilogb(|x|)-23; */ u1.xbits.expsign = ex - e0; z = u1.e; for(i=0;i<4;i++) { tx[i] = (double)((int32_t)(z)); z = (z-tx[i])*two24; } tx[4] = z; nx = 5; while(tx[nx-1]==zero) nx--; /* skip zero term */ n = __kernel_rem_pio2(tx,ty,e0,nx,3); t = (long double)ty[2] + ty[1]; r = t + ty[0]; w = ty[0] - (r - t); if(expsign<0) {y[0] = -r; y[1] = -w; return -n;} y[0] = r; y[1] = w; return n; } openlibm-0.5.0/ld128/e_sinhl.c000066400000000000000000000061621266752446200157630ustar00rootroot00000000000000/* @(#)e_sinh.c 5.1 93/09/24 */ /* * ==================================================== * 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. * ==================================================== */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* sinhl(x) * Method : * mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2 * 1. Replace x by |x| (sinhl(-x) = -sinhl(x)). * 2. * E + E/(E+1) * 0 <= x <= 25 : sinhl(x) := --------------, E=expm1l(x) * 2 * * 25 <= x <= lnovft : sinhl(x) := expl(x)/2 * lnovft <= x <= ln2ovft: sinhl(x) := expl(x/2)/2 * expl(x/2) * ln2ovft < x : sinhl(x) := x*shuge (overflow) * * Special cases: * sinhl(x) is |x| if x is +INF, -INF, or NaN. * only sinhl(0)=0 is exact for finite x. */ #include #include "math_private.h" static const long double one = 1.0, shuge = 1.0e4931L, ovf_thresh = 1.1357216553474703894801348310092223067821E4L; long double sinhl(long double x) { long double t, w, h; u_int32_t jx, ix; ieee_quad_shape_type u; /* Words of |x|. */ u.value = x; jx = u.parts32.mswhi; ix = jx & 0x7fffffff; /* x is INF or NaN */ if (ix >= 0x7fff0000) return x + x; h = 0.5; if (jx & 0x80000000) h = -h; /* Absolute value of x. */ u.parts32.mswhi = ix; /* |x| in [0,40], return sign(x)*0.5*(E+E/(E+1))) */ if (ix <= 0x40044000) { if (ix < 0x3fc60000) /* |x| < 2^-57 */ if (shuge + x > one) return x; /* sinh(tiny) = tiny with inexact */ t = expm1l (u.value); if (ix < 0x3fff0000) return h * (2.0 * t - t * t / (t + one)); return h * (t + t / (t + one)); } /* |x| in [40, log(maxdouble)] return 0.5*exp(|x|) */ if (ix <= 0x400c62e3) /* 11356.375 */ return h * expl (u.value); /* |x| in [log(maxdouble), overflowthreshold] Overflow threshold is log(2 * maxdouble). */ if (u.value <= ovf_thresh) { w = expl (0.5 * u.value); t = h * w; return t * w; } /* |x| > overflowthreshold, sinhl(x) overflow */ return x * shuge; } openlibm-0.5.0/ld128/e_tgammal.c000066400000000000000000000023341266752446200162650ustar00rootroot00000000000000/* $OpenBSD: e_tgammal.c,v 1.1 2011/07/06 00:02:42 martynas Exp $ */ /* * Copyright (c) 2011 Martynas Venckus * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include "math_private.h" long double tgammal(long double x) { int64_t i0,i1; GET_LDOUBLE_WORDS64(i0,i1,x); if (((i0&0x7fffffffffffffffLL)|i1) == 0) return (1.0/x); if (i0<0 && (u_int64_t)i0<0xffff000000000000ULL && rintl(x)==x) return (x-x)/(x-x); if (i0==0xffff000000000000ULL && i1==0) return (x-x); return expl(lgammal(x)); } openlibm-0.5.0/ld128/invtrig.c000066400000000000000000000101641266752446200160210ustar00rootroot00000000000000/*- * Copyright (c) 2008 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/ld128/invtrig.c,v 1.1 2008/07/31 22:41:26 das Exp $"); #include "ld128/invtrig.h" /* * asinl() and acosl() */ const long double pS0 = 1.66666666666666666666666666666700314e-01L, pS1 = -7.32816946414566252574527475428622708e-01L, pS2 = 1.34215708714992334609030036562143589e+00L, pS3 = -1.32483151677116409805070261790752040e+00L, pS4 = 7.61206183613632558824485341162121989e-01L, pS5 = -2.56165783329023486777386833928147375e-01L, pS6 = 4.80718586374448793411019434585413855e-02L, pS7 = -4.42523267167024279410230886239774718e-03L, pS8 = 1.44551535183911458253205638280410064e-04L, pS9 = -2.10558957916600254061591040482706179e-07L, qS1 = -4.84690167848739751544716485245697428e+00L, qS2 = 9.96619113536172610135016921140206980e+00L, qS3 = -1.13177895428973036660836798461641458e+01L, qS4 = 7.74004374389488266169304117714658761e+00L, qS5 = -3.25871986053534084709023539900339905e+00L, qS6 = 8.27830318881232209752469022352928864e-01L, qS7 = -1.18768052702942805423330715206348004e-01L, qS8 = 8.32600764660522313269101537926539470e-03L, qS9 = -1.99407384882605586705979504567947007e-04L; /* * atanl() */ const long double atanhi[] = { 4.63647609000806116214256231461214397e-01L, 7.85398163397448309615660845819875699e-01L, 9.82793723247329067985710611014666038e-01L, 1.57079632679489661923132169163975140e+00L, }; const long double atanlo[] = { 4.89509642257333492668618435220297706e-36L, 2.16795253253094525619926100651083806e-35L, -2.31288434538183565909319952098066272e-35L, 4.33590506506189051239852201302167613e-35L, }; const long double aT[] = { 3.33333333333333333333333333333333125e-01L, -1.99999999999999999999999999999180430e-01L, 1.42857142857142857142857142125269827e-01L, -1.11111111111111111111110834490810169e-01L, 9.09090909090909090908522355708623681e-02L, -7.69230769230769230696553844935357021e-02L, 6.66666666666666660390096773046256096e-02L, -5.88235294117646671706582985209643694e-02L, 5.26315789473666478515847092020327506e-02L, -4.76190476189855517021024424991436144e-02L, 4.34782608678695085948531993458097026e-02L, -3.99999999632663469330634215991142368e-02L, 3.70370363987423702891250829918659723e-02L, -3.44827496515048090726669907612335954e-02L, 3.22579620681420149871973710852268528e-02L, -3.03020767654269261041647570626778067e-02L, 2.85641979882534783223403715930946138e-02L, -2.69824879726738568189929461383741323e-02L, 2.54194698498808542954187110873675769e-02L, -2.35083879708189059926183138130183215e-02L, 2.04832358998165364349957325067131428e-02L, -1.54489555488544397858507248612362957e-02L, 8.64492360989278761493037861575248038e-03L, -2.58521121597609872727919154569765469e-03L, }; const long double pi_lo = 8.67181013012378102479704402604335225e-35L; openlibm-0.5.0/ld128/invtrig.h000066400000000000000000000070641266752446200160330ustar00rootroot00000000000000/*- * Copyright (c) 2008 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/lib/msun/ld128/invtrig.h,v 1.1 2008/07/31 22:41:26 das Exp $ */ #include #include "fpmath.h" #define BIAS (LDBL_MAX_EXP - 1) #define MANH_SIZE (LDBL_MANH_SIZE + 1) /* Approximation thresholds. */ #define ASIN_LINEAR (BIAS - 56) /* 2**-56 */ #define ACOS_CONST (BIAS - 113) /* 2**-113 */ #define ATAN_CONST (BIAS + 113) /* 2**113 */ #define ATAN_LINEAR (BIAS - 56) /* 2**-56 */ /* 0.95 */ #define THRESH ((0xe666666666666666ULL>>(64-(MANH_SIZE-1)))|LDBL_NBIT) /* Constants shared by the long double inverse trig functions. */ #define pS0 _ItL_pS0 #define pS1 _ItL_pS1 #define pS2 _ItL_pS2 #define pS3 _ItL_pS3 #define pS4 _ItL_pS4 #define pS5 _ItL_pS5 #define pS6 _ItL_pS6 #define pS7 _ItL_pS7 #define pS8 _ItL_pS8 #define pS9 _ItL_pS9 #define qS1 _ItL_qS1 #define qS2 _ItL_qS2 #define qS3 _ItL_qS3 #define qS4 _ItL_qS4 #define qS5 _ItL_qS5 #define qS6 _ItL_qS6 #define qS7 _ItL_qS7 #define qS8 _ItL_qS8 #define qS9 _ItL_qS9 #define atanhi _ItL_atanhi #define atanlo _ItL_atanlo #define aT _ItL_aT #define pi_lo _ItL_pi_lo #define pio2_hi atanhi[3] #define pio2_lo atanlo[3] #define pio4_hi atanhi[1] /* Constants shared by the long double inverse trig functions. */ extern const long double pS0, pS1, pS2, pS3, pS4, pS5, pS6, pS7, pS8, pS9; extern const long double qS1, qS2, qS3, qS4, qS5, qS6, qS7, qS8, qS9; extern const long double atanhi[], atanlo[], aT[]; extern const long double pi_lo; static inline long double P(long double x) { return (x * (pS0 + x * (pS1 + x * (pS2 + x * (pS3 + x * \ (pS4 + x * (pS5 + x * (pS6 + x * (pS7 + x * (pS8 + x * \ pS9)))))))))); } static inline long double Q(long double x) { return (1.0 + x * (qS1 + x * (qS2 + x * (qS3 + x * (qS4 + x * \ (qS5 + x * (qS6 + x * (qS7 + x * (qS8 + x * qS9))))))))); } static inline long double T_even(long double x) { return (aT[0] + x * (aT[2] + x * (aT[4] + x * (aT[6] + x * \ (aT[8] + x * (aT[10] + x * (aT[12] + x * (aT[14] + x * \ (aT[16] + x * (aT[18] + x * (aT[20] + x * aT[22]))))))))))); } static inline long double T_odd(long double x) { return (aT[1] + x * (aT[3] + x * (aT[5] + x * (aT[7] + x * \ (aT[9] + x * (aT[11] + x * (aT[13] + x * (aT[15] + x * \ (aT[17] + x * (aT[19] + x * (aT[21] + x * aT[23]))))))))))); } openlibm-0.5.0/ld128/k_cosl.c000066400000000000000000000037101266752446200156100ustar00rootroot00000000000000/* From: @(#)k_cos.c 1.3 95/01/18 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/ld128/k_cosl.c,v 1.1 2008/02/17 07:32:31 das Exp $"); /* * ld128 version of k_cos.c. See ../src/k_cos.c for most comments. */ #include "math_private.h" /* * Domain [-0.7854, 0.7854], range ~[-1.80e-37, 1.79e-37]: * |cos(x) - c(x))| < 2**-122.0 * * 113-bit precision requires more care than 64-bit precision, since * simple methods give a minimax polynomial with coefficient for x^2 * that is 1 ulp below 0.5, but we want it to be precisely 0.5. See * ../ld80/k_cosl.c for more details. */ static const double one = 1.0; static const long double C1 = 0.04166666666666666666666666666666658424671L, C2 = -0.001388888888888888888888888888863490893732L, C3 = 0.00002480158730158730158730158600795304914210L, C4 = -0.2755731922398589065255474947078934284324e-6L, C5 = 0.2087675698786809897659225313136400793948e-8L, C6 = -0.1147074559772972315817149986812031204775e-10L, C7 = 0.4779477332386808976875457937252120293400e-13L; static const double C8 = -0.1561920696721507929516718307820958119868e-15, C9 = 0.4110317413744594971475941557607804508039e-18, C10 = -0.8896592467191938803288521958313920156409e-21, C11 = 0.1601061435794535138244346256065192782581e-23; DLLEXPORT long double __kernel_cosl(long double x, long double y) { long double hz,z,r,w; z = x*x; r = z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*(C6+z*(C7+ z*(C8+z*(C9+z*(C10+z*C11)))))))))); hz = 0.5*z; w = one-hz; return w + (((one-w)-hz) + (z*r-x*y)); } openlibm-0.5.0/ld128/k_sinl.c000066400000000000000000000037341266752446200156230ustar00rootroot00000000000000/* From: @(#)k_sin.c 1.3 95/01/18 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/ld128/k_sinl.c,v 1.1 2008/02/17 07:32:31 das Exp $"); /* * ld128 version of k_sin.c. See ../src/k_sin.c for most comments. */ #include "math_private.h" static const double half = 0.5; /* * Domain [-0.7854, 0.7854], range ~[-1.53e-37, 1.659e-37] * |sin(x)/x - s(x)| < 2**-122.1 * * See ../ld80/k_cosl.c for more details about the polynomial. */ static const long double S1 = -0.16666666666666666666666666666666666606732416116558L, S2 = 0.0083333333333333333333333333333331135404851288270047L, S3 = -0.00019841269841269841269841269839935785325638310428717L, S4 = 0.27557319223985890652557316053039946268333231205686e-5L, S5 = -0.25052108385441718775048214826384312253862930064745e-7L, S6 = 0.16059043836821614596571832194524392581082444805729e-9L, S7 = -0.76471637318198151807063387954939213287488216303768e-12L, S8 = 0.28114572543451292625024967174638477283187397621303e-14L; static const double S9 = -0.82206352458348947812512122163446202498005154296863e-17, S10 = 0.19572940011906109418080609928334380560135358385256e-19, S11 = -0.38680813379701966970673724299207480965452616911420e-22, S12 = 0.64038150078671872796678569586315881020659912139412e-25; DLLEXPORT long double __kernel_sinl(long double x, long double y, int iy) { long double z,r,v; z = x*x; v = z*x; r = S2+z*(S3+z*(S4+z*(S5+z*(S6+z*(S7+z*(S8+ z*(S9+z*(S10+z*(S11+z*S12))))))))); if(iy==0) return x+v*(S1+z*r); else return x-((z*(half*y-v*r)-y)-v*S1); } openlibm-0.5.0/ld128/k_tanl.c000066400000000000000000000073111266752446200156070ustar00rootroot00000000000000/* From: @(#)k_tan.c 1.5 04/04/22 SMI */ /* * ==================================================== * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved. * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans. * * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/ld128/k_tanl.c,v 1.1 2008/02/17 07:32:31 das Exp $"); /* * ld128 version of k_tan.c. See ../src/k_tan.c for most comments. */ #include #include "math_private.h" /* * Domain [-0.67434, 0.67434], range ~[-3.37e-36, 1.982e-37] * |tan(x)/x - t(x)| < 2**-117.8 (XXX should be ~1e-37) * * See ../ld80/k_cosl.c for more details about the polynomial. */ static const long double T3 = 0x1.5555555555555555555555555553p-2L, T5 = 0x1.1111111111111111111111111eb5p-3L, T7 = 0x1.ba1ba1ba1ba1ba1ba1ba1b694cd6p-5L, T9 = 0x1.664f4882c10f9f32d6bbe09d8bcdp-6L, T11 = 0x1.226e355e6c23c8f5b4f5762322eep-7L, T13 = 0x1.d6d3d0e157ddfb5fed8e84e27b37p-9L, T15 = 0x1.7da36452b75e2b5fce9ee7c2c92ep-10L, T17 = 0x1.355824803674477dfcf726649efep-11L, T19 = 0x1.f57d7734d1656e0aceb716f614c2p-13L, T21 = 0x1.967e18afcb180ed942dfdc518d6cp-14L, T23 = 0x1.497d8eea21e95bc7e2aa79b9f2cdp-15L, T25 = 0x1.0b132d39f055c81be49eff7afd50p-16L, T27 = 0x1.b0f72d33eff7bfa2fbc1059d90b6p-18L, T29 = 0x1.5ef2daf21d1113df38d0fbc00267p-19L, T31 = 0x1.1c77d6eac0234988cdaa04c96626p-20L, T33 = 0x1.cd2a5a292b180e0bdd701057dfe3p-22L, T35 = 0x1.75c7357d0298c01a31d0a6f7d518p-23L, T37 = 0x1.2f3190f4718a9a520f98f50081fcp-24L, pio4 = 0x1.921fb54442d18469898cc51701b8p-1L, pio4lo = 0x1.cd129024e088a67cc74020bbea60p-116L; static const double T39 = 0.000000028443389121318352, /* 0x1e8a7592977938.0p-78 */ T41 = 0.000000011981013102001973, /* 0x19baa1b1223219.0p-79 */ T43 = 0.0000000038303578044958070, /* 0x107385dfb24529.0p-80 */ T45 = 0.0000000034664378216909893, /* 0x1dc6c702a05262.0p-81 */ T47 = -0.0000000015090641701997785, /* -0x19ecef3569ebb6.0p-82 */ T49 = 0.0000000029449552300483952, /* 0x194c0668da786a.0p-81 */ T51 = -0.0000000022006995706097711, /* -0x12e763b8845268.0p-81 */ T53 = 0.0000000015468200913196612, /* 0x1a92fc98c29554.0p-82 */ T55 = -0.00000000061311613386849674, /* -0x151106cbc779a9.0p-83 */ T57 = 1.4912469681508012e-10; /* 0x147edbdba6f43a.0p-85 */ DLLEXPORT long double __kernel_tanl(long double x, long double y, int iy) { long double z, r, v, w, s; long double osign; int i; iy = (iy == 1 ? -1 : 1); /* XXX recover original interface */ osign = (x >= 0 ? 1.0 : -1.0); /* XXX slow, probably wrong for -0 */ if (fabsl(x) >= 0.67434) { if (x < 0) { x = -x; y = -y; } z = pio4 - x; w = pio4lo - y; x = z + w; y = 0.0; i = 1; } else i = 0; z = x * x; w = z * z; r = T5 + w * (T9 + w * (T13 + w * (T17 + w * (T21 + w * (T25 + w * (T29 + w * (T33 + w * (T37 + w * (T41 + w * (T45 + w * (T49 + w * (T53 + w * T57)))))))))))); v = z * (T7 + w * (T11 + w * (T15 + w * (T19 + w * (T23 + w * (T27 + w * (T31 + w * (T35 + w * (T39 + w * (T43 + w * (T47 + w * (T51 + w * T55)))))))))))); s = z * x; r = y + z * (s * (r + v) + y); r += T3 * s; w = x + r; if (i == 1) { v = (long double) iy; return osign * (v - 2.0 * (x - (w * w / (w + v) - r))); } if (iy == 1) return w; else { /* * if allow error up to 2 ulp, simply return * -1.0 / (x+r) here */ /* compute -1.0 / (x+r) accurately */ long double a, t; z = w; z = z + 0x1p32 - 0x1p32; v = r - (z - x); /* z+v = r+x */ t = a = -1.0 / w; /* a = -1.0/w */ t = t + 0x1p32 - 0x1p32; s = 1.0 + t * z; return t + a * (s + t * v); } } openlibm-0.5.0/ld128/s_asinhl.c000066400000000000000000000033431266752446200161400ustar00rootroot00000000000000/* @(#)s_asinh.c 5.1 93/09/24 */ /* * ==================================================== * 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. * ==================================================== */ /* asinhl(x) * Method : * Based on * asinhl(x) = signl(x) * logl [ |x| + sqrtl(x*x+1) ] * we have * asinhl(x) := x if 1+x*x=1, * := signl(x)*(logl(x)+ln2)) for large |x|, else * := signl(x)*logl(2|x|+1/(|x|+sqrtl(x*x+1))) if|x|>2, else * := signl(x)*log1pl(|x| + x^2/(1 + sqrtl(1+x^2))) */ #include #include "math_private.h" static const long double one = 1.0L, ln2 = 6.931471805599453094172321214581765681e-1L, huge = 1.0e+4900L; long double asinhl(long double x) { long double t, w; int32_t ix, sign; ieee_quad_shape_type u; u.value = x; sign = u.parts32.mswhi; ix = sign & 0x7fffffff; if (ix == 0x7fff0000) return x + x; /* x is inf or NaN */ if (ix < 0x3fc70000) { /* |x| < 2^ -56 */ if (huge + x > one) return x; /* return x inexact except 0 */ } u.parts32.mswhi = ix; if (ix > 0x40350000) { /* |x| > 2 ^ 54 */ w = logl (u.value) + ln2; } else if (ix >0x40000000) { /* 2^ 54 > |x| > 2.0 */ t = u.value; w = logl (2.0 * t + one / (sqrtl (x * x + one) + t)); } else { /* 2.0 > |x| > 2 ^ -56 */ t = x * x; w = log1pl (u.value + t / (one + sqrtl (one + t))); } if (sign & 0x80000000) return -w; else return w; } openlibm-0.5.0/ld128/s_ceill.c000066400000000000000000000032661266752446200157560ustar00rootroot00000000000000/* @(#)s_ceil.c 5.1 93/09/24 */ /* * ==================================================== * 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. * ==================================================== */ /* * ceill(x) * Return x rounded toward -inf to integral value * Method: * Bit twiddling. * Exception: * Inexact flag raised if x not equal to ceil(x). */ #include #include "math_private.h" static const long double huge = 1.0e4930L; long double ceill(long double x) { int64_t i0,i1,jj0; u_int64_t i,j; GET_LDOUBLE_WORDS64(i0,i1,x); jj0 = ((i0>>48)&0x7fff)-0x3fff; if(jj0<48) { if(jj0<0) { /* raise inexact if x != 0 */ if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */ if(i0<0) {i0=0x8000000000000000ULL;i1=0;} else if((i0|i1)!=0) { i0=0x3fff000000000000ULL;i1=0;} } } else { i = (0x0000ffffffffffffULL)>>jj0; if(((i0&i)|i1)==0) return x; /* x is integral */ if(huge+x>0.0) { /* raise inexact flag */ if(i0>0) i0 += (0x0001000000000000LL)>>jj0; i0 &= (~i); i1=0; } } } else if (jj0>111) { if(jj0==0x4000) return x+x; /* inf or NaN */ else return x; /* x is integral */ } else { i = -1ULL>>(jj0-48); if((i1&i)==0) return x; /* x is integral */ if(huge+x>0.0) { /* raise inexact flag */ if(i0>0) { if(jj0==48) i0+=1; else { j = i1+(1LL<<(112-jj0)); if(j * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* double erf(double x) * double erfc(double x) * x * 2 |\ * erf(x) = --------- | exp(-t*t)dt * sqrt(pi) \| * 0 * * erfc(x) = 1-erf(x) * Note that * erf(-x) = -erf(x) * erfc(-x) = 2 - erfc(x) * * Method: * 1. erf(x) = x + x*R(x^2) for |x| in [0, 7/8] * Remark. The formula is derived by noting * erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....) * and that * 2/sqrt(pi) = 1.128379167095512573896158903121545171688 * is close to one. * * 1a. erf(x) = 1 - erfc(x), for |x| > 1.0 * erfc(x) = 1 - erf(x) if |x| < 1/4 * * 2. For |x| in [7/8, 1], let s = |x| - 1, and * c = 0.84506291151 rounded to single (24 bits) * erf(s + c) = sign(x) * (c + P1(s)/Q1(s)) * Remark: here we use the taylor series expansion at x=1. * erf(1+s) = erf(1) + s*Poly(s) * = 0.845.. + P1(s)/Q1(s) * Note that |P1/Q1|< 0.078 for x in [0.84375,1.25] * * 3. For x in [1/4, 5/4], * erfc(s + const) = erfc(const) + s P1(s)/Q1(s) * for const = 1/4, 3/8, ..., 9/8 * and 0 <= s <= 1/8 . * * 4. For x in [5/4, 107], * erfc(x) = (1/x)*exp(-x*x-0.5625 + R(z)) * z=1/x^2 * The interval is partitioned into several segments * of width 1/8 in 1/x. * * Note1: * To compute exp(-x*x-0.5625+R/S), let s be a single * precision number and s := x; then * -x*x = -s*s + (s-x)*(s+x) * exp(-x*x-0.5626+R/S) = * exp(-s*s-0.5625)*exp((s-x)*(s+x)+R/S); * Note2: * Here 4 and 5 make use of the asymptotic series * exp(-x*x) * erfc(x) ~ ---------- * ( 1 + Poly(1/x^2) ) * x*sqrt(pi) * * 5. For inf > x >= 107 * erf(x) = sign(x) *(1 - tiny) (raise inexact) * erfc(x) = tiny*tiny (raise underflow) if x > 0 * = 2 - tiny if x<0 * * 7. Special case: * erf(0) = 0, erf(inf) = 1, erf(-inf) = -1, * erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2, * erfc/erf(NaN) is NaN */ #include #include "math_private.h" /* Evaluate P[n] x^n + P[n-1] x^(n-1) + ... + P[0] */ static long double neval (long double x, const long double *p, int n) { long double y; p += n; y = *p--; do { y = y * x + *p--; } while (--n > 0); return y; } /* Evaluate x^n+1 + P[n] x^(n) + P[n-1] x^(n-1) + ... + P[0] */ static long double deval (long double x, const long double *p, int n) { long double y; p += n; y = x + *p--; do { y = y * x + *p--; } while (--n > 0); return y; } static const long double tiny = 1e-4931L, one = 1.0L, two = 2.0L, /* 2/sqrt(pi) - 1 */ efx = 1.2837916709551257389615890312154517168810E-1L, /* 8 * (2/sqrt(pi) - 1) */ efx8 = 1.0270333367641005911692712249723613735048E0L; /* erf(x) = x + x R(x^2) 0 <= x <= 7/8 Peak relative error 1.8e-35 */ #define NTN1 8 static const long double TN1[NTN1 + 1] = { -3.858252324254637124543172907442106422373E10L, 9.580319248590464682316366876952214879858E10L, 1.302170519734879977595901236693040544854E10L, 2.922956950426397417800321486727032845006E9L, 1.764317520783319397868923218385468729799E8L, 1.573436014601118630105796794840834145120E7L, 4.028077380105721388745632295157816229289E5L, 1.644056806467289066852135096352853491530E4L, 3.390868480059991640235675479463287886081E1L }; #define NTD1 8 static const long double TD1[NTD1 + 1] = { -3.005357030696532927149885530689529032152E11L, -1.342602283126282827411658673839982164042E11L, -2.777153893355340961288511024443668743399E10L, -3.483826391033531996955620074072768276974E9L, -2.906321047071299585682722511260895227921E8L, -1.653347985722154162439387878512427542691E7L, -6.245520581562848778466500301865173123136E5L, -1.402124304177498828590239373389110545142E4L, -1.209368072473510674493129989468348633579E2L /* 1.0E0 */ }; /* erf(z+1) = erf_const + P(z)/Q(z) -.125 <= z <= 0 Peak relative error 7.3e-36 */ static const long double erf_const = 0.845062911510467529296875L; #define NTN2 8 static const long double TN2[NTN2 + 1] = { -4.088889697077485301010486931817357000235E1L, 7.157046430681808553842307502826960051036E3L, -2.191561912574409865550015485451373731780E3L, 2.180174916555316874988981177654057337219E3L, 2.848578658049670668231333682379720943455E2L, 1.630362490952512836762810462174798925274E2L, 6.317712353961866974143739396865293596895E0L, 2.450441034183492434655586496522857578066E1L, 5.127662277706787664956025545897050896203E-1L }; #define NTD2 8 static const long double TD2[NTD2 + 1] = { 1.731026445926834008273768924015161048885E4L, 1.209682239007990370796112604286048173750E4L, 1.160950290217993641320602282462976163857E4L, 5.394294645127126577825507169061355698157E3L, 2.791239340533632669442158497532521776093E3L, 8.989365571337319032943005387378993827684E2L, 2.974016493766349409725385710897298069677E2L, 6.148192754590376378740261072533527271947E1L, 1.178502892490738445655468927408440847480E1L /* 1.0E0 */ }; /* erfc(x + 0.25) = erfc(0.25) + x R(x) 0 <= x < 0.125 Peak relative error 1.4e-35 */ #define NRNr13 8 static const long double RNr13[NRNr13 + 1] = { -2.353707097641280550282633036456457014829E3L, 3.871159656228743599994116143079870279866E2L, -3.888105134258266192210485617504098426679E2L, -2.129998539120061668038806696199343094971E1L, -8.125462263594034672468446317145384108734E1L, 8.151549093983505810118308635926270319660E0L, -5.033362032729207310462422357772568553670E0L, -4.253956621135136090295893547735851168471E-2L, -8.098602878463854789780108161581050357814E-2L }; #define NRDr13 7 static const long double RDr13[NRDr13 + 1] = { 2.220448796306693503549505450626652881752E3L, 1.899133258779578688791041599040951431383E2L, 1.061906712284961110196427571557149268454E3L, 7.497086072306967965180978101974566760042E1L, 2.146796115662672795876463568170441327274E2L, 1.120156008362573736664338015952284925592E1L, 2.211014952075052616409845051695042741074E1L, 6.469655675326150785692908453094054988938E-1L /* 1.0E0 */ }; /* erfc(0.25) = C13a + C13b to extra precision. */ static const long double C13a = 0.723663330078125L; static const long double C13b = 1.0279753638067014931732235184287934646022E-5L; /* erfc(x + 0.375) = erfc(0.375) + x R(x) 0 <= x < 0.125 Peak relative error 1.2e-35 */ #define NRNr14 8 static const long double RNr14[NRNr14 + 1] = { -2.446164016404426277577283038988918202456E3L, 6.718753324496563913392217011618096698140E2L, -4.581631138049836157425391886957389240794E2L, -2.382844088987092233033215402335026078208E1L, -7.119237852400600507927038680970936336458E1L, 1.313609646108420136332418282286454287146E1L, -6.188608702082264389155862490056401365834E0L, -2.787116601106678287277373011101132659279E-2L, -2.230395570574153963203348263549700967918E-2L }; #define NRDr14 7 static const long double RDr14[NRDr14 + 1] = { 2.495187439241869732696223349840963702875E3L, 2.503549449872925580011284635695738412162E2L, 1.159033560988895481698051531263861842461E3L, 9.493751466542304491261487998684383688622E1L, 2.276214929562354328261422263078480321204E2L, 1.367697521219069280358984081407807931847E1L, 2.276988395995528495055594829206582732682E1L, 7.647745753648996559837591812375456641163E-1L /* 1.0E0 */ }; /* erfc(0.375) = C14a + C14b to extra precision. */ static const long double C14a = 0.5958709716796875L; static const long double C14b = 1.2118885490201676174914080878232469565953E-5L; /* erfc(x + 0.5) = erfc(0.5) + x R(x) 0 <= x < 0.125 Peak relative error 4.7e-36 */ #define NRNr15 8 static const long double RNr15[NRNr15 + 1] = { -2.624212418011181487924855581955853461925E3L, 8.473828904647825181073831556439301342756E2L, -5.286207458628380765099405359607331669027E2L, -3.895781234155315729088407259045269652318E1L, -6.200857908065163618041240848728398496256E1L, 1.469324610346924001393137895116129204737E1L, -6.961356525370658572800674953305625578903E0L, 5.145724386641163809595512876629030548495E-3L, 1.990253655948179713415957791776180406812E-2L }; #define NRDr15 7 static const long double RDr15[NRDr15 + 1] = { 2.986190760847974943034021764693341524962E3L, 5.288262758961073066335410218650047725985E2L, 1.363649178071006978355113026427856008978E3L, 1.921707975649915894241864988942255320833E2L, 2.588651100651029023069013885900085533226E2L, 2.628752920321455606558942309396855629459E1L, 2.455649035885114308978333741080991380610E1L, 1.378826653595128464383127836412100939126E0L /* 1.0E0 */ }; /* erfc(0.5) = C15a + C15b to extra precision. */ static const long double C15a = 0.4794921875L; static const long double C15b = 7.9346869534623172533461080354712635484242E-6L; /* erfc(x + 0.625) = erfc(0.625) + x R(x) 0 <= x < 0.125 Peak relative error 5.1e-36 */ #define NRNr16 8 static const long double RNr16[NRNr16 + 1] = { -2.347887943200680563784690094002722906820E3L, 8.008590660692105004780722726421020136482E2L, -5.257363310384119728760181252132311447963E2L, -4.471737717857801230450290232600243795637E1L, -4.849540386452573306708795324759300320304E1L, 1.140885264677134679275986782978655952843E1L, -6.731591085460269447926746876983786152300E0L, 1.370831653033047440345050025876085121231E-1L, 2.022958279982138755020825717073966576670E-2L, }; #define NRDr16 7 static const long double RDr16[NRDr16 + 1] = { 3.075166170024837215399323264868308087281E3L, 8.730468942160798031608053127270430036627E2L, 1.458472799166340479742581949088453244767E3L, 3.230423687568019709453130785873540386217E2L, 2.804009872719893612081109617983169474655E2L, 4.465334221323222943418085830026979293091E1L, 2.612723259683205928103787842214809134746E1L, 2.341526751185244109722204018543276124997E0L, /* 1.0E0 */ }; /* erfc(0.625) = C16a + C16b to extra precision. */ static const long double C16a = 0.3767547607421875L; static const long double C16b = 4.3570693945275513594941232097252997287766E-6L; /* erfc(x + 0.75) = erfc(0.75) + x R(x) 0 <= x < 0.125 Peak relative error 1.7e-35 */ #define NRNr17 8 static const long double RNr17[NRNr17 + 1] = { -1.767068734220277728233364375724380366826E3L, 6.693746645665242832426891888805363898707E2L, -4.746224241837275958126060307406616817753E2L, -2.274160637728782675145666064841883803196E1L, -3.541232266140939050094370552538987982637E1L, 6.988950514747052676394491563585179503865E0L, -5.807687216836540830881352383529281215100E0L, 3.631915988567346438830283503729569443642E-1L, -1.488945487149634820537348176770282391202E-2L }; #define NRDr17 7 static const long double RDr17[NRDr17 + 1] = { 2.748457523498150741964464942246913394647E3L, 1.020213390713477686776037331757871252652E3L, 1.388857635935432621972601695296561952738E3L, 3.903363681143817750895999579637315491087E2L, 2.784568344378139499217928969529219886578E2L, 5.555800830216764702779238020065345401144E1L, 2.646215470959050279430447295801291168941E1L, 2.984905282103517497081766758550112011265E0L, /* 1.0E0 */ }; /* erfc(0.75) = C17a + C17b to extra precision. */ static const long double C17a = 0.2888336181640625L; static const long double C17b = 1.0748182422368401062165408589222625794046E-5L; /* erfc(x + 0.875) = erfc(0.875) + x R(x) 0 <= x < 0.125 Peak relative error 2.2e-35 */ #define NRNr18 8 static const long double RNr18[NRNr18 + 1] = { -1.342044899087593397419622771847219619588E3L, 6.127221294229172997509252330961641850598E2L, -4.519821356522291185621206350470820610727E2L, 1.223275177825128732497510264197915160235E1L, -2.730789571382971355625020710543532867692E1L, 4.045181204921538886880171727755445395862E0L, -4.925146477876592723401384464691452700539E0L, 5.933878036611279244654299924101068088582E-1L, -5.557645435858916025452563379795159124753E-2L }; #define NRDr18 7 static const long double RDr18[NRDr18 + 1] = { 2.557518000661700588758505116291983092951E3L, 1.070171433382888994954602511991940418588E3L, 1.344842834423493081054489613250688918709E3L, 4.161144478449381901208660598266288188426E2L, 2.763670252219855198052378138756906980422E2L, 5.998153487868943708236273854747564557632E1L, 2.657695108438628847733050476209037025318E1L, 3.252140524394421868923289114410336976512E0L, /* 1.0E0 */ }; /* erfc(0.875) = C18a + C18b to extra precision. */ static const long double C18a = 0.215911865234375L; static const long double C18b = 1.3073705765341685464282101150637224028267E-5L; /* erfc(x + 1.0) = erfc(1.0) + x R(x) 0 <= x < 0.125 Peak relative error 1.6e-35 */ #define NRNr19 8 static const long double RNr19[NRNr19 + 1] = { -1.139180936454157193495882956565663294826E3L, 6.134903129086899737514712477207945973616E2L, -4.628909024715329562325555164720732868263E2L, 4.165702387210732352564932347500364010833E1L, -2.286979913515229747204101330405771801610E1L, 1.870695256449872743066783202326943667722E0L, -4.177486601273105752879868187237000032364E0L, 7.533980372789646140112424811291782526263E-1L, -8.629945436917752003058064731308767664446E-2L }; #define NRDr19 7 static const long double RDr19[NRDr19 + 1] = { 2.744303447981132701432716278363418643778E3L, 1.266396359526187065222528050591302171471E3L, 1.466739461422073351497972255511919814273E3L, 4.868710570759693955597496520298058147162E2L, 2.993694301559756046478189634131722579643E2L, 6.868976819510254139741559102693828237440E1L, 2.801505816247677193480190483913753613630E1L, 3.604439909194350263552750347742663954481E0L, /* 1.0E0 */ }; /* erfc(1.0) = C19a + C19b to extra precision. */ static const long double C19a = 0.15728759765625L; static const long double C19b = 1.1609394035130658779364917390740703933002E-5L; /* erfc(x + 1.125) = erfc(1.125) + x R(x) 0 <= x < 0.125 Peak relative error 3.6e-36 */ #define NRNr20 8 static const long double RNr20[NRNr20 + 1] = { -9.652706916457973956366721379612508047640E2L, 5.577066396050932776683469951773643880634E2L, -4.406335508848496713572223098693575485978E2L, 5.202893466490242733570232680736966655434E1L, -1.931311847665757913322495948705563937159E1L, -9.364318268748287664267341457164918090611E-2L, -3.306390351286352764891355375882586201069E0L, 7.573806045289044647727613003096916516475E-1L, -9.611744011489092894027478899545635991213E-2L }; #define NRDr20 7 static const long double RDr20[NRDr20 + 1] = { 3.032829629520142564106649167182428189014E3L, 1.659648470721967719961167083684972196891E3L, 1.703545128657284619402511356932569292535E3L, 6.393465677731598872500200253155257708763E2L, 3.489131397281030947405287112726059221934E2L, 8.848641738570783406484348434387611713070E1L, 3.132269062552392974833215844236160958502E1L, 4.430131663290563523933419966185230513168E0L /* 1.0E0 */ }; /* erfc(1.125) = C20a + C20b to extra precision. */ static const long double C20a = 0.111602783203125L; static const long double C20b = 8.9850951672359304215530728365232161564636E-6L; /* erfc(1/x) = 1/x exp (-1/x^2 - 0.5625 + R(1/x^2)) 7/8 <= 1/x < 1 Peak relative error 1.4e-35 */ #define NRNr8 9 static const long double RNr8[NRNr8 + 1] = { 3.587451489255356250759834295199296936784E1L, 5.406249749087340431871378009874875889602E2L, 2.931301290625250886238822286506381194157E3L, 7.359254185241795584113047248898753470923E3L, 9.201031849810636104112101947312492532314E3L, 5.749697096193191467751650366613289284777E3L, 1.710415234419860825710780802678697889231E3L, 2.150753982543378580859546706243022719599E2L, 8.740953582272147335100537849981160931197E0L, 4.876422978828717219629814794707963640913E-2L }; #define NRDr8 8 static const long double RDr8[NRDr8 + 1] = { 6.358593134096908350929496535931630140282E1L, 9.900253816552450073757174323424051765523E2L, 5.642928777856801020545245437089490805186E3L, 1.524195375199570868195152698617273739609E4L, 2.113829644500006749947332935305800887345E4L, 1.526438562626465706267943737310282977138E4L, 5.561370922149241457131421914140039411782E3L, 9.394035530179705051609070428036834496942E2L, 6.147019596150394577984175188032707343615E1L /* 1.0E0 */ }; /* erfc(1/x) = 1/x exp (-1/x^2 - 0.5625 + R(1/x^2)) 0.75 <= 1/x <= 0.875 Peak relative error 2.0e-36 */ #define NRNr7 9 static const long double RNr7[NRNr7 + 1] = { 1.686222193385987690785945787708644476545E1L, 1.178224543567604215602418571310612066594E3L, 1.764550584290149466653899886088166091093E4L, 1.073758321890334822002849369898232811561E5L, 3.132840749205943137619839114451290324371E5L, 4.607864939974100224615527007793867585915E5L, 3.389781820105852303125270837910972384510E5L, 1.174042187110565202875011358512564753399E5L, 1.660013606011167144046604892622504338313E4L, 6.700393957480661937695573729183733234400E2L }; #define NRDr7 9 static const long double RDr7[NRDr7 + 1] = { -1.709305024718358874701575813642933561169E3L, -3.280033887481333199580464617020514788369E4L, -2.345284228022521885093072363418750835214E5L, -8.086758123097763971926711729242327554917E5L, -1.456900414510108718402423999575992450138E6L, -1.391654264881255068392389037292702041855E6L, -6.842360801869939983674527468509852583855E5L, -1.597430214446573566179675395199807533371E5L, -1.488876130609876681421645314851760773480E4L, -3.511762950935060301403599443436465645703E2L /* 1.0E0 */ }; /* erfc(1/x) = 1/x exp(-1/x^2 - 0.5625 + R(1/x^2)) 5/8 <= 1/x < 3/4 Peak relative error 1.9e-35 */ #define NRNr6 9 static const long double RNr6[NRNr6 + 1] = { 1.642076876176834390623842732352935761108E0L, 1.207150003611117689000664385596211076662E2L, 2.119260779316389904742873816462800103939E3L, 1.562942227734663441801452930916044224174E4L, 5.656779189549710079988084081145693580479E4L, 1.052166241021481691922831746350942786299E5L, 9.949798524786000595621602790068349165758E4L, 4.491790734080265043407035220188849562856E4L, 8.377074098301530326270432059434791287601E3L, 4.506934806567986810091824791963991057083E2L }; #define NRDr6 9 static const long double RDr6[NRDr6 + 1] = { -1.664557643928263091879301304019826629067E2L, -3.800035902507656624590531122291160668452E3L, -3.277028191591734928360050685359277076056E4L, -1.381359471502885446400589109566587443987E5L, -3.082204287382581873532528989283748656546E5L, -3.691071488256738343008271448234631037095E5L, -2.300482443038349815750714219117566715043E5L, -6.873955300927636236692803579555752171530E4L, -8.262158817978334142081581542749986845399E3L, -2.517122254384430859629423488157361983661E2L /* 1.00 */ }; /* erfc(1/x) = 1/x exp(-1/x^2 - 0.5625 + R(1/x^2)) 1/2 <= 1/x < 5/8 Peak relative error 4.6e-36 */ #define NRNr5 10 static const long double RNr5[NRNr5 + 1] = { -3.332258927455285458355550878136506961608E-3L, -2.697100758900280402659586595884478660721E-1L, -6.083328551139621521416618424949137195536E0L, -6.119863528983308012970821226810162441263E1L, -3.176535282475593173248810678636522589861E2L, -8.933395175080560925809992467187963260693E2L, -1.360019508488475978060917477620199499560E3L, -1.075075579828188621541398761300910213280E3L, -4.017346561586014822824459436695197089916E2L, -5.857581368145266249509589726077645791341E1L, -2.077715925587834606379119585995758954399E0L }; #define NRDr5 9 static const long double RDr5[NRDr5 + 1] = { 3.377879570417399341550710467744693125385E-1L, 1.021963322742390735430008860602594456187E1L, 1.200847646592942095192766255154827011939E2L, 7.118915528142927104078182863387116942836E2L, 2.318159380062066469386544552429625026238E3L, 4.238729853534009221025582008928765281620E3L, 4.279114907284825886266493994833515580782E3L, 2.257277186663261531053293222591851737504E3L, 5.570475501285054293371908382916063822957E2L, 5.142189243856288981145786492585432443560E1L /* 1.0E0 */ }; /* erfc(1/x) = 1/x exp(-1/x^2 - 0.5625 + R(1/x^2)) 3/8 <= 1/x < 1/2 Peak relative error 2.0e-36 */ #define NRNr4 10 static const long double RNr4[NRNr4 + 1] = { 3.258530712024527835089319075288494524465E-3L, 2.987056016877277929720231688689431056567E-1L, 8.738729089340199750734409156830371528862E0L, 1.207211160148647782396337792426311125923E2L, 8.997558632489032902250523945248208224445E2L, 3.798025197699757225978410230530640879762E3L, 9.113203668683080975637043118209210146846E3L, 1.203285891339933238608683715194034900149E4L, 8.100647057919140328536743641735339740855E3L, 2.383888249907144945837976899822927411769E3L, 2.127493573166454249221983582495245662319E2L }; #define NRDr4 10 static const long double RDr4[NRDr4 + 1] = { -3.303141981514540274165450687270180479586E-1L, -1.353768629363605300707949368917687066724E1L, -2.206127630303621521950193783894598987033E2L, -1.861800338758066696514480386180875607204E3L, -8.889048775872605708249140016201753255599E3L, -2.465888106627948210478692168261494857089E4L, -3.934642211710774494879042116768390014289E4L, -3.455077258242252974937480623730228841003E4L, -1.524083977439690284820586063729912653196E4L, -2.810541887397984804237552337349093953857E3L, -1.343929553541159933824901621702567066156E2L /* 1.0E0 */ }; /* erfc(1/x) = 1/x exp(-1/x^2 - 0.5625 + R(1/x^2)) 1/4 <= 1/x < 3/8 Peak relative error 8.4e-37 */ #define NRNr3 11 static const long double RNr3[NRNr3 + 1] = { -1.952401126551202208698629992497306292987E-6L, -2.130881743066372952515162564941682716125E-4L, -8.376493958090190943737529486107282224387E-3L, -1.650592646560987700661598877522831234791E-1L, -1.839290818933317338111364667708678163199E0L, -1.216278715570882422410442318517814388470E1L, -4.818759344462360427612133632533779091386E1L, -1.120994661297476876804405329172164436784E2L, -1.452850765662319264191141091859300126931E2L, -9.485207851128957108648038238656777241333E1L, -2.563663855025796641216191848818620020073E1L, -1.787995944187565676837847610706317833247E0L }; #define NRDr3 10 static const long double RDr3[NRDr3 + 1] = { 1.979130686770349481460559711878399476903E-4L, 1.156941716128488266238105813374635099057E-2L, 2.752657634309886336431266395637285974292E-1L, 3.482245457248318787349778336603569327521E0L, 2.569347069372696358578399521203959253162E1L, 1.142279000180457419740314694631879921561E2L, 3.056503977190564294341422623108332700840E2L, 4.780844020923794821656358157128719184422E2L, 4.105972727212554277496256802312730410518E2L, 1.724072188063746970865027817017067646246E2L, 2.815939183464818198705278118326590370435E1L /* 1.0E0 */ }; /* erfc(1/x) = 1/x exp(-1/x^2 - 0.5625 + R(1/x^2)) 1/8 <= 1/x < 1/4 Peak relative error 1.5e-36 */ #define NRNr2 11 static const long double RNr2[NRNr2 + 1] = { -2.638914383420287212401687401284326363787E-8L, -3.479198370260633977258201271399116766619E-6L, -1.783985295335697686382487087502222519983E-4L, -4.777876933122576014266349277217559356276E-3L, -7.450634738987325004070761301045014986520E-2L, -7.068318854874733315971973707247467326619E-1L, -4.113919921935944795764071670806867038732E0L, -1.440447573226906222417767283691888875082E1L, -2.883484031530718428417168042141288943905E1L, -2.990886974328476387277797361464279931446E1L, -1.325283914915104866248279787536128997331E1L, -1.572436106228070195510230310658206154374E0L }; #define NRDr2 10 static const long double RDr2[NRDr2 + 1] = { 2.675042728136731923554119302571867799673E-6L, 2.170997868451812708585443282998329996268E-4L, 7.249969752687540289422684951196241427445E-3L, 1.302040375859768674620410563307838448508E-1L, 1.380202483082910888897654537144485285549E0L, 8.926594113174165352623847870299170069350E0L, 3.521089584782616472372909095331572607185E1L, 8.233547427533181375185259050330809105570E1L, 1.072971579885803033079469639073292840135E2L, 6.943803113337964469736022094105143158033E1L, 1.775695341031607738233608307835017282662E1L /* 1.0E0 */ }; /* erfc(1/x) = 1/x exp(-1/x^2 - 0.5625 + R(1/x^2)) 1/128 <= 1/x < 1/8 Peak relative error 2.2e-36 */ #define NRNr1 9 static const long double RNr1[NRNr1 + 1] = { -4.250780883202361946697751475473042685782E-8L, -5.375777053288612282487696975623206383019E-6L, -2.573645949220896816208565944117382460452E-4L, -6.199032928113542080263152610799113086319E-3L, -8.262721198693404060380104048479916247786E-2L, -6.242615227257324746371284637695778043982E-1L, -2.609874739199595400225113299437099626386E0L, -5.581967563336676737146358534602770006970E0L, -5.124398923356022609707490956634280573882E0L, -1.290865243944292370661544030414667556649E0L }; #define NRDr1 8 static const long double RDr1[NRDr1 + 1] = { 4.308976661749509034845251315983612976224E-6L, 3.265390126432780184125233455960049294580E-4L, 9.811328839187040701901866531796570418691E-3L, 1.511222515036021033410078631914783519649E-1L, 1.289264341917429958858379585970225092274E0L, 6.147640356182230769548007536914983522270E0L, 1.573966871337739784518246317003956180750E1L, 1.955534123435095067199574045529218238263E1L, 9.472613121363135472247929109615785855865E0L /* 1.0E0 */ }; long double erfl(long double x) { long double a, y, z; int32_t i, ix, sign; ieee_quad_shape_type u; u.value = x; sign = u.parts32.mswhi; ix = sign & 0x7fffffff; if (ix >= 0x7fff0000) { /* erf(nan)=nan */ i = ((sign & 0xffff0000) >> 31) << 1; return (long double) (1 - i) + one / x; /* erf(+-inf)=+-1 */ } if (ix >= 0x3fff0000) /* |x| >= 1.0 */ { y = erfcl (x); return (one - y); /* return (one - erfcl (x)); */ } u.parts32.mswhi = ix; a = u.value; z = x * x; if (ix < 0x3ffec000) /* a < 0.875 */ { if (ix < 0x3fc60000) /* |x|<2**-57 */ { if (ix < 0x00080000) return 0.125 * (8.0 * x + efx8 * x); /*avoid underflow */ return x + efx * x; } y = a + a * neval (z, TN1, NTN1) / deval (z, TD1, NTD1); } else { a = a - one; y = erf_const + neval (a, TN2, NTN2) / deval (a, TD2, NTD2); } if (sign & 0x80000000) /* x < 0 */ y = -y; return( y ); } long double erfcl(long double x) { long double y, z, p, r; int32_t i, ix, sign; ieee_quad_shape_type u; u.value = x; sign = u.parts32.mswhi; ix = sign & 0x7fffffff; u.parts32.mswhi = ix; if (ix >= 0x7fff0000) { /* erfc(nan)=nan */ /* erfc(+-inf)=0,2 */ return (long double) (((u_int32_t) sign >> 31) << 1) + one / x; } if (ix < 0x3ffd0000) /* |x| <1/4 */ { if (ix < 0x3f8d0000) /* |x|<2**-114 */ return one - x; return one - erfl (x); } if (ix < 0x3fff4000) /* 1.25 */ { x = u.value; i = 8.0 * x; switch (i) { case 2: z = x - 0.25L; y = C13b + z * neval (z, RNr13, NRNr13) / deval (z, RDr13, NRDr13); y += C13a; break; case 3: z = x - 0.375L; y = C14b + z * neval (z, RNr14, NRNr14) / deval (z, RDr14, NRDr14); y += C14a; break; case 4: z = x - 0.5L; y = C15b + z * neval (z, RNr15, NRNr15) / deval (z, RDr15, NRDr15); y += C15a; break; case 5: z = x - 0.625L; y = C16b + z * neval (z, RNr16, NRNr16) / deval (z, RDr16, NRDr16); y += C16a; break; case 6: z = x - 0.75L; y = C17b + z * neval (z, RNr17, NRNr17) / deval (z, RDr17, NRDr17); y += C17a; break; case 7: z = x - 0.875L; y = C18b + z * neval (z, RNr18, NRNr18) / deval (z, RDr18, NRDr18); y += C18a; break; case 8: z = x - 1.0L; y = C19b + z * neval (z, RNr19, NRNr19) / deval (z, RDr19, NRDr19); y += C19a; break; case 9: z = x - 1.125L; y = C20b + z * neval (z, RNr20, NRNr20) / deval (z, RDr20, NRDr20); y += C20a; break; } if (sign & 0x80000000) y = 2.0L - y; return y; } /* 1.25 < |x| < 107 */ if (ix < 0x4005ac00) { /* x < -9 */ if ((ix >= 0x40022000) && (sign & 0x80000000)) return two - tiny; x = fabsl (x); z = one / (x * x); i = 8.0 / x; switch (i) { default: case 0: p = neval (z, RNr1, NRNr1) / deval (z, RDr1, NRDr1); break; case 1: p = neval (z, RNr2, NRNr2) / deval (z, RDr2, NRDr2); break; case 2: p = neval (z, RNr3, NRNr3) / deval (z, RDr3, NRDr3); break; case 3: p = neval (z, RNr4, NRNr4) / deval (z, RDr4, NRDr4); break; case 4: p = neval (z, RNr5, NRNr5) / deval (z, RDr5, NRDr5); break; case 5: p = neval (z, RNr6, NRNr6) / deval (z, RDr6, NRDr6); break; case 6: p = neval (z, RNr7, NRNr7) / deval (z, RDr7, NRDr7); break; case 7: p = neval (z, RNr8, NRNr8) / deval (z, RDr8, NRDr8); break; } u.value = x; u.parts32.lswlo = 0; u.parts32.lswhi &= 0xfe000000; z = u.value; r = expl (-z * z - 0.5625) * expl ((z - x) * (z + x) + p); if ((sign & 0x80000000) == 0) return r / x; else return two - r / x; } else { if ((sign & 0x80000000) == 0) return tiny * tiny; else return two - tiny; } } openlibm-0.5.0/ld128/s_exp2l.c000066400000000000000000000312211266752446200157100ustar00rootroot00000000000000/*- * Copyright (c) 2005-2008 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/ld128/s_exp2l.c,v 1.3 2008/02/13 10:44:44 bde Exp $"); #include #include #include #include "fpmath.h" #include "math_private.h" #define TBLBITS 7 #define TBLSIZE (1 << TBLBITS) #define BIAS (LDBL_MAX_EXP - 1) #define EXPMASK (BIAS + LDBL_MAX_EXP) #if 0 /* XXX Prevent gcc from erroneously constant folding this. */ static const long double twom10000 = 0x1p-10000L; #else static volatile long double twom10000 = 0x1p-10000L; #endif static const long double huge = 0x1p10000L, P1 = 0x1.62e42fefa39ef35793c7673007e6p-1L, P2 = 0x1.ebfbdff82c58ea86f16b06ec9736p-3L, P3 = 0x1.c6b08d704a0bf8b33a762bad3459p-5L, P4 = 0x1.3b2ab6fba4e7729ccbbe0b4f3fc2p-7L, P5 = 0x1.5d87fe78a67311071dee13fd11d9p-10L, P6 = 0x1.430912f86c7876f4b663b23c5fe5p-13L; static const double P7 = 0x1.ffcbfc588b041p-17, P8 = 0x1.62c0223a5c7c7p-20, P9 = 0x1.b52541ff59713p-24, P10 = 0x1.e4cf56a391e22p-28, redux = 0x1.8p112 / TBLSIZE; static const long double tbl[TBLSIZE] = { 0x1.6a09e667f3bcc908b2fb1366dfeap-1L, 0x1.6c012750bdabeed76a99800f4edep-1L, 0x1.6dfb23c651a2ef220e2cbe1bc0d4p-1L, 0x1.6ff7df9519483cf87e1b4f3e1e98p-1L, 0x1.71f75e8ec5f73dd2370f2ef0b148p-1L, 0x1.73f9a48a58173bd5c9a4e68ab074p-1L, 0x1.75feb564267c8bf6e9aa33a489a8p-1L, 0x1.780694fde5d3f619ae02808592a4p-1L, 0x1.7a11473eb0186d7d51023f6ccb1ap-1L, 0x1.7c1ed0130c1327c49334459378dep-1L, 0x1.7e2f336cf4e62105d02ba1579756p-1L, 0x1.80427543e1a11b60de67649a3842p-1L, 0x1.82589994cce128acf88afab34928p-1L, 0x1.8471a4623c7acce52f6b97c6444cp-1L, 0x1.868d99b4492ec80e41d90ac2556ap-1L, 0x1.88ac7d98a669966530bcdf2d4cc0p-1L, 0x1.8ace5422aa0db5ba7c55a192c648p-1L, 0x1.8cf3216b5448bef2aa1cd161c57ap-1L, 0x1.8f1ae991577362b982745c72eddap-1L, 0x1.9145b0b91ffc588a61b469f6b6a0p-1L, 0x1.93737b0cdc5e4f4501c3f2540ae8p-1L, 0x1.95a44cbc8520ee9b483695a0e7fep-1L, 0x1.97d829fde4e4f8b9e920f91e8eb6p-1L, 0x1.9a0f170ca07b9ba3109b8c467844p-1L, 0x1.9c49182a3f0901c7c46b071f28dep-1L, 0x1.9e86319e323231824ca78e64c462p-1L, 0x1.a0c667b5de564b29ada8b8cabbacp-1L, 0x1.a309bec4a2d3358c171f770db1f4p-1L, 0x1.a5503b23e255c8b424491caf88ccp-1L, 0x1.a799e1330b3586f2dfb2b158f31ep-1L, 0x1.a9e6b5579fdbf43eb243bdff53a2p-1L, 0x1.ac36bbfd3f379c0db966a3126988p-1L, 0x1.ae89f995ad3ad5e8734d17731c80p-1L, 0x1.b0e07298db66590842acdfc6fb4ep-1L, 0x1.b33a2b84f15faf6bfd0e7bd941b0p-1L, 0x1.b59728de559398e3881111648738p-1L, 0x1.b7f76f2fb5e46eaa7b081ab53ff6p-1L, 0x1.ba5b030a10649840cb3c6af5b74cp-1L, 0x1.bcc1e904bc1d2247ba0f45b3d06cp-1L, 0x1.bf2c25bd71e088408d7025190cd0p-1L, 0x1.c199bdd85529c2220cb12a0916bap-1L, 0x1.c40ab5fffd07a6d14df820f17deap-1L, 0x1.c67f12e57d14b4a2137fd20f2a26p-1L, 0x1.c8f6d9406e7b511acbc48805c3f6p-1L, 0x1.cb720dcef90691503cbd1e949d0ap-1L, 0x1.cdf0b555dc3f9c44f8958fac4f12p-1L, 0x1.d072d4a07897b8d0f22f21a13792p-1L, 0x1.d2f87080d89f18ade123989ea50ep-1L, 0x1.d5818dcfba48725da05aeb66dff8p-1L, 0x1.d80e316c98397bb84f9d048807a0p-1L, 0x1.da9e603db3285708c01a5b6d480cp-1L, 0x1.dd321f301b4604b695de3c0630c0p-1L, 0x1.dfc97337b9b5eb968cac39ed284cp-1L, 0x1.e264614f5a128a12761fa17adc74p-1L, 0x1.e502ee78b3ff6273d130153992d0p-1L, 0x1.e7a51fbc74c834b548b2832378a4p-1L, 0x1.ea4afa2a490d9858f73a18f5dab4p-1L, 0x1.ecf482d8e67f08db0312fb949d50p-1L, 0x1.efa1bee615a27771fd21a92dabb6p-1L, 0x1.f252b376bba974e8696fc3638f24p-1L, 0x1.f50765b6e4540674f84b762861a6p-1L, 0x1.f7bfdad9cbe138913b4bfe72bd78p-1L, 0x1.fa7c1819e90d82e90a7e74b26360p-1L, 0x1.fd3c22b8f71f10975ba4b32bd006p-1L, 0x1.0000000000000000000000000000p+0L, 0x1.0163da9fb33356d84a66ae336e98p+0L, 0x1.02c9a3e778060ee6f7caca4f7a18p+0L, 0x1.04315e86e7f84bd738f9a20da442p+0L, 0x1.059b0d31585743ae7c548eb68c6ap+0L, 0x1.0706b29ddf6ddc6dc403a9d87b1ep+0L, 0x1.0874518759bc808c35f25d942856p+0L, 0x1.09e3ecac6f3834521e060c584d5cp+0L, 0x1.0b5586cf9890f6298b92b7184200p+0L, 0x1.0cc922b7247f7407b705b893dbdep+0L, 0x1.0e3ec32d3d1a2020742e4f8af794p+0L, 0x1.0fb66affed31af232091dd8a169ep+0L, 0x1.11301d0125b50a4ebbf1aed9321cp+0L, 0x1.12abdc06c31cbfb92bad324d6f84p+0L, 0x1.1429aaea92ddfb34101943b2588ep+0L, 0x1.15a98c8a58e512480d573dd562aep+0L, 0x1.172b83c7d517adcdf7c8c50eb162p+0L, 0x1.18af9388c8de9bbbf70b9a3c269cp+0L, 0x1.1a35beb6fcb753cb698f692d2038p+0L, 0x1.1bbe084045cd39ab1e72b442810ep+0L, 0x1.1d4873168b9aa7805b8028990be8p+0L, 0x1.1ed5022fcd91cb8819ff61121fbep+0L, 0x1.2063b88628cd63b8eeb0295093f6p+0L, 0x1.21f49917ddc962552fd29294bc20p+0L, 0x1.2387a6e75623866c1fadb1c159c0p+0L, 0x1.251ce4fb2a63f3582ab7de9e9562p+0L, 0x1.26b4565e27cdd257a673281d3068p+0L, 0x1.284dfe1f5638096cf15cf03c9fa0p+0L, 0x1.29e9df51fdee12c25d15f5a25022p+0L, 0x1.2b87fd0dad98ffddea46538fca24p+0L, 0x1.2d285a6e4030b40091d536d0733ep+0L, 0x1.2ecafa93e2f5611ca0f45d5239a4p+0L, 0x1.306fe0a31b7152de8d5a463063bep+0L, 0x1.32170fc4cd8313539cf1c3009330p+0L, 0x1.33c08b26416ff4c9c8610d96680ep+0L, 0x1.356c55f929ff0c94623476373be4p+0L, 0x1.371a7373aa9caa7145502f45452ap+0L, 0x1.38cae6d05d86585a9cb0d9bed530p+0L, 0x1.3a7db34e59ff6ea1bc9299e0a1fep+0L, 0x1.3c32dc313a8e484001f228b58cf0p+0L, 0x1.3dea64c12342235b41223e13d7eep+0L, 0x1.3fa4504ac801ba0bf701aa417b9cp+0L, 0x1.4160a21f72e29f84325b8f3dbacap+0L, 0x1.431f5d950a896dc704439410b628p+0L, 0x1.44e086061892d03136f409df0724p+0L, 0x1.46a41ed1d005772512f459229f0ap+0L, 0x1.486a2b5c13cd013c1a3b69062f26p+0L, 0x1.4a32af0d7d3de672d8bcf46f99b4p+0L, 0x1.4bfdad5362a271d4397afec42e36p+0L, 0x1.4dcb299fddd0d63b36ef1a9e19dep+0L, 0x1.4f9b2769d2ca6ad33d8b69aa0b8cp+0L, 0x1.516daa2cf6641c112f52c84d6066p+0L, 0x1.5342b569d4f81df0a83c49d86bf4p+0L, 0x1.551a4ca5d920ec52ec620243540cp+0L, 0x1.56f4736b527da66ecb004764e61ep+0L, 0x1.58d12d497c7fd252bc2b7343d554p+0L, 0x1.5ab07dd48542958c93015191e9a8p+0L, 0x1.5c9268a5946b701c4b1b81697ed4p+0L, 0x1.5e76f15ad21486e9be4c20399d12p+0L, 0x1.605e1b976dc08b076f592a487066p+0L, 0x1.6247eb03a5584b1f0fa06fd2d9eap+0L, 0x1.6434634ccc31fc76f8714c4ee122p+0L, 0x1.66238825522249127d9e29b92ea2p+0L, 0x1.68155d44ca973081c57227b9f69ep+0L, }; static const float eps[TBLSIZE] = { -0x1.5c50p-101, -0x1.5d00p-106, 0x1.8e90p-102, -0x1.5340p-103, 0x1.1bd0p-102, -0x1.4600p-105, -0x1.7a40p-104, 0x1.d590p-102, -0x1.d590p-101, 0x1.b100p-103, -0x1.0d80p-105, 0x1.6b00p-103, -0x1.9f00p-105, 0x1.c400p-103, 0x1.e120p-103, -0x1.c100p-104, -0x1.9d20p-103, 0x1.a800p-108, 0x1.4c00p-106, -0x1.9500p-106, 0x1.6900p-105, -0x1.29d0p-100, 0x1.4c60p-103, 0x1.13a0p-102, -0x1.5b60p-103, -0x1.1c40p-103, 0x1.db80p-102, 0x1.91a0p-102, 0x1.dc00p-105, 0x1.44c0p-104, 0x1.9710p-102, 0x1.8760p-103, -0x1.a720p-103, 0x1.ed20p-103, -0x1.49c0p-102, -0x1.e000p-111, 0x1.86a0p-103, 0x1.2b40p-103, -0x1.b400p-108, 0x1.1280p-99, -0x1.02d8p-102, -0x1.e3d0p-103, -0x1.b080p-105, -0x1.f100p-107, -0x1.16c0p-105, -0x1.1190p-103, -0x1.a7d2p-100, 0x1.3450p-103, -0x1.67c0p-105, 0x1.4b80p-104, -0x1.c4e0p-103, 0x1.6000p-108, -0x1.3f60p-105, 0x1.93f0p-104, 0x1.5fe0p-105, 0x1.6f80p-107, -0x1.7600p-106, 0x1.21e0p-106, -0x1.3a40p-106, -0x1.40c0p-104, -0x1.9860p-105, -0x1.5d40p-108, -0x1.1d70p-106, 0x1.2760p-105, 0x0.0000p+0, 0x1.21e2p-104, -0x1.9520p-108, -0x1.5720p-106, -0x1.4810p-106, -0x1.be00p-109, 0x1.0080p-105, -0x1.5780p-108, -0x1.d460p-105, -0x1.6140p-105, 0x1.4630p-104, 0x1.ad50p-103, 0x1.82e0p-105, 0x1.1d3cp-101, 0x1.6100p-107, 0x1.ec30p-104, 0x1.f200p-108, 0x1.0b40p-103, 0x1.3660p-102, 0x1.d9d0p-103, -0x1.02d0p-102, 0x1.b070p-103, 0x1.b9c0p-104, -0x1.01c0p-103, -0x1.dfe0p-103, 0x1.1b60p-104, -0x1.ae94p-101, -0x1.3340p-104, 0x1.b3d8p-102, -0x1.6e40p-105, -0x1.3670p-103, 0x1.c140p-104, 0x1.1840p-101, 0x1.1ab0p-102, -0x1.a400p-104, 0x1.1f00p-104, -0x1.7180p-103, 0x1.4ce0p-102, 0x1.9200p-107, -0x1.54c0p-103, 0x1.1b80p-105, -0x1.1828p-101, 0x1.5720p-102, -0x1.a060p-100, 0x1.9160p-102, 0x1.a280p-104, 0x1.3400p-107, 0x1.2b20p-102, 0x1.7800p-108, 0x1.cfd0p-101, 0x1.2ef0p-102, -0x1.2760p-99, 0x1.b380p-104, 0x1.0048p-101, -0x1.60b0p-102, 0x1.a1ccp-100, -0x1.a640p-104, -0x1.08a0p-101, 0x1.7e60p-102, 0x1.22c0p-103, -0x1.7200p-106, 0x1.f0f0p-102, 0x1.eb4ep-99, 0x1.c6e0p-103, }; /* * exp2l(x): compute the base 2 exponential of x * * Accuracy: Peak error < 0.502 ulp. * * Method: (accurate tables) * * Reduce x: * x = 2**k + y, for integer k and |y| <= 1/2. * Thus we have exp2(x) = 2**k * exp2(y). * * Reduce y: * y = i/TBLSIZE + z - eps[i] for integer i near y * TBLSIZE. * Thus we have exp2(y) = exp2(i/TBLSIZE) * exp2(z - eps[i]), * with |z - eps[i]| <= 2**-8 + 2**-98 for the table used. * * We compute exp2(i/TBLSIZE) via table lookup and exp2(z - eps[i]) via * a degree-10 minimax polynomial with maximum error under 2**-120. * The values in exp2t[] and eps[] are chosen such that * exp2t[i] = exp2(i/TBLSIZE + eps[i]), and eps[i] is a small offset such * that exp2t[i] is accurate to 2**-122. * * Note that the range of i is +-TBLSIZE/2, so we actually index the tables * by i0 = i + TBLSIZE/2. * * This method is due to Gal, with many details due to Gal and Bachelis: * * Gal, S. and Bachelis, B. An Accurate Elementary Mathematical Library * for the IEEE Floating Point Standard. TOMS 17(1), 26-46 (1991). */ DLLEXPORT long double exp2l(long double x) { union IEEEl2bits u, v; long double r, t, twopk, twopkp10000, z; uint32_t hx, ix, i0; int k; u.e = x; /* Filter out exceptional cases. */ hx = u.xbits.expsign; ix = hx & EXPMASK; if (ix >= BIAS + 14) { /* |x| >= 16384 */ if (ix == BIAS + LDBL_MAX_EXP) { if (u.xbits.manh != 0 || u.xbits.manl != 0 || (hx & 0x8000) == 0) return (x + x); /* x is NaN or +Inf */ else return (0.0); /* x is -Inf */ } if (x >= 16384) return (huge * huge); /* overflow */ if (x <= -16495) return (twom10000 * twom10000); /* underflow */ } else if (ix <= BIAS - 115) { /* |x| < 0x1p-115 */ return (1.0 + x); } /* * Reduce x, computing z, i0, and k. The low bits of x + redux * contain the 16-bit integer part of the exponent (k) followed by * TBLBITS fractional bits (i0). We use bit tricks to extract these * as integers, then set z to the remainder. * * Example: Suppose x is 0xabc.123456p0 and TBLBITS is 8. * Then the low-order word of x + redux is 0x000abc12, * We split this into k = 0xabc and i0 = 0x12 (adjusted to * index into the table), then we compute z = 0x0.003456p0. * * XXX If the exponent is negative, the computation of k depends on * '>>' doing sign extension. */ u.e = x + redux; i0 = (u.bits.manl & 0xffffffff) + TBLSIZE / 2; k = (int)i0 >> TBLBITS; i0 = i0 & (TBLSIZE - 1); u.e -= redux; z = x - u.e; v.xbits.manh = 0; v.xbits.manl = 0; if (k >= LDBL_MIN_EXP) { v.xbits.expsign = LDBL_MAX_EXP - 1 + k; twopk = v.e; } else { v.xbits.expsign = LDBL_MAX_EXP - 1 + k + 10000; twopkp10000 = v.e; } /* Compute r = exp2(y) = exp2t[i0] * p(z - eps[i]). */ t = tbl[i0]; /* exp2t[i0] */ z -= eps[i0]; /* eps[i0] */ r = t + t * z * (P1 + z * (P2 + z * (P3 + z * (P4 + z * (P5 + z * (P6 + z * (P7 + z * (P8 + z * (P9 + z * P10))))))))); /* Scale by 2**k. */ if(k >= LDBL_MIN_EXP) { if (k == LDBL_MAX_EXP) return (r * 2.0 * 0x1p16383L); return (r * twopk); } else { return (r * twopkp10000 * twom10000); } } openlibm-0.5.0/ld128/s_expm1l.c000066400000000000000000000106421266752446200160700ustar00rootroot00000000000000/* $OpenBSD: s_expm1l.c,v 1.1 2011/07/06 00:02:42 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* expm1l.c * * Exponential function, minus 1 * 128-bit long double precision * * * * SYNOPSIS: * * long double x, y, expm1l(); * * y = expm1l( x ); * * * * DESCRIPTION: * * Returns e (2.71828...) raised to the x power, minus one. * * Range reduction is accomplished by separating the argument * into an integer k and fraction f such that * * x k f * e = 2 e. * * An expansion x + .5 x^2 + x^3 R(x) approximates exp(f) - 1 * in the basic range [-0.5 ln 2, 0.5 ln 2]. * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE -79,+MAXLOG 100,000 1.7e-34 4.5e-35 * */ #include #include #include "math_private.h" /* exp(x) - 1 = x + 0.5 x^2 + x^3 P(x)/Q(x) -.5 ln 2 < x < .5 ln 2 Theoretical peak relative error = 8.1e-36 */ static const long double P0 = 2.943520915569954073888921213330863757240E8L, P1 = -5.722847283900608941516165725053359168840E7L, P2 = 8.944630806357575461578107295909719817253E6L, P3 = -7.212432713558031519943281748462837065308E5L, P4 = 4.578962475841642634225390068461943438441E4L, P5 = -1.716772506388927649032068540558788106762E3L, P6 = 4.401308817383362136048032038528753151144E1L, P7 = -4.888737542888633647784737721812546636240E-1L, Q0 = 1.766112549341972444333352727998584753865E9L, Q1 = -7.848989743695296475743081255027098295771E8L, Q2 = 1.615869009634292424463780387327037251069E8L, Q3 = -2.019684072836541751428967854947019415698E7L, Q4 = 1.682912729190313538934190635536631941751E6L, Q5 = -9.615511549171441430850103489315371768998E4L, Q6 = 3.697714952261803935521187272204485251835E3L, Q7 = -8.802340681794263968892934703309274564037E1L, /* Q8 = 1.000000000000000000000000000000000000000E0 */ /* C1 + C2 = ln 2 */ C1 = 6.93145751953125E-1L, C2 = 1.428606820309417232121458176568075500134E-6L, /* ln (2^16384 * (1 - 2^-113)) */ maxlog = 1.1356523406294143949491931077970764891253E4L, /* ln 2^-114 */ minarg = -7.9018778583833765273564461846232128760607E1L, big = 1e4932L; long double expm1l(long double x) { long double px, qx, xx; int32_t ix, sign; ieee_quad_shape_type u; int k; /* Detect infinity and NaN. */ u.value = x; ix = u.parts32.mswhi; sign = ix & 0x80000000; ix &= 0x7fffffff; if (ix >= 0x7fff0000) { /* Infinity. */ if (((ix & 0xffff) | u.parts32.mswlo | u.parts32.lswhi | u.parts32.lswlo) == 0) { if (sign) return -1.0L; else return x; } /* NaN. No invalid exception. */ return x; } /* expm1(+- 0) = +- 0. */ if ((ix == 0) && (u.parts32.mswlo | u.parts32.lswhi | u.parts32.lswlo) == 0) return x; /* Overflow. */ if (x > maxlog) return (big * big); /* Minimum value. */ if (x < minarg) return (4.0/big - 1.0L); /* Express x = ln 2 (k + remainder), remainder not exceeding 1/2. */ xx = C1 + C2; /* ln 2. */ px = floorl (0.5 + x / xx); k = px; /* remainder times ln 2 */ x -= px * C1; x -= px * C2; /* Approximate exp(remainder ln 2). */ px = (((((((P7 * x + P6) * x + P5) * x + P4) * x + P3) * x + P2) * x + P1) * x + P0) * x; qx = (((((((x + Q7) * x + Q6) * x + Q5) * x + Q4) * x + Q3) * x + Q2) * x + Q1) * x + Q0; xx = x * x; qx = x + (0.5 * xx + xx * px / qx); /* exp(x) = exp(k ln 2) exp(remainder ln 2) = 2^k exp(remainder ln 2). We have qx = exp(remainder ln 2) - 1, so exp(x) - 1 = 2^k (qx + 1) - 1 = 2^k qx + 2^k - 1. */ px = ldexpl (1.0L, k); x = px * qx + (px - 1.0); return x; } openlibm-0.5.0/ld128/s_floorl.c000066400000000000000000000032211266752446200161520ustar00rootroot00000000000000/* @(#)s_floor.c 5.1 93/09/24 */ /* * ==================================================== * 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. * ==================================================== */ /* * floorl(x) * Return x rounded toward -inf to integral value * Method: * Bit twiddling. * Exception: * Inexact flag raised if x not equal to floor(x). */ #include #include "math_private.h" static const long double huge = 1.0e4930L; long double floorl(long double x) { int64_t i0,i1,jj0; u_int64_t i,j; GET_LDOUBLE_WORDS64(i0,i1,x); jj0 = ((i0>>48)&0x7fff)-0x3fff; if(jj0<48) { if(jj0<0) { /* raise inexact if x != 0 */ if(huge+x>0.0) { if(i0>=0) return 0.0L; else if(((i0&0x7fffffffffffffffLL)|i1)!=0) return -1.0L; } } else { i = (0x0000ffffffffffffULL)>>jj0; if(((i0&i)|i1)==0) return x; /* x is integral */ if(huge+x>0.0) { /* raise inexact flag */ if(i0<0) i0 += (0x0001000000000000LL)>>jj0; i0 &= (~i); i1=0; } } } else if (jj0>111) { if(jj0==0x4000) return x+x; /* inf or NaN */ else return x; /* x is integral */ } else { i = -1ULL>>(jj0-48); if((i1&i)==0) return x; /* x is integral */ if(huge+x>0.0) { /* raise inexact flag */ if(i0<0) { if(jj0==48) i0+=1; else { j = i1+(1LL<<(112-jj0)); if(j * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* log1pl.c * * Relative error logarithm * Natural logarithm of 1+x, 128-bit long double precision * * * * SYNOPSIS: * * long double x, y, log1pl(); * * y = log1pl( x ); * * * * DESCRIPTION: * * Returns the base e (2.718...) logarithm of 1+x. * * The argument 1+x is separated into its exponent and fractional * parts. If the exponent is between -1 and +1, the logarithm * of the fraction is approximated by * * log(1+x) = x - 0.5 x^2 + x^3 P(x)/Q(x). * * Otherwise, setting z = 2(w-1)/(w+1), * * log(w) = z + z^3 P(z)/Q(z). * * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE -1, 8 100000 1.9e-34 4.3e-35 */ #include #include "math_private.h" /* Coefficients for log(1+x) = x - x^2 / 2 + x^3 P(x)/Q(x) * 1/sqrt(2) <= 1+x < sqrt(2) * Theoretical peak relative error = 5.3e-37, * relative peak error spread = 2.3e-14 */ static const long double P12 = 1.538612243596254322971797716843006400388E-6L, P11 = 4.998469661968096229986658302195402690910E-1L, P10 = 2.321125933898420063925789532045674660756E1L, P9 = 4.114517881637811823002128927449878962058E2L, P8 = 3.824952356185897735160588078446136783779E3L, P7 = 2.128857716871515081352991964243375186031E4L, P6 = 7.594356839258970405033155585486712125861E4L, P5 = 1.797628303815655343403735250238293741397E5L, P4 = 2.854829159639697837788887080758954924001E5L, P3 = 3.007007295140399532324943111654767187848E5L, P2 = 2.014652742082537582487669938141683759923E5L, P1 = 7.771154681358524243729929227226708890930E4L, P0 = 1.313572404063446165910279910527789794488E4L, /* Q12 = 1.000000000000000000000000000000000000000E0L, */ Q11 = 4.839208193348159620282142911143429644326E1L, Q10 = 9.104928120962988414618126155557301584078E2L, Q9 = 9.147150349299596453976674231612674085381E3L, Q8 = 5.605842085972455027590989944010492125825E4L, Q7 = 2.248234257620569139969141618556349415120E5L, Q6 = 6.132189329546557743179177159925690841200E5L, Q5 = 1.158019977462989115839826904108208787040E6L, Q4 = 1.514882452993549494932585972882995548426E6L, Q3 = 1.347518538384329112529391120390701166528E6L, Q2 = 7.777690340007566932935753241556479363645E5L, Q1 = 2.626900195321832660448791748036714883242E5L, Q0 = 3.940717212190338497730839731583397586124E4L; /* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2), * where z = 2(x-1)/(x+1) * 1/sqrt(2) <= x < sqrt(2) * Theoretical peak relative error = 1.1e-35, * relative peak error spread 1.1e-9 */ static const long double R5 = -8.828896441624934385266096344596648080902E-1L, R4 = 8.057002716646055371965756206836056074715E1L, R3 = -2.024301798136027039250415126250455056397E3L, R2 = 2.048819892795278657810231591630928516206E4L, R1 = -8.977257995689735303686582344659576526998E4L, R0 = 1.418134209872192732479751274970992665513E5L, /* S6 = 1.000000000000000000000000000000000000000E0L, */ S5 = -1.186359407982897997337150403816839480438E2L, S4 = 3.998526750980007367835804959888064681098E3L, S3 = -5.748542087379434595104154610899551484314E4L, S2 = 4.001557694070773974936904547424676279307E5L, S1 = -1.332535117259762928288745111081235577029E6L, S0 = 1.701761051846631278975701529965589676574E6L; /* C1 + C2 = ln 2 */ static const long double C1 = 6.93145751953125E-1L; static const long double C2 = 1.428606820309417232121458176568075500134E-6L; static const long double sqrth = 0.7071067811865475244008443621048490392848L; /* ln (2^16384 * (1 - 2^-113)) */ static const long double zero = 0.0L; long double log1pl(long double xm1) { long double x, y, z, r, s; ieee_quad_shape_type u; int32_t hx; int e; /* Test for NaN or infinity input. */ u.value = xm1; hx = u.parts32.mswhi; if (hx >= 0x7fff0000) return xm1; /* log1p(+- 0) = +- 0. */ if (((hx & 0x7fffffff) == 0) && (u.parts32.mswlo | u.parts32.lswhi | u.parts32.lswlo) == 0) return xm1; x = xm1 + 1.0L; /* log1p(-1) = -inf */ if (x <= 0.0L) { if (x == 0.0L) return (-1.0L / (x - x)); else return (zero / (x - x)); } /* Separate mantissa from exponent. */ /* Use frexp used so that denormal numbers will be handled properly. */ x = frexpl (x, &e); /* Logarithm using log(x) = z + z^3 P(z^2)/Q(z^2), where z = 2(x-1)/x+1). */ if ((e > 2) || (e < -2)) { if (x < sqrth) { /* 2( 2x-1 )/( 2x+1 ) */ e -= 1; z = x - 0.5L; y = 0.5L * z + 0.5L; } else { /* 2 (x-1)/(x+1) */ z = x - 0.5L; z -= 0.5L; y = 0.5L * x + 0.5L; } x = z / y; z = x * x; r = ((((R5 * z + R4) * z + R3) * z + R2) * z + R1) * z + R0; s = (((((z + S5) * z + S4) * z + S3) * z + S2) * z + S1) * z + S0; z = x * (z * r / s); z = z + e * C2; z = z + x; z = z + e * C1; return (z); } /* Logarithm using log(1+x) = x - .5x^2 + x^3 P(x)/Q(x). */ if (x < sqrth) { e -= 1; if (e != 0) x = 2.0L * x - 1.0L; /* 2x - 1 */ else x = xm1; } else { if (e != 0) x = x - 1.0L; else x = xm1; } z = x * x; r = (((((((((((P12 * x + P11) * x + P10) * x + P9) * x + P8) * x + P7) * x + P6) * x + P5) * x + P4) * x + P3) * x + P2) * x + P1) * x + P0; s = (((((((((((x + Q11) * x + Q10) * x + Q9) * x + Q8) * x + Q7) * x + Q6) * x + Q5) * x + Q4) * x + Q3) * x + Q2) * x + Q1) * x + Q0; y = x * (z * r / s); y = y + e * C2; z = y - 0.5L * z; z = z + x; z = z + e * C1; return (z); } openlibm-0.5.0/ld128/s_modfl.c000066400000000000000000000035551266752446200157700ustar00rootroot00000000000000/* @(#)s_modf.c 5.1 93/09/24 */ /* * ==================================================== * 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. * ==================================================== */ /* * modfl(long double x, long double *iptr) * return fraction part of x, and return x's integral part in *iptr. * Method: * Bit twiddling. * * Exception: * No exception. */ #include #include "math_private.h" static const long double one = 1.0; long double modfl(long double x, long double *iptr) { int64_t i0,i1,jj0; u_int64_t i; GET_LDOUBLE_WORDS64(i0,i1,x); jj0 = ((i0>>48)&0x7fff)-0x3fff; /* exponent of x */ if(jj0<48) { /* integer part in high x */ if(jj0<0) { /* |x|<1 */ /* *iptr = +-0 */ SET_LDOUBLE_WORDS64(*iptr,i0&0x8000000000000000ULL,0); return x; } else { i = (0x0000ffffffffffffLL)>>jj0; if(((i0&i)|i1)==0) { /* x is integral */ *iptr = x; /* return +-0 */ SET_LDOUBLE_WORDS64(x,i0&0x8000000000000000ULL,0); return x; } else { SET_LDOUBLE_WORDS64(*iptr,i0&(~i),0); return x - *iptr; } } } else if (jj0>111) { /* no fraction part */ *iptr = x*one; /* We must handle NaNs separately. */ if (jj0 == 0x4000 && ((i0 & 0x0000ffffffffffffLL) | i1)) return x*one; /* return +-0 */ SET_LDOUBLE_WORDS64(x,i0&0x8000000000000000ULL,0); return x; } else { /* fraction part in low x */ i = -1ULL>>(jj0-48); if((i1&i)==0) { /* x is integral */ *iptr = x; /* return +-0 */ SET_LDOUBLE_WORDS64(x,i0&0x8000000000000000ULL,0); return x; } else { SET_LDOUBLE_WORDS64(*iptr,i0,i1&(~i)); return x - *iptr; } } } openlibm-0.5.0/ld128/s_nanl.c000066400000000000000000000033171266752446200156130ustar00rootroot00000000000000/*- * Copyright (c) 2007 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/lib/msun/ld128/s_nanl.c,v 1.3 2008/03/02 20:16:55 das Exp $ */ #include #include "fpmath.h" #include "math_private.h" DLLEXPORT long double nanl(const char *s) { union { union IEEEl2bits ieee; uint32_t bits[4]; } u; __scan_nan(u.bits, 4, s); u.ieee.bits.exp = 0x7fff; u.ieee.bits.manh |= 1ULL << 47; /* make it a quiet NaN */ return (u.ieee.e); } openlibm-0.5.0/ld128/s_nextafterl.c000066400000000000000000000036151266752446200170400ustar00rootroot00000000000000/* @(#)s_nextafter.c 5.1 93/09/24 */ /* * ==================================================== * 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. * ==================================================== */ /* IEEE functions * nextafterl(x,y) * return the next machine floating-point number of x in the * direction toward y. * Special cases: */ #include #include "math_private.h" long double nextafterl(long double x, long double y) { int64_t hx,hy,ix,iy; u_int64_t lx,ly; GET_LDOUBLE_WORDS64(hx,lx,x); GET_LDOUBLE_WORDS64(hy,ly,y); ix = hx&0x7fffffffffffffffLL; /* |x| */ iy = hy&0x7fffffffffffffffLL; /* |y| */ if(((ix>=0x7fff000000000000LL)&&((ix-0x7fff000000000000LL)|lx)!=0) || /* x is nan */ ((iy>=0x7fff000000000000LL)&&((iy-0x7fff000000000000LL)|ly)!=0)) /* y is nan */ return x+y; if(x==y) return y; /* x=y, return y */ if((ix|lx)==0) { /* x == 0 */ volatile long double u; SET_LDOUBLE_WORDS64(x,hy&0x8000000000000000ULL,1);/* return +-minsubnormal */ u = x; u = u * u; /* raise underflow flag */ return x; } if(hx>=0) { /* x > 0 */ if(hx>hy||((hx==hy)&&(lx>ly))) { /* x > y, x -= ulp */ if(lx==0) hx--; lx--; } else { /* x < y, x += ulp */ lx++; if(lx==0) hx++; } } else { /* x < 0 */ if(hy>=0||hx>hy||((hx==hy)&&(lx>ly))){/* x < y, x -= ulp */ if(lx==0) hx--; lx--; } else { /* x > y, x += ulp */ lx++; if(lx==0) hx++; } } hy = hx&0x7fff000000000000LL; if(hy==0x7fff000000000000LL) return x+x;/* overflow */ if(hy==0) { volatile long double u = x*x; /* underflow */ } SET_LDOUBLE_WORDS64(x,hx,lx); return x; } __strong_alias(nexttowardl, nextafterl); openlibm-0.5.0/ld128/s_nexttoward.c000066400000000000000000000044041266752446200170600ustar00rootroot00000000000000/* @(#)s_nextafter.c 5.1 93/09/24 */ /* * ==================================================== * 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. * ==================================================== */ /* IEEE functions * nexttoward(x,y) * return the next machine floating-point number of x in the * direction toward y. * Special cases: */ #include #include #include "math_private.h" double nexttoward(double x, long double y) { int32_t hx,ix; int64_t hy,iy; u_int32_t lx; u_int64_t ly; EXTRACT_WORDS(hx,lx,x); GET_LDOUBLE_WORDS64(hy,ly,y); ix = hx&0x7fffffff; /* |x| */ iy = hy&0x7fffffffffffffffLL; /* |y| */ if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) || /* x is nan */ ((iy>=0x7fff000000000000LL)&&((iy-0x7fff000000000000LL)|ly)!=0)) /* y is nan */ return x+y; if((long double) x==y) return y; /* x=y, return y */ if((ix|lx)==0) { /* x == 0 */ volatile double u; INSERT_WORDS(x,(u_int32_t)((hy>>32)&0x80000000),1);/* return +-minsub */ u = x; u = u * u; /* raise underflow flag */ return x; } if(hx>=0) { /* x > 0 */ if (hy<0||(ix>>20)>(iy>>48)-0x3c00 || ((ix>>20)==(iy>>48)-0x3c00 && (((((int64_t)hx)<<28)|(lx>>4))>(hy&0x0000ffffffffffffLL) || (((((int64_t)hx)<<28)|(lx>>4))==(hy&0x0000ffffffffffffLL) && (lx&0xf)>(ly>>60))))) { /* x > y, x -= ulp */ if(lx==0) hx -= 1; lx -= 1; } else { /* x < y, x += ulp */ lx += 1; if(lx==0) hx += 1; } } else { /* x < 0 */ if (hy>=0||(ix>>20)>(iy>>48)-0x3c00 || ((ix>>20)==(iy>>48)-0x3c00 && (((((int64_t)hx)<<28)|(lx>>4))>(hy&0x0000ffffffffffffLL) || (((((int64_t)hx)<<28)|(lx>>4))==(hy&0x0000ffffffffffffLL) && (lx&0xf)>(ly>>60))))) { /* x < y, x -= ulp */ if(lx==0) hx -= 1; lx -= 1; } else { /* x > y, x += ulp */ lx += 1; if(lx==0) hx += 1; } } hy = hx&0x7ff00000; if(hy>=0x7ff00000) { x = x+x; /* overflow */ return x; } if(hy<0x00100000) { volatile double u = x*x; /* underflow */ } INSERT_WORDS(x,hx,lx); return x; } openlibm-0.5.0/ld128/s_nexttowardf.c000066400000000000000000000033311266752446200172240ustar00rootroot00000000000000/* @(#)s_nextafter.c 5.1 93/09/24 */ /* * ==================================================== * 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 #include "math_private.h" float nexttowardf(float x, long double y) { int32_t hx,ix; int64_t hy,iy; u_int64_t ly; GET_FLOAT_WORD(hx,x); GET_LDOUBLE_WORDS64(hy,ly,y); ix = hx&0x7fffffff; /* |x| */ iy = hy&0x7fffffffffffffffLL; /* |y| */ if((ix>0x7f800000) || /* x is nan */ ((iy>=0x7fff000000000000LL)&&((iy-0x7fff000000000000LL)|ly)!=0)) /* y is nan */ return x+y; if((long double) x==y) return y; /* x=y, return y */ if(ix==0) { /* x == 0 */ volatile float u; SET_FLOAT_WORD(x,(u_int32_t)((hy>>32)&0x80000000)|1);/* return +-minsub*/ u = x; u = u * u; /* raise underflow flag */ return x; } if(hx>=0) { /* x > 0 */ if(hy<0||(ix>>23)>(iy>>48)-0x3f80 || ((ix>>23)==(iy>>48)-0x3f80 && (ix&0x7fffff)>((hy>>25)&0x7fffff))) {/* x > y, x -= ulp */ hx -= 1; } else { /* x < y, x += ulp */ hx += 1; } } else { /* x < 0 */ if(hy>=0||(ix>>23)>(iy>>48)-0x3f80 || ((ix>>23)==(iy>>48)-0x3f80 && (ix&0x7fffff)>((hy>>25)&0x7fffff))) {/* x < y, x -= ulp */ hx -= 1; } else { /* x > y, x += ulp */ hx += 1; } } hy = hx&0x7f800000; if(hy>=0x7f800000) return x+x; /* overflow */ if(hy<0x00800000) { volatile float u = x*x; /* underflow */ } SET_FLOAT_WORD(x,hx); return x; } openlibm-0.5.0/ld128/s_remquol.c000066400000000000000000000110161266752446200163420ustar00rootroot00000000000000/* @(#)e_fmod.c 1.3 95/01/18 */ /*- * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include #include #include #include #include #include "math_private.h" #define BIAS (LDBL_MAX_EXP - 1) /* * These macros add and remove an explicit integer bit in front of the * fractional mantissa, if the architecture doesn't have such a bit by * default already. */ #ifdef LDBL_IMPLICIT_NBIT #define LDBL_NBIT 0 #define SET_NBIT(hx) ((hx) | (1ULL << LDBL_MANH_SIZE)) #define HFRAC_BITS (EXT_FRACHBITS + EXT_FRACHMBITS) #else #define LDBL_NBIT 0x80000000 #define SET_NBIT(hx) (hx) #define HFRAC_BITS (EXT_FRACHBITS + EXT_FRACHMBITS - 1) #endif #define MANL_SHIFT (EXT_FRACLMBITS + EXT_FRACLBITS - 1) static const long double Zero[] = {0.0L, -0.0L}; /* * Return the IEEE remainder and set *quo to the last n bits of the * quotient, rounded to the nearest integer. We choose n=31 because * we wind up computing all the integer bits of the quotient anyway as * a side-effect of computing the remainder by the shift and subtract * method. In practice, this is far more bits than are needed to use * remquo in reduction algorithms. * * Assumptions: * - The low part of the mantissa fits in a manl_t exactly. * - The high part of the mantissa fits in an int64_t with enough room * for an explicit integer bit in front of the fractional bits. */ long double remquol(long double x, long double y, int *quo) { int64_t hx,hz,hy,_hx; uint64_t lx,ly,lz; uint64_t sx,sxy; int ix,iy,n,q; GET_LDOUBLE_WORDS64(hx,lx,x); GET_LDOUBLE_WORDS64(hy,ly,y); sx = (hx>>48)&0x8000; sxy = sx ^ ((hy>>48)&0x8000); hx &= 0x7fffffffffffffffLL; /* |x| */ hy &= 0x7fffffffffffffffLL; /* |y| */ SET_LDOUBLE_WORDS64(x,hx,lx); SET_LDOUBLE_WORDS64(y,hy,ly); /* purge off exception values */ if((hy|ly)==0 || /* y=0 */ ((hx>>48) == BIAS + LDBL_MAX_EXP) || /* or x not finite */ ((hy>>48) == BIAS + LDBL_MAX_EXP && (((hy&0x0000ffffffffffffLL)&~LDBL_NBIT)|ly)!=0)) /* or y is NaN */ return (x*y)/(x*y); if((hx>>48)<=(hy>>48)) { if(((hx>>48)<(hy>>48)) || ((hx&0x0000ffffffffffffLL)<=(hy&0x0000ffffffffffffLL) && ((hx&0x0000ffffffffffffLL)<(hy&0x0000ffffffffffffLL) || lx>48) == 0) { /* subnormal x */ x *= 0x1.0p512; GET_LDOUBLE_WORDS64(hx,lx,x); ix = (hx>>48) - (BIAS + 512); } else { ix = (hx>>48) - BIAS; } /* determine iy = ilogb(y) */ if((hy>>48) == 0) { /* subnormal y */ y *= 0x1.0p512; GET_LDOUBLE_WORDS64(hy,ly,y); iy = (hy>>48) - (BIAS + 512); } else { iy = (hy>>48) - BIAS; } /* set up {hx,lx}, {hy,ly} and align y to x */ _hx = SET_NBIT(hx) & 0x0000ffffffffffffLL; hy = SET_NBIT(hy); /* fix point fmod */ n = ix - iy; q = 0; while(n--) { hz=_hx-hy;lz=lx-ly; if(lx>MANL_SHIFT); lx = lx+lx;} else {_hx = hz+hz+(lz>>MANL_SHIFT); lx = lz+lz; q++;} q <<= 1; } hz=_hx-hy;lz=lx-ly; if(lx=0) {_hx=hz;lx=lz;q++;} /* convert back to floating value and restore the sign */ if((_hx|lx)==0) { /* return sign(x)*0 */ *quo = (sxy ? -q : q); return Zero[sx!=0]; } while(_hx<(1ULL<>MANL_SHIFT); lx = lx+lx; iy -= 1; } hx = (hx&0xffff000000000000LL) | (_hx&0x0000ffffffffffffLL); if (iy < LDBL_MIN_EXP) { hx = (hx&0x0000ffffffffffffLL) | (uint64_t)(iy + BIAS + 512)<<48; SET_LDOUBLE_WORDS64(x,hx,lx); x *= 0x1p-512; GET_LDOUBLE_WORDS64(hx,lx,x); } else { hx = (hx&0x0000ffffffffffffLL) | (uint64_t)(iy + BIAS)<<48; } hx &= 0x7fffffffffffffffLL; SET_LDOUBLE_WORDS64(x,hx,lx); fixup: y = fabsl(y); if (y < LDBL_MIN * 2) { if (x+x>y || (x+x==y && (q & 1))) { q++; x-=y; } } else if (x>0.5*y || (x==0.5*y && (q & 1))) { q++; x-=y; } GET_LDOUBLE_MSW64(hx,x); hx ^= sx; SET_LDOUBLE_MSW64(x,hx); q &= 0x7fffffff; *quo = (sxy ? -q : q); return x; } openlibm-0.5.0/ld128/s_tanhl.c000066400000000000000000000063511266752446200157720ustar00rootroot00000000000000/* @(#)s_tanh.c 5.1 93/09/24 */ /* * ==================================================== * 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. * ==================================================== */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* tanhl(x) * Return the Hyperbolic Tangent of x * * Method : * x -x * e - e * 0. tanhl(x) is defined to be ----------- * x -x * e + e * 1. reduce x to non-negative by tanhl(-x) = -tanhl(x). * 2. 0 <= x <= 2**-57 : tanhl(x) := x*(one+x) * -t * 2**-57 < x <= 1 : tanhl(x) := -----; t = expm1l(-2x) * t + 2 * 2 * 1 <= x <= 40.0 : tanhl(x) := 1- ----- ; t=expm1l(2x) * t + 2 * 40.0 < x <= INF : tanhl(x) := 1. * * Special cases: * tanhl(NaN) is NaN; * only tanhl(0)=0 is exact for finite argument. */ #include #include "math_private.h" static const long double one = 1.0, two = 2.0, tiny = 1.0e-4900L; long double tanhl(long double x) { long double t, z; u_int32_t jx, ix; ieee_quad_shape_type u; /* Words of |x|. */ u.value = x; jx = u.parts32.mswhi; ix = jx & 0x7fffffff; /* x is INF or NaN */ if (ix >= 0x7fff0000) { /* for NaN it's not important which branch: tanhl(NaN) = NaN */ if (jx & 0x80000000) return one / x - one; /* tanhl(-inf)= -1; */ else return one / x + one; /* tanhl(+inf)=+1 */ } /* |x| < 40 */ if (ix < 0x40044000) { if (u.value == 0) return x; /* x == +- 0 */ if (ix < 0x3fc60000) /* |x| < 2^-57 */ return x * (one + tiny); /* tanh(small) = small */ u.parts32.mswhi = ix; /* Absolute value of x. */ if (ix >= 0x3fff0000) { /* |x| >= 1 */ t = expm1l (two * u.value); z = one - two / (t + two); } else { t = expm1l (-two * u.value); z = -t / (t + two); } /* |x| > 40, return +-1 */ } else { z = one - tiny; /* raised inexact flag */ } return (jx & 0x80000000) ? -z : z; } openlibm-0.5.0/ld128/s_truncl.c000066400000000000000000000032751266752446200161750ustar00rootroot00000000000000/* * ==================================================== * 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. * ==================================================== * * From: @(#)s_floor.c 5.1 93/09/24 */ /* * truncl(x) * Return x rounded toward 0 to integral value * Method: * Bit twiddling. * Exception: * Inexact flag raised if x not equal to truncl(x). */ #include #include #include #include #include #include "math_private.h" #ifdef LDBL_IMPLICIT_NBIT #define MANH_SIZE (EXT_FRACHBITS + EXT_FRACHMBITS + 1) #else #define MANH_SIZE (EXT_FRACHBITS + EXT_FRACHMBITS) #endif static const long double huge = 1.0e300; static const float zero[] = { 0.0, -0.0 }; long double truncl(long double x) { int e; int64_t ix0, ix1; GET_LDOUBLE_WORDS64(ix0,ix1,x); e = ((ix0>>48)&0x7fff) - LDBL_MAX_EXP + 1; if (e < MANH_SIZE - 1) { if (e < 0) { /* raise inexact if x != 0 */ if (huge + x > 0.0) return (zero[((ix0>>48)&0x8000)!=0]); } else { uint64_t m = ((1llu << MANH_SIZE) - 1) >> (e + 1); if (((ix0 & m) | ix1) == 0) return (x); /* x is integral */ if (huge + x > 0.0) { /* raise inexact flag */ ix0 &= ~m; ix1 = 0; } } } else if (e < LDBL_MANT_DIG - 1) { uint64_t m = (uint64_t)-1 >> (64 - LDBL_MANT_DIG + e + 1); if ((ix1 & m) == 0) return (x); /* x is integral */ if (huge + x > 0.0) /* raise inexact flag */ ix1 &= ~m; } SET_LDOUBLE_WORDS64(x,ix0,ix1); return (x); } openlibm-0.5.0/ld80/000077500000000000000000000000001266752446200141065ustar00rootroot00000000000000openlibm-0.5.0/ld80/Make.files000066400000000000000000000010611266752446200160050ustar00rootroot00000000000000$(CUR_SRCS) += invtrig.c \ e_acoshl.c e_powl.c k_tanl.c s_exp2l.c \ e_atanhl.c e_lgammal_r.c e_sinhl.c s_asinhl.c s_expm1l.c \ e_coshl.c e_log10l.c e_tgammal.c \ e_expl.c e_log2l.c k_cosl.c s_log1pl.c s_tanhl.c \ e_logl.c k_sinl.c s_erfl.c # s_remquol.c e_fmodl.c s_truncl.c # e_hypotl.c s_floorl.c s_nextafterl.c s_ceill.c s_modfl.c ifneq ($(OS), WINNT) $(CUR_SRCS) += s_nanl.c endif openlibm-0.5.0/ld80/e_acoshl.c000066400000000000000000000030061266752446200160260ustar00rootroot00000000000000/* @(#)e_acosh.c 5.1 93/09/24 */ /* * ==================================================== * 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. * ==================================================== */ /* acoshl(x) * Method : * Based on * acoshl(x) = logl [ x + sqrtl(x*x-1) ] * we have * acoshl(x) := logl(x)+ln2, if x is large; else * acoshl(x) := logl(2x-1/(sqrtl(x*x-1)+x)) if x>2; else * acoshl(x) := log1pl(t+sqrtl(2.0*t+t*t)); where t=x-1. * * Special cases: * acoshl(x) is NaN with signal if x<1. * acoshl(NaN) is NaN without signal. */ #include #include "math_private.h" static const long double one = 1.0, ln2 = 6.931471805599453094287e-01L; /* 0x3FFE, 0xB17217F7, 0xD1CF79AC */ long double acoshl(long double x) { long double t; u_int32_t se,i0,i1; GET_LDOUBLE_WORDS(se,i0,i1,x); if(se<0x3fff || se & 0x8000) { /* x < 1 */ return (x-x)/(x-x); } else if(se >=0x401d) { /* x > 2**30 */ if(se >=0x7fff) { /* x is inf of NaN */ return x+x; } else return logl(x)+ln2; /* acoshl(huge)=logl(2x) */ } else if(((se-0x3fff)|i0|i1)==0) { return 0.0; /* acosh(1) = 0 */ } else if (se > 0x4000) { /* 2**28 > x > 2 */ t=x*x; return logl(2.0*x-one/(x+sqrtl(t-one))); } else { /* 1=0.5 * 1 2x x * atanhl(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------) * 2 1 - x 1 - x * * For x<0.5 * atanhl(x) = 0.5*log1pl(2x+2x*x/(1-x)) * * Special cases: * atanhl(x) is NaN if |x| > 1 with signal; * atanhl(NaN) is that NaN with no signal; * atanhl(+-1) is +-INF with signal. * */ #include #include "math_private.h" static const long double one = 1.0, huge = 1e4900L; static const long double zero = 0.0; long double atanhl(long double x) { long double t; int32_t ix; u_int32_t se,i0,i1; GET_LDOUBLE_WORDS(se,i0,i1,x); ix = se&0x7fff; if ((ix+((((i0&0x7fffffff)|i1)|(-((i0&0x7fffffff)|i1)))>>31))>0x3fff) /* |x|>1 */ return (x-x)/(x-x); if(ix==0x3fff) return x/zero; if(ix<0x3fe3&&(huge+x)>zero) return x; /* x<2**-28 */ SET_LDOUBLE_EXP(x,ix); if(ix<0x3ffe) { /* x < 0.5 */ t = x+x; t = 0.5*log1pl(t+t*x/(one-x)); } else t = 0.5*log1pl((x+x)/(one-x)); if(se<=0x7fff) return t; else return -t; } openlibm-0.5.0/ld80/e_coshl.c000066400000000000000000000044761266752446200157010ustar00rootroot00000000000000/* @(#)e_cosh.c 5.1 93/09/24 */ /* * ==================================================== * 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. * ==================================================== */ /* coshl(x) * Method : * mathematically coshl(x) if defined to be (exp(x)+exp(-x))/2 * 1. Replace x by |x| (coshl(x) = coshl(-x)). * 2. * [ exp(x) - 1 ]^2 * 0 <= x <= ln2/2 : coshl(x) := 1 + ------------------- * 2*exp(x) * * exp(x) + 1/exp(x) * ln2/2 <= x <= 22 : coshl(x) := ------------------- * 2 * 22 <= x <= lnovft : coshl(x) := expl(x)/2 * lnovft <= x <= ln2ovft: coshl(x) := expl(x/2)/2 * expl(x/2) * ln2ovft < x : coshl(x) := huge*huge (overflow) * * Special cases: * coshl(x) is |x| if x is +INF, -INF, or NaN. * only coshl(0)=1 is exact for finite x. */ #include #include "math_private.h" static const long double one = 1.0, half=0.5, huge = 1.0e4900L; long double coshl(long double x) { long double t,w; int32_t ex; u_int32_t mx,lx; /* High word of |x|. */ GET_LDOUBLE_WORDS(ex,mx,lx,x); ex &= 0x7fff; /* x is INF or NaN */ if(ex==0x7fff) return x*x; /* |x| in [0,0.5*ln2], return 1+expm1l(|x|)^2/(2*expl(|x|)) */ if(ex < 0x3ffd || (ex == 0x3ffd && mx < 0xb17217f7u)) { t = expm1l(fabsl(x)); w = one+t; if (ex<0x3fbc) return w; /* cosh(tiny) = 1 */ return one+(t*t)/(w+w); } /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */ if (ex < 0x4003 || (ex == 0x4003 && mx < 0xb0000000u)) { t = expl(fabsl(x)); return half*t+half/t; } /* |x| in [22, ln(maxdouble)] return half*exp(|x|) */ if (ex < 0x400c || (ex == 0x400c && mx < 0xb1700000u)) return half*expl(fabsl(x)); /* |x| in [log(maxdouble), log(2*maxdouble)) */ if (ex == 0x400c && (mx < 0xb174ddc0u || (mx == 0xb174ddc0u && lx < 0x31aec0ebu))) { w = expl(half*fabsl(x)); t = half*w; return t*w; } /* |x| >= log(2*maxdouble), cosh(x) overflow */ return huge*huge; } openlibm-0.5.0/ld80/e_expl.c000066400000000000000000000067031266752446200155340ustar00rootroot00000000000000/* $OpenBSD: e_expl.c,v 1.3 2013/11/12 20:35:19 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* expl.c * * Exponential function, long double precision * * * * SYNOPSIS: * * long double x, y, expl(); * * y = expl( x ); * * * * DESCRIPTION: * * Returns e (2.71828...) raised to the x power. * * Range reduction is accomplished by separating the argument * into an integer k and fraction f such that * * x k f * e = 2 e. * * A Pade' form of degree 2/3 is used to approximate exp(f) - 1 * in the basic range [-0.5 ln 2, 0.5 ln 2]. * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE +-10000 50000 1.12e-19 2.81e-20 * * * Error amplification in the exponential function can be * a serious matter. The error propagation involves * exp( X(1+delta) ) = exp(X) ( 1 + X*delta + ... ), * which shows that a 1 lsb error in representing X produces * a relative error of X times 1 lsb in the function. * While the routine gives an accurate result for arguments * that are exactly represented by a long double precision * computer number, the result contains amplified roundoff * error for large arguments not exactly represented. * * * ERROR MESSAGES: * * message condition value returned * exp underflow x < MINLOG 0.0 * exp overflow x > MAXLOG MAXNUM * */ /* Exponential function */ #include #include "math_private.h" static long double P[3] = { 1.2617719307481059087798E-4L, 3.0299440770744196129956E-2L, 9.9999999999999999991025E-1L, }; static long double Q[4] = { 3.0019850513866445504159E-6L, 2.5244834034968410419224E-3L, 2.2726554820815502876593E-1L, 2.0000000000000000000897E0L, }; static const long double C1 = 6.9314575195312500000000E-1L; static const long double C2 = 1.4286068203094172321215E-6L; static const long double MAXLOGL = 1.1356523406294143949492E4L; static const long double MINLOGL = -1.13994985314888605586758E4L; static const long double LOG2EL = 1.4426950408889634073599E0L; long double expl(long double x) { long double px, xx; int n; if( isnan(x) ) return(x); if( x > MAXLOGL) return( INFINITY ); if( x < MINLOGL ) return(0.0L); /* Express e**x = e**g 2**n * = e**g e**( n loge(2) ) * = e**( g + n loge(2) ) */ px = floorl( LOG2EL * x + 0.5L ); /* floor() truncates toward -infinity. */ n = px; x -= px * C1; x -= px * C2; /* rational approximation for exponential * of the fractional part: * e**x = 1 + 2x P(x**2)/( Q(x**2) - P(x**2) ) */ xx = x * x; px = x * __polevll( xx, P, 2 ); x = px/( __polevll( xx, Q, 3 ) - px ); x = 1.0L + ldexpl( x, 1 ); x = ldexpl( x, n ); return(x); } openlibm-0.5.0/ld80/e_fmodl.c000066400000000000000000000074771266752446200156760ustar00rootroot00000000000000/* @(#)e_fmod.c 1.3 95/01/18 */ /*- * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include //#include #include #include #include #include "math_private.h" #define BIAS (LDBL_MAX_EXP - 1) /* * These macros add and remove an explicit integer bit in front of the * fractional mantissa, if the architecture doesn't have such a bit by * default already. */ #ifdef LDBL_IMPLICIT_NBIT #define LDBL_NBIT 0 #define SET_NBIT(hx) ((hx) | (1ULL << LDBL_MANH_SIZE)) #define HFRAC_BITS EXT_FRACHBITS #else #define LDBL_NBIT 0x80000000 #define SET_NBIT(hx) (hx) #define HFRAC_BITS (EXT_FRACHBITS - 1) #endif #define MANL_SHIFT (EXT_FRACLBITS - 1) static const long double one = 1.0, Zero[] = {0.0, -0.0,}; /* * fmodl(x,y) * Return x mod y in exact arithmetic * Method: shift and subtract * * Assumptions: * - The low part of the mantissa fits in a manl_t exactly. * - The high part of the mantissa fits in an int64_t with enough room * for an explicit integer bit in front of the fractional bits. */ long double fmodl(long double x, long double y) { union { long double e; struct ieee_ext bits; } ux, uy; int64_t hx,hz; /* We need a carry bit even if LDBL_MANH_SIZE is 32. */ uint32_t hy; uint32_t lx,ly,lz; int ix,iy,n,sx; ux.e = x; uy.e = y; sx = ux.bits.ext_sign; /* purge off exception values */ if((uy.bits.ext_exp|uy.bits.ext_frach|uy.bits.ext_fracl)==0 || /* y=0 */ (ux.bits.ext_exp == BIAS + LDBL_MAX_EXP) || /* or x not finite */ (uy.bits.ext_exp == BIAS + LDBL_MAX_EXP && ((uy.bits.ext_frach&~LDBL_NBIT)|uy.bits.ext_fracl)!=0)) /* or y is NaN */ return (x*y)/(x*y); if(ux.bits.ext_exp<=uy.bits.ext_exp) { if((ux.bits.ext_exp>MANL_SHIFT); lx = lx+lx;} else { if ((hz|lz)==0) /* return sign(x)*0 */ return Zero[sx]; hx = hz+hz+(lz>>MANL_SHIFT); lx = lz+lz; } } hz=hx-hy;lz=lx-ly; if(lx=0) {hx=hz;lx=lz;} /* convert back to floating value and restore the sign */ if((hx|lx)==0) /* return sign(x)*0 */ return Zero[sx]; while(hx<(1ULL<>MANL_SHIFT); lx = lx+lx; iy -= 1; } ux.bits.ext_frach = hx; /* The mantissa is truncated here if needed. */ ux.bits.ext_fracl = lx; if (iy < LDBL_MIN_EXP) { ux.bits.ext_exp = iy + (BIAS + 512); ux.e *= 0x1p-512; } else { ux.bits.ext_exp = iy + BIAS; } x = ux.e * one; /* create necessary signal */ return x; /* exact output */ } openlibm-0.5.0/ld80/e_hypotl.c000066400000000000000000000064001266752446200160750ustar00rootroot00000000000000/* @(#)e_hypot.c 5.1 93/09/24 */ /* * ==================================================== * 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. * ==================================================== */ /* hypotl(x,y) * * Method : * If (assume round-to-nearest) z=x*x+y*y * has error less than sqrt(2)/2 ulp, than * sqrt(z) has error less than 1 ulp (exercise). * * So, compute sqrt(x*x+y*y) with some care as * follows to get the error below 1 ulp: * * Assume x>y>0; * (if possible, set rounding to round-to-nearest) * 1. if x > 2y use * x1*x1+(y*y+(x2*(x+x1))) for x*x+y*y * where x1 = x with lower 32 bits cleared, x2 = x-x1; else * 2. if x <= 2y use * t1*yy1+((x-y)*(x-y)+(t1*y2+t2*y)) * where t1 = 2x with lower 32 bits cleared, t2 = 2x-t1, * yy1= y with lower 32 bits chopped, y2 = y-yy1. * * NOTE: scaling may be necessary if some argument is too * large or too tiny * * Special cases: * hypot(x,y) is INF if x or y is +INF or -INF; else * hypot(x,y) is NAN if x or y is NAN. * * Accuracy: * hypot(x,y) returns sqrt(x^2+y^2) with error less * than 1 ulps (units in the last place) */ #include #include "math_private.h" long double hypotl(long double x, long double y) { long double a,b,t1,t2,yy1,y2,w; u_int32_t j,k,ea,eb; GET_LDOUBLE_EXP(ea,x); ea &= 0x7fff; GET_LDOUBLE_EXP(eb,y); eb &= 0x7fff; if(eb > ea) {a=y;b=x;j=ea; ea=eb;eb=j;} else {a=x;b=y;} SET_LDOUBLE_EXP(a,ea); /* a <- |a| */ SET_LDOUBLE_EXP(b,eb); /* b <- |b| */ if((ea-eb)>0x46) {return a+b;} /* x/y > 2**70 */ k=0; if(ea > 0x5f3f) { /* a>2**8000 */ if(ea == 0x7fff) { /* Inf or NaN */ u_int32_t es,high,low; w = a+b; /* for sNaN */ GET_LDOUBLE_WORDS(es,high,low,a); if(((high&0x7fffffff)|low)==0) w = a; GET_LDOUBLE_WORDS(es,high,low,b); if(((eb^0x7fff)|(high&0x7fffffff)|low)==0) w = b; return w; } /* scale a and b by 2**-9600 */ ea -= 0x2580; eb -= 0x2580; k += 9600; SET_LDOUBLE_EXP(a,ea); SET_LDOUBLE_EXP(b,eb); } if(eb < 0x20bf) { /* b < 2**-8000 */ if(eb == 0) { /* subnormal b or 0 */ u_int32_t es,high,low; GET_LDOUBLE_WORDS(es,high,low,b); if((high|low)==0) return a; SET_LDOUBLE_WORDS(t1, 0x7ffd, 0, 0); /* t1=2^16382 */ b *= t1; a *= t1; k -= 16382; } else { /* scale a and b by 2^9600 */ ea += 0x2580; /* a *= 2^9600 */ eb += 0x2580; /* b *= 2^9600 */ k -= 9600; SET_LDOUBLE_EXP(a,ea); SET_LDOUBLE_EXP(b,eb); } } /* medium size a and b */ w = a-b; if (w>b) { u_int32_t high; GET_LDOUBLE_MSW(high,a); SET_LDOUBLE_WORDS(t1,ea,high,0); t2 = a-t1; w = sqrtl(t1*t1-(b*(-b)-t2*(a+t1))); } else { u_int32_t high; GET_LDOUBLE_MSW(high,b); a = a+a; SET_LDOUBLE_WORDS(yy1,eb,high,0); y2 = b - yy1; GET_LDOUBLE_MSW(high,a); SET_LDOUBLE_WORDS(t1,ea+1,high,0); t2 = a - t1; w = sqrtl(t1*yy1-(w*(-w)-(t1*y2+t2*b))); } if(k!=0) { u_int32_t es; t1 = 1.0; GET_LDOUBLE_EXP(es,t1); SET_LDOUBLE_EXP(t1,es+k); return t1*w; } else return w; } openlibm-0.5.0/ld80/e_lgammal_r.c000066400000000000000000000303251266752446200165140ustar00rootroot00000000000000/* * ==================================================== * 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. * ==================================================== */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* lgammal_r(x, signgamp) * Reentrant version of the logarithm of the Gamma function * with user provide pointer for the sign of Gamma(x). * * Method: * 1. Argument Reduction for 0 < x <= 8 * Since gamma(1+s)=s*gamma(s), for x in [0,8], we may * reduce x to a number in [1.5,2.5] by * lgamma(1+s) = log(s) + lgamma(s) * for example, * lgamma(7.3) = log(6.3) + lgamma(6.3) * = log(6.3*5.3) + lgamma(5.3) * = log(6.3*5.3*4.3*3.3*2.3) + lgamma(2.3) * 2. Polynomial approximation of lgamma around its * minimun ymin=1.461632144968362245 to maintain monotonicity. * On [ymin-0.23, ymin+0.27] (i.e., [1.23164,1.73163]), use * Let z = x-ymin; * lgamma(x) = -1.214862905358496078218 + z^2*poly(z) * 2. Rational approximation in the primary interval [2,3] * We use the following approximation: * s = x-2.0; * lgamma(x) = 0.5*s + s*P(s)/Q(s) * Our algorithms are based on the following observation * * zeta(2)-1 2 zeta(3)-1 3 * lgamma(2+s) = s*(1-Euler) + --------- * s - --------- * s + ... * 2 3 * * where Euler = 0.5771... is the Euler constant, which is very * close to 0.5. * * 3. For x>=8, we have * lgamma(x)~(x-0.5)log(x)-x+0.5*log(2pi)+1/(12x)-1/(360x**3)+.... * (better formula: * lgamma(x)~(x-0.5)*(log(x)-1)-.5*(log(2pi)-1) + ...) * Let z = 1/x, then we approximation * f(z) = lgamma(x) - (x-0.5)(log(x)-1) * by * 3 5 11 * w = w0 + w1*z + w2*z + w3*z + ... + w6*z * * 4. For negative x, since (G is gamma function) * -x*G(-x)*G(x) = pi/sin(pi*x), * we have * G(x) = pi/(sin(pi*x)*(-x)*G(-x)) * since G(-x) is positive, sign(G(x)) = sign(sin(pi*x)) for x<0 * Hence, for x<0, signgam = sign(sin(pi*x)) and * lgamma(x) = log(|Gamma(x)|) * = log(pi/(|x*sin(pi*x)|)) - lgamma(-x); * Note: one should avoid compute pi*(-x) directly in the * computation of sin(pi*(-x)). * * 5. Special Cases * lgamma(2+s) ~ s*(1-Euler) for tiny s * lgamma(1)=lgamma(2)=0 * lgamma(x) ~ -log(x) for tiny x * lgamma(0) = lgamma(inf) = inf * lgamma(-integer) = +-inf * */ #include #include "math_private.h" static const long double half = 0.5L, one = 1.0L, pi = 3.14159265358979323846264L, two63 = 9.223372036854775808e18L, /* lgam(1+x) = 0.5 x + x a(x)/b(x) -0.268402099609375 <= x <= 0 peak relative error 6.6e-22 */ a0 = -6.343246574721079391729402781192128239938E2L, a1 = 1.856560238672465796768677717168371401378E3L, a2 = 2.404733102163746263689288466865843408429E3L, a3 = 8.804188795790383497379532868917517596322E2L, a4 = 1.135361354097447729740103745999661157426E2L, a5 = 3.766956539107615557608581581190400021285E0L, b0 = 8.214973713960928795704317259806842490498E3L, b1 = 1.026343508841367384879065363925870888012E4L, b2 = 4.553337477045763320522762343132210919277E3L, b3 = 8.506975785032585797446253359230031874803E2L, b4 = 6.042447899703295436820744186992189445813E1L, /* b5 = 1.000000000000000000000000000000000000000E0 */ tc = 1.4616321449683623412626595423257213284682E0L, tf = -1.2148629053584961146050602565082954242826E-1,/* double precision */ /* tt = (tail of tf), i.e. tf + tt has extended precision. */ tt = 3.3649914684731379602768989080467587736363E-18L, /* lgam ( 1.4616321449683623412626595423257213284682E0 ) = -1.2148629053584960809551455717769158215135617312999903886372437313313530E-1 */ /* lgam (x + tc) = tf + tt + x g(x)/h(x) - 0.230003726999612341262659542325721328468 <= x <= 0.2699962730003876587373404576742786715318 peak relative error 2.1e-21 */ g0 = 3.645529916721223331888305293534095553827E-18L, g1 = 5.126654642791082497002594216163574795690E3L, g2 = 8.828603575854624811911631336122070070327E3L, g3 = 5.464186426932117031234820886525701595203E3L, g4 = 1.455427403530884193180776558102868592293E3L, g5 = 1.541735456969245924860307497029155838446E2L, g6 = 4.335498275274822298341872707453445815118E0L, h0 = 1.059584930106085509696730443974495979641E4L, h1 = 2.147921653490043010629481226937850618860E4L, h2 = 1.643014770044524804175197151958100656728E4L, h3 = 5.869021995186925517228323497501767586078E3L, h4 = 9.764244777714344488787381271643502742293E2L, h5 = 6.442485441570592541741092969581997002349E1L, /* h6 = 1.000000000000000000000000000000000000000E0 */ /* lgam (x+1) = -0.5 x + x u(x)/v(x) -0.100006103515625 <= x <= 0.231639862060546875 peak relative error 1.3e-21 */ u0 = -8.886217500092090678492242071879342025627E1L, u1 = 6.840109978129177639438792958320783599310E2L, u2 = 2.042626104514127267855588786511809932433E3L, u3 = 1.911723903442667422201651063009856064275E3L, u4 = 7.447065275665887457628865263491667767695E2L, u5 = 1.132256494121790736268471016493103952637E2L, u6 = 4.484398885516614191003094714505960972894E0L, v0 = 1.150830924194461522996462401210374632929E3L, v1 = 3.399692260848747447377972081399737098610E3L, v2 = 3.786631705644460255229513563657226008015E3L, v3 = 1.966450123004478374557778781564114347876E3L, v4 = 4.741359068914069299837355438370682773122E2L, v5 = 4.508989649747184050907206782117647852364E1L, /* v6 = 1.000000000000000000000000000000000000000E0 */ /* lgam (x+2) = .5 x + x s(x)/r(x) 0 <= x <= 1 peak relative error 7.2e-22 */ s0 = 1.454726263410661942989109455292824853344E6L, s1 = -3.901428390086348447890408306153378922752E6L, s2 = -6.573568698209374121847873064292963089438E6L, s3 = -3.319055881485044417245964508099095984643E6L, s4 = -7.094891568758439227560184618114707107977E5L, s5 = -6.263426646464505837422314539808112478303E4L, s6 = -1.684926520999477529949915657519454051529E3L, r0 = -1.883978160734303518163008696712983134698E7L, r1 = -2.815206082812062064902202753264922306830E7L, r2 = -1.600245495251915899081846093343626358398E7L, r3 = -4.310526301881305003489257052083370058799E6L, r4 = -5.563807682263923279438235987186184968542E5L, r5 = -3.027734654434169996032905158145259713083E4L, r6 = -4.501995652861105629217250715790764371267E2L, /* r6 = 1.000000000000000000000000000000000000000E0 */ /* lgam(x) = ( x - 0.5 ) * log(x) - x + LS2PI + 1/x w(1/x^2) x >= 8 Peak relative error 1.51e-21 w0 = LS2PI - 0.5 */ w0 = 4.189385332046727417803e-1L, w1 = 8.333333333333331447505E-2L, w2 = -2.777777777750349603440E-3L, w3 = 7.936507795855070755671E-4L, w4 = -5.952345851765688514613E-4L, w5 = 8.412723297322498080632E-4L, w6 = -1.880801938119376907179E-3L, w7 = 4.885026142432270781165E-3L; static const long double zero = 0.0L; static long double sin_pi(long double x) { long double y, z; int n, ix; u_int32_t se, i0, i1; GET_LDOUBLE_WORDS (se, i0, i1, x); ix = se & 0x7fff; ix = (ix << 16) | (i0 >> 16); if (ix < 0x3ffd8000) /* 0.25 */ return sinl (pi * x); y = -x; /* x is assume negative */ /* * argument reduction, make sure inexact flag not raised if input * is an integer */ z = floorl (y); if (z != y) { /* inexact anyway */ y *= 0.5; y = 2.0*(y - floorl(y)); /* y = |x| mod 2.0 */ n = (int) (y*4.0); } else { if (ix >= 0x403f8000) /* 2^64 */ { y = zero; n = 0; /* y must be even */ } else { if (ix < 0x403e8000) /* 2^63 */ z = y + two63; /* exact */ GET_LDOUBLE_WORDS (se, i0, i1, z); n = i1 & 1; y = n; n <<= 2; } } switch (n) { case 0: y = sinl (pi * y); break; case 1: case 2: y = cosl (pi * (half - y)); break; case 3: case 4: y = sinl (pi * (one - y)); break; case 5: case 6: y = -cosl (pi * (y - 1.5)); break; default: y = sinl (pi * (y - 2.0)); break; } return -y; } long double lgammal_r(long double x, int *signgamp) { long double t, y, z, nadj, p, p1, p2, q, r, w; int i, ix; u_int32_t se, i0, i1; *signgamp = 1; GET_LDOUBLE_WORDS (se, i0, i1, x); ix = se & 0x7fff; if ((ix | i0 | i1) == 0) { if (se & 0x8000) *signgamp = -1; return one / fabsl (x); } ix = (ix << 16) | (i0 >> 16); /* purge off +-inf, NaN, +-0, and negative arguments */ if (ix >= 0x7fff0000) return x * x; if (ix < 0x3fc08000) /* 2^-63 */ { /* |x|<2**-63, return -log(|x|) */ if (se & 0x8000) { *signgamp = -1; return -logl (-x); } else return -logl (x); } if (se & 0x8000) { t = sin_pi (x); if (t == zero) return one / fabsl (t); /* -integer */ nadj = logl (pi / fabsl (t * x)); if (t < zero) *signgamp = -1; x = -x; } /* purge off 1 and 2 */ if ((((ix - 0x3fff8000) | i0 | i1) == 0) || (((ix - 0x40008000) | i0 | i1) == 0)) r = 0; else if (ix < 0x40008000) /* 2.0 */ { /* x < 2.0 */ if (ix <= 0x3ffee666) /* 8.99993896484375e-1 */ { /* lgamma(x) = lgamma(x+1) - log(x) */ r = -logl (x); if (ix >= 0x3ffebb4a) /* 7.31597900390625e-1 */ { y = x - one; i = 0; } else if (ix >= 0x3ffced33)/* 2.31639862060546875e-1 */ { y = x - (tc - one); i = 1; } else { /* x < 0.23 */ y = x; i = 2; } } else { r = zero; if (ix >= 0x3fffdda6) /* 1.73162841796875 */ { /* [1.7316,2] */ y = x - 2.0; i = 0; } else if (ix >= 0x3fff9da6)/* 1.23162841796875 */ { /* [1.23,1.73] */ y = x - tc; i = 1; } else { /* [0.9, 1.23] */ y = x - one; i = 2; } } switch (i) { case 0: p1 = a0 + y * (a1 + y * (a2 + y * (a3 + y * (a4 + y * a5)))); p2 = b0 + y * (b1 + y * (b2 + y * (b3 + y * (b4 + y)))); r += half * y + y * p1/p2; break; case 1: p1 = g0 + y * (g1 + y * (g2 + y * (g3 + y * (g4 + y * (g5 + y * g6))))); p2 = h0 + y * (h1 + y * (h2 + y * (h3 + y * (h4 + y * (h5 + y))))); p = tt + y * p1/p2; r += (tf + p); break; case 2: p1 = y * (u0 + y * (u1 + y * (u2 + y * (u3 + y * (u4 + y * (u5 + y * u6)))))); p2 = v0 + y * (v1 + y * (v2 + y * (v3 + y * (v4 + y * (v5 + y))))); r += (-half * y + p1 / p2); } } else if (ix < 0x40028000) /* 8.0 */ { /* x < 8.0 */ i = (int) x; t = zero; y = x - (double) i; p = y * (s0 + y * (s1 + y * (s2 + y * (s3 + y * (s4 + y * (s5 + y * s6)))))); q = r0 + y * (r1 + y * (r2 + y * (r3 + y * (r4 + y * (r5 + y * (r6 + y)))))); r = half * y + p / q; z = one; /* lgamma(1+s) = log(s) + lgamma(s) */ switch (i) { case 7: z *= (y + 6.0); /* FALLTHRU */ case 6: z *= (y + 5.0); /* FALLTHRU */ case 5: z *= (y + 4.0); /* FALLTHRU */ case 4: z *= (y + 3.0); /* FALLTHRU */ case 3: z *= (y + 2.0); /* FALLTHRU */ r += logl (z); break; } } else if (ix < 0x40418000) /* 2^66 */ { /* 8.0 <= x < 2**66 */ t = logl (x); z = one / x; y = z * z; w = w0 + z * (w1 + y * (w2 + y * (w3 + y * (w4 + y * (w5 + y * (w6 + y * w7)))))); r = (x - half) * (t - one) + w; } else /* 2**66 <= x <= inf */ r = x * (logl (x) - one); if (se & 0x8000) r = nadj - r; return r; } openlibm-0.5.0/ld80/e_log10l.c000066400000000000000000000110671266752446200156610ustar00rootroot00000000000000/* $OpenBSD: e_log10l.c,v 1.2 2013/11/12 20:35:19 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* log10l.c * * Common logarithm, long double precision * * * * SYNOPSIS: * * long double x, y, log10l(); * * y = log10l( x ); * * * * DESCRIPTION: * * Returns the base 10 logarithm of x. * * The argument is separated into its exponent and fractional * parts. If the exponent is between -1 and +1, the logarithm * of the fraction is approximated by * * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x). * * Otherwise, setting z = 2(x-1)/x+1), * * log(x) = z + z**3 P(z)/Q(z). * * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE 0.5, 2.0 30000 9.0e-20 2.6e-20 * IEEE exp(+-10000) 30000 6.0e-20 2.3e-20 * * In the tests over the interval exp(+-10000), the logarithms * of the random arguments were uniformly distributed over * [-10000, +10000]. * * ERROR MESSAGES: * * log singularity: x = 0; returns MINLOG * log domain: x < 0; returns MINLOG */ #include #include "math_private.h" /* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x) * 1/sqrt(2) <= x < sqrt(2) * Theoretical peak relative error = 6.2e-22 */ static long double P[] = { 4.9962495940332550844739E-1L, 1.0767376367209449010438E1L, 7.7671073698359539859595E1L, 2.5620629828144409632571E2L, 4.2401812743503691187826E2L, 3.4258224542413922935104E2L, 1.0747524399916215149070E2L, }; static long double Q[] = { /* 1.0000000000000000000000E0,*/ 2.3479774160285863271658E1L, 1.9444210022760132894510E2L, 7.7952888181207260646090E2L, 1.6911722418503949084863E3L, 2.0307734695595183428202E3L, 1.2695660352705325274404E3L, 3.2242573199748645407652E2L, }; /* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2), * where z = 2(x-1)/(x+1) * 1/sqrt(2) <= x < sqrt(2) * Theoretical peak relative error = 6.16e-22 */ static long double R[4] = { 1.9757429581415468984296E-3L, -7.1990767473014147232598E-1L, 1.0777257190312272158094E1L, -3.5717684488096787370998E1L, }; static long double S[4] = { /* 1.00000000000000000000E0L,*/ -2.6201045551331104417768E1L, 1.9361891836232102174846E2L, -4.2861221385716144629696E2L, }; /* log10(2) */ #define L102A 0.3125L #define L102B -1.1470004336018804786261e-2L /* log10(e) */ #define L10EA 0.5L #define L10EB -6.5705518096748172348871e-2L #define SQRTH 0.70710678118654752440L long double log10l(long double x) { long double y; volatile long double z; int e; if( isnan(x) ) return(x); /* Test for domain */ if( x <= 0.0L ) { if( x == 0.0L ) return (-1.0L / (x - x)); else return (x - x) / (x - x); } if( x == INFINITY ) return(INFINITY); /* separate mantissa from exponent */ /* Note, frexp is used so that denormal numbers * will be handled properly. */ x = frexpl( x, &e ); /* logarithm using log(x) = z + z**3 P(z)/Q(z), * where z = 2(x-1)/x+1) */ if( (e > 2) || (e < -2) ) { if( x < SQRTH ) { /* 2( 2x-1 )/( 2x+1 ) */ e -= 1; z = x - 0.5L; y = 0.5L * z + 0.5L; } else { /* 2 (x-1)/(x+1) */ z = x - 0.5L; z -= 0.5L; y = 0.5L * x + 0.5L; } x = z / y; z = x*x; y = x * ( z * __polevll( z, R, 3 ) / __p1evll( z, S, 3 ) ); goto done; } /* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */ if( x < SQRTH ) { e -= 1; x = ldexpl( x, 1 ) - 1.0L; /* 2x - 1 */ } else { x = x - 1.0L; } z = x*x; y = x * ( z * __polevll( x, P, 6 ) / __p1evll( x, Q, 7 ) ); y = y - ldexpl( z, -1 ); /* -0.5x^2 + ... */ done: /* Multiply log of fraction by log10(e) * and base 2 exponent by log10(2). * * ***CAUTION*** * * This sequence of operations is critical and it may * be horribly defeated by some compiler optimizers. */ z = y * (L10EB); z += x * (L10EB); z += e * (L102B); z += y * (L10EA); z += x * (L10EA); z += e * (L102A); return( z ); } openlibm-0.5.0/ld80/e_log2l.c000066400000000000000000000106061266752446200156000ustar00rootroot00000000000000/* $OpenBSD: e_log2l.c,v 1.2 2013/11/12 20:35:19 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* log2l.c * * Base 2 logarithm, long double precision * * * * SYNOPSIS: * * long double x, y, log2l(); * * y = log2l( x ); * * * * DESCRIPTION: * * Returns the base 2 logarithm of x. * * The argument is separated into its exponent and fractional * parts. If the exponent is between -1 and +1, the (natural) * logarithm of the fraction is approximated by * * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x). * * Otherwise, setting z = 2(x-1)/x+1), * * log(x) = z + z**3 P(z)/Q(z). * * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE 0.5, 2.0 30000 9.8e-20 2.7e-20 * IEEE exp(+-10000) 70000 5.4e-20 2.3e-20 * * In the tests over the interval exp(+-10000), the logarithms * of the random arguments were uniformly distributed over * [-10000, +10000]. * * ERROR MESSAGES: * * log singularity: x = 0; returns -INFINITY * log domain: x < 0; returns NAN */ #include #include "math_private.h" /* Coefficients for ln(1+x) = x - x**2/2 + x**3 P(x)/Q(x) * 1/sqrt(2) <= x < sqrt(2) * Theoretical peak relative error = 6.2e-22 */ static long double P[] = { 4.9962495940332550844739E-1L, 1.0767376367209449010438E1L, 7.7671073698359539859595E1L, 2.5620629828144409632571E2L, 4.2401812743503691187826E2L, 3.4258224542413922935104E2L, 1.0747524399916215149070E2L, }; static long double Q[] = { /* 1.0000000000000000000000E0,*/ 2.3479774160285863271658E1L, 1.9444210022760132894510E2L, 7.7952888181207260646090E2L, 1.6911722418503949084863E3L, 2.0307734695595183428202E3L, 1.2695660352705325274404E3L, 3.2242573199748645407652E2L, }; /* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2), * where z = 2(x-1)/(x+1) * 1/sqrt(2) <= x < sqrt(2) * Theoretical peak relative error = 6.16e-22 */ static long double R[4] = { 1.9757429581415468984296E-3L, -7.1990767473014147232598E-1L, 1.0777257190312272158094E1L, -3.5717684488096787370998E1L, }; static long double S[4] = { /* 1.00000000000000000000E0L,*/ -2.6201045551331104417768E1L, 1.9361891836232102174846E2L, -4.2861221385716144629696E2L, }; /* log2(e) - 1 */ #define LOG2EA 4.4269504088896340735992e-1L #define SQRTH 0.70710678118654752440L long double log2l(long double x) { volatile long double z; long double y; int e; if( isnan(x) ) return(x); if( x == INFINITY ) return(x); /* Test for domain */ if( x <= 0.0L ) { if( x == 0.0L ) return( -INFINITY ); else return( NAN ); } /* separate mantissa from exponent */ /* Note, frexp is used so that denormal numbers * will be handled properly. */ x = frexpl( x, &e ); /* logarithm using log(x) = z + z**3 P(z)/Q(z), * where z = 2(x-1)/x+1) */ if( (e > 2) || (e < -2) ) { if( x < SQRTH ) { /* 2( 2x-1 )/( 2x+1 ) */ e -= 1; z = x - 0.5L; y = 0.5L * z + 0.5L; } else { /* 2 (x-1)/(x+1) */ z = x - 0.5L; z -= 0.5L; y = 0.5L * x + 0.5L; } x = z / y; z = x*x; y = x * ( z * __polevll( z, R, 3 ) / __p1evll( z, S, 3 ) ); goto done; } /* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */ if( x < SQRTH ) { e -= 1; x = ldexpl( x, 1 ) - 1.0L; /* 2x - 1 */ } else { x = x - 1.0L; } z = x*x; y = x * ( z * __polevll( x, P, 6 ) / __p1evll( x, Q, 7 ) ); y = y - ldexpl( z, -1 ); /* -0.5x^2 + ... */ done: /* Multiply log of fraction by log2(e) * and base 2 exponent by 1 * * ***CAUTION*** * * This sequence of operations is critical and it may * be horribly defeated by some compiler optimizers. */ z = y * LOG2EA; z += x * LOG2EA; z += y; z += x; z += e; return( z ); } openlibm-0.5.0/ld80/e_logl.c000066400000000000000000000105671266752446200155240ustar00rootroot00000000000000/* $OpenBSD: e_logl.c,v 1.3 2013/11/12 20:35:19 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* logl.c * * Natural logarithm, long double precision * * * * SYNOPSIS: * * long double x, y, logl(); * * y = logl( x ); * * * * DESCRIPTION: * * Returns the base e (2.718...) logarithm of x. * * The argument is separated into its exponent and fractional * parts. If the exponent is between -1 and +1, the logarithm * of the fraction is approximated by * * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x). * * Otherwise, setting z = 2(x-1)/x+1), * * log(x) = z + z**3 P(z)/Q(z). * * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE 0.5, 2.0 150000 8.71e-20 2.75e-20 * IEEE exp(+-10000) 100000 5.39e-20 2.34e-20 * * In the tests over the interval exp(+-10000), the logarithms * of the random arguments were uniformly distributed over * [-10000, +10000]. * * ERROR MESSAGES: * * log singularity: x = 0; returns -INFINITY * log domain: x < 0; returns NAN */ #include #include "math_private.h" /* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x) * 1/sqrt(2) <= x < sqrt(2) * Theoretical peak relative error = 2.32e-20 */ static long double P[] = { 4.5270000862445199635215E-5L, 4.9854102823193375972212E-1L, 6.5787325942061044846969E0L, 2.9911919328553073277375E1L, 6.0949667980987787057556E1L, 5.7112963590585538103336E1L, 2.0039553499201281259648E1L, }; static long double Q[] = { /* 1.0000000000000000000000E0,*/ 1.5062909083469192043167E1L, 8.3047565967967209469434E1L, 2.2176239823732856465394E2L, 3.0909872225312059774938E2L, 2.1642788614495947685003E2L, 6.0118660497603843919306E1L, }; /* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2), * where z = 2(x-1)/(x+1) * 1/sqrt(2) <= x < sqrt(2) * Theoretical peak relative error = 6.16e-22 */ static long double R[4] = { 1.9757429581415468984296E-3L, -7.1990767473014147232598E-1L, 1.0777257190312272158094E1L, -3.5717684488096787370998E1L, }; static long double S[4] = { /* 1.00000000000000000000E0L,*/ -2.6201045551331104417768E1L, 1.9361891836232102174846E2L, -4.2861221385716144629696E2L, }; static const long double C1 = 6.9314575195312500000000E-1L; static const long double C2 = 1.4286068203094172321215E-6L; #define SQRTH 0.70710678118654752440L long double logl(long double x) { long double y, z; int e; if( isnan(x) ) return(x); if( x == INFINITY ) return(x); /* Test for domain */ if( x <= 0.0L ) { if( x == 0.0L ) return( -INFINITY ); else return( NAN ); } /* separate mantissa from exponent */ /* Note, frexp is used so that denormal numbers * will be handled properly. */ x = frexpl( x, &e ); /* logarithm using log(x) = z + z**3 P(z)/Q(z), * where z = 2(x-1)/x+1) */ if( (e > 2) || (e < -2) ) { if( x < SQRTH ) { /* 2( 2x-1 )/( 2x+1 ) */ e -= 1; z = x - 0.5L; y = 0.5L * z + 0.5L; } else { /* 2 (x-1)/(x+1) */ z = x - 0.5L; z -= 0.5L; y = 0.5L * x + 0.5L; } x = z / y; z = x*x; z = x * ( z * __polevll( z, R, 3 ) / __p1evll( z, S, 3 ) ); z = z + e * C2; z = z + x; z = z + e * C1; return( z ); } /* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */ if( x < SQRTH ) { e -= 1; x = ldexpl( x, 1 ) - 1.0L; /* 2x - 1 */ } else { x = x - 1.0L; } z = x*x; y = x * ( z * __polevll( x, P, 6 ) / __p1evll( x, Q, 6 ) ); y = y + e * C2; z = y - ldexpl( z, -1 ); /* y - 0.5 * z */ /* Note, the sum of above terms does not exceed x/4, * so it contributes at most about 1/4 lsb to the error. */ z = z + x; z = z + e * C1; /* This sum has an error of 1/2 lsb. */ return( z ); } openlibm-0.5.0/ld80/e_powl.c000066400000000000000000000306001266752446200155360ustar00rootroot00000000000000/* $OpenBSD: e_powl.c,v 1.5 2013/11/12 20:35:19 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* powl.c * * Power function, long double precision * * * * SYNOPSIS: * * long double x, y, z, powl(); * * z = powl( x, y ); * * * * DESCRIPTION: * * Computes x raised to the yth power. Analytically, * * x**y = exp( y log(x) ). * * Following Cody and Waite, this program uses a lookup table * of 2**-i/32 and pseudo extended precision arithmetic to * obtain several extra bits of accuracy in both the logarithm * and the exponential. * * * * ACCURACY: * * The relative error of pow(x,y) can be estimated * by y dl ln(2), where dl is the absolute error of * the internally computed base 2 logarithm. At the ends * of the approximation interval the logarithm equal 1/32 * and its relative error is about 1 lsb = 1.1e-19. Hence * the predicted relative error in the result is 2.3e-21 y . * * Relative error: * arithmetic domain # trials peak rms * * IEEE +-1000 40000 2.8e-18 3.7e-19 * .001 < x < 1000, with log(x) uniformly distributed. * -1000 < y < 1000, y uniformly distributed. * * IEEE 0,8700 60000 6.5e-18 1.0e-18 * 0.99 < x < 1.01, 0 < y < 8700, uniformly distributed. * * * ERROR MESSAGES: * * message condition value returned * pow overflow x**y > MAXNUM INFINITY * pow underflow x**y < 1/MAXNUM 0.0 * pow domain x<0 and y noninteger 0.0 * */ #include #include #include "math_private.h" /* Table size */ #define NXT 32 /* log2(Table size) */ #define LNXT 5 /* log(1+x) = x - .5x^2 + x^3 * P(z)/Q(z) * on the domain 2^(-1/32) - 1 <= x <= 2^(1/32) - 1 */ static long double P[] = { 8.3319510773868690346226E-4L, 4.9000050881978028599627E-1L, 1.7500123722550302671919E0L, 1.4000100839971580279335E0L, }; static long double Q[] = { /* 1.0000000000000000000000E0L,*/ 5.2500282295834889175431E0L, 8.4000598057587009834666E0L, 4.2000302519914740834728E0L, }; /* A[i] = 2^(-i/32), rounded to IEEE long double precision. * If i is even, A[i] + B[i/2] gives additional accuracy. */ static long double A[33] = { 1.0000000000000000000000E0L, 9.7857206208770013448287E-1L, 9.5760328069857364691013E-1L, 9.3708381705514995065011E-1L, 9.1700404320467123175367E-1L, 8.9735453750155359320742E-1L, 8.7812608018664974155474E-1L, 8.5930964906123895780165E-1L, 8.4089641525371454301892E-1L, 8.2287773907698242225554E-1L, 8.0524516597462715409607E-1L, 7.8799042255394324325455E-1L, 7.7110541270397041179298E-1L, 7.5458221379671136985669E-1L, 7.3841307296974965571198E-1L, 7.2259040348852331001267E-1L, 7.0710678118654752438189E-1L, 6.9195494098191597746178E-1L, 6.7712777346844636413344E-1L, 6.6261832157987064729696E-1L, 6.4841977732550483296079E-1L, 6.3452547859586661129850E-1L, 6.2092890603674202431705E-1L, 6.0762367999023443907803E-1L, 5.9460355750136053334378E-1L, 5.8186242938878875689693E-1L, 5.6939431737834582684856E-1L, 5.5719337129794626814472E-1L, 5.4525386633262882960438E-1L, 5.3357020033841180906486E-1L, 5.2213689121370692017331E-1L, 5.1094857432705833910408E-1L, 5.0000000000000000000000E-1L, }; static long double B[17] = { 0.0000000000000000000000E0L, 2.6176170809902549338711E-20L, -1.0126791927256478897086E-20L, 1.3438228172316276937655E-21L, 1.2207982955417546912101E-20L, -6.3084814358060867200133E-21L, 1.3164426894366316434230E-20L, -1.8527916071632873716786E-20L, 1.8950325588932570796551E-20L, 1.5564775779538780478155E-20L, 6.0859793637556860974380E-21L, -2.0208749253662532228949E-20L, 1.4966292219224761844552E-20L, 3.3540909728056476875639E-21L, -8.6987564101742849540743E-22L, -1.2327176863327626135542E-20L, 0.0000000000000000000000E0L, }; /* 2^x = 1 + x P(x), * on the interval -1/32 <= x <= 0 */ static long double R[] = { 1.5089970579127659901157E-5L, 1.5402715328927013076125E-4L, 1.3333556028915671091390E-3L, 9.6181291046036762031786E-3L, 5.5504108664798463044015E-2L, 2.4022650695910062854352E-1L, 6.9314718055994530931447E-1L, }; #define douba(k) A[k] #define doubb(k) B[k] #define MEXP (NXT*16384.0L) /* The following if denormal numbers are supported, else -MEXP: */ #define MNEXP (-NXT*(16384.0L+64.0L)) /* log2(e) - 1 */ #define LOG2EA 0.44269504088896340735992L #define F W #define Fa Wa #define Fb Wb #define G W #define Ga Wa #define Gb u #define H W #define Ha Wb #define Hb Wb static const long double MAXLOGL = 1.1356523406294143949492E4L; static const long double MINLOGL = -1.13994985314888605586758E4L; static const long double LOGE2L = 6.9314718055994530941723E-1L; static volatile long double z; static long double w, W, Wa, Wb, ya, yb, u; static const long double huge = 0x1p10000L; #if 0 /* XXX Prevent gcc from erroneously constant folding this. */ static const long double twom10000 = 0x1p-10000L; #else static volatile long double twom10000 = 0x1p-10000L; #endif static long double reducl( long double ); static long double powil ( long double, int ); long double powl(long double x, long double y) { /* double F, Fa, Fb, G, Ga, Gb, H, Ha, Hb */ int i, nflg, iyflg, yoddint; long e; if( y == 0.0L ) return( 1.0L ); if( x == 1.0L ) return( 1.0L ); if( isnan(x) ) return( x ); if( isnan(y) ) return( y ); if( y == 1.0L ) return( x ); if( !isfinite(y) && x == -1.0L ) return( 1.0L ); if( y >= LDBL_MAX ) { if( x > 1.0L ) return( INFINITY ); if( x > 0.0L && x < 1.0L ) return( 0.0L ); if( x < -1.0L ) return( INFINITY ); if( x > -1.0L && x < 0.0L ) return( 0.0L ); } if( y <= -LDBL_MAX ) { if( x > 1.0L ) return( 0.0L ); if( x > 0.0L && x < 1.0L ) return( INFINITY ); if( x < -1.0L ) return( 0.0L ); if( x > -1.0L && x < 0.0L ) return( INFINITY ); } if( x >= LDBL_MAX ) { if( y > 0.0L ) return( INFINITY ); return( 0.0L ); } w = floorl(y); /* Set iyflg to 1 if y is an integer. */ iyflg = 0; if( w == y ) iyflg = 1; /* Test for odd integer y. */ yoddint = 0; if( iyflg ) { ya = fabsl(y); ya = floorl(0.5L * ya); yb = 0.5L * fabsl(w); if( ya != yb ) yoddint = 1; } if( x <= -LDBL_MAX ) { if( y > 0.0L ) { if( yoddint ) return( -INFINITY ); return( INFINITY ); } if( y < 0.0L ) { if( yoddint ) return( -0.0L ); return( 0.0 ); } } nflg = 0; /* flag = 1 if x<0 raised to integer power */ if( x <= 0.0L ) { if( x == 0.0L ) { if( y < 0.0 ) { if( signbit(x) && yoddint ) return( -INFINITY ); return( INFINITY ); } if( y > 0.0 ) { if( signbit(x) && yoddint ) return( -0.0L ); return( 0.0 ); } if( y == 0.0L ) return( 1.0L ); /* 0**0 */ else return( 0.0L ); /* 0**y */ } else { if( iyflg == 0 ) return (x - x) / (x - x); /* (x<0)**(non-int) is NaN */ nflg = 1; } } /* Integer power of an integer. */ if( iyflg ) { i = w; w = floorl(x); if( (w == x) && (fabsl(y) < 32768.0) ) { w = powil( x, (int) y ); return( w ); } } if( nflg ) x = fabsl(x); /* separate significand from exponent */ x = frexpl( x, &i ); e = i; /* find significand in antilog table A[] */ i = 1; if( x <= douba(17) ) i = 17; if( x <= douba(i+8) ) i += 8; if( x <= douba(i+4) ) i += 4; if( x <= douba(i+2) ) i += 2; if( x >= douba(1) ) i = -1; i += 1; /* Find (x - A[i])/A[i] * in order to compute log(x/A[i]): * * log(x) = log( a x/a ) = log(a) + log(x/a) * * log(x/a) = log(1+v), v = x/a - 1 = (x-a)/a */ x -= douba(i); x -= doubb(i/2); x /= douba(i); /* rational approximation for log(1+v): * * log(1+v) = v - v**2/2 + v**3 P(v) / Q(v) */ z = x*x; w = x * ( z * __polevll( x, P, 3 ) / __p1evll( x, Q, 3 ) ); w = w - ldexpl( z, -1 ); /* w - 0.5 * z */ /* Convert to base 2 logarithm: * multiply by log2(e) = 1 + LOG2EA */ z = LOG2EA * w; z += w; z += LOG2EA * x; z += x; /* Compute exponent term of the base 2 logarithm. */ w = -i; w = ldexpl( w, -LNXT ); /* divide by NXT */ w += e; /* Now base 2 log of x is w + z. */ /* Multiply base 2 log by y, in extended precision. */ /* separate y into large part ya * and small part yb less than 1/NXT */ ya = reducl(y); yb = y - ya; /* (w+z)(ya+yb) * = w*ya + w*yb + z*y */ F = z * y + w * yb; Fa = reducl(F); Fb = F - Fa; G = Fa + w * ya; Ga = reducl(G); Gb = G - Ga; H = Fb + Gb; Ha = reducl(H); w = ldexpl( Ga+Ha, LNXT ); /* Test the power of 2 for overflow */ if( w > MEXP ) return (huge * huge); /* overflow */ if( w < MNEXP ) return (twom10000 * twom10000); /* underflow */ e = w; Hb = H - Ha; if( Hb > 0.0L ) { e += 1; Hb -= (1.0L/NXT); /*0.0625L;*/ } /* Now the product y * log2(x) = Hb + e/NXT. * * Compute base 2 exponential of Hb, * where -0.0625 <= Hb <= 0. */ z = Hb * __polevll( Hb, R, 6 ); /* z = 2**Hb - 1 */ /* Express e/NXT as an integer plus a negative number of (1/NXT)ths. * Find lookup table entry for the fractional power of 2. */ if( e < 0 ) i = 0; else i = 1; i = e/NXT + i; e = NXT*i - e; w = douba( e ); z = w * z; /* 2**-e * ( 1 + (2**Hb-1) ) */ z = z + w; z = ldexpl( z, i ); /* multiply by integer power of 2 */ if( nflg ) { /* For negative x, * find out if the integer exponent * is odd or even. */ w = ldexpl( y, -1 ); w = floorl(w); w = ldexpl( w, 1 ); if( w != y ) z = -z; /* odd exponent */ } return( z ); } /* Find a multiple of 1/NXT that is within 1/NXT of x. */ static long double reducl(long double x) { long double t; t = ldexpl( x, LNXT ); t = floorl( t ); t = ldexpl( t, -LNXT ); return(t); } /* powil.c * * Real raised to integer power, long double precision * * * * SYNOPSIS: * * long double x, y, powil(); * int n; * * y = powil( x, n ); * * * * DESCRIPTION: * * Returns argument x raised to the nth power. * The routine efficiently decomposes n as a sum of powers of * two. The desired power is a product of two-to-the-kth * powers of x. Thus to compute the 32767 power of x requires * 28 multiplications instead of 32767 multiplications. * * * * ACCURACY: * * * Relative error: * arithmetic x domain n domain # trials peak rms * IEEE .001,1000 -1022,1023 50000 4.3e-17 7.8e-18 * IEEE 1,2 -1022,1023 20000 3.9e-17 7.6e-18 * IEEE .99,1.01 0,8700 10000 3.6e-16 7.2e-17 * * Returns MAXNUM on overflow, zero on underflow. * */ static long double powil(long double x, int nn) { long double ww, y; long double s; int n, e, sign, asign, lx; if( x == 0.0L ) { if( nn == 0 ) return( 1.0L ); else if( nn < 0 ) return( LDBL_MAX ); else return( 0.0L ); } if( nn == 0 ) return( 1.0L ); if( x < 0.0L ) { asign = -1; x = -x; } else asign = 0; if( nn < 0 ) { sign = -1; n = -nn; } else { sign = 1; n = nn; } /* Overflow detection */ /* Calculate approximate logarithm of answer */ s = x; s = frexpl( s, &lx ); e = (lx - 1)*n; if( (e == 0) || (e > 64) || (e < -64) ) { s = (s - 7.0710678118654752e-1L) / (s + 7.0710678118654752e-1L); s = (2.9142135623730950L * s - 0.5L + lx) * nn * LOGE2L; } else { s = LOGE2L * e; } if( s > MAXLOGL ) return (huge * huge); /* overflow */ if( s < MINLOGL ) return (twom10000 * twom10000); /* underflow */ /* Handle tiny denormal answer, but with less accuracy * since roundoff error in 1.0/x will be amplified. * The precise demarcation should be the gradual underflow threshold. */ if( s < (-MAXLOGL+2.0L) ) { x = 1.0L/x; sign = -sign; } /* First bit of the power */ if( n & 1 ) y = x; else { y = 1.0L; asign = 0; } ww = x; n >>= 1; while( n ) { ww = ww * ww; /* arg to the 2-to-the-kth power */ if( n & 1 ) /* if that bit is set, then include in product */ y *= ww; n >>= 1; } if( asign ) y = -y; /* odd power of negative number */ if( sign < 0 ) y = 1.0L/y; return(y); } openlibm-0.5.0/ld80/e_rem_pio2l.h000066400000000000000000000111621266752446200164540ustar00rootroot00000000000000/* From: @(#)e_rem_pio2.c 1.4 95/01/18 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== * * Optimized by Bruce D. Evans. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/ld80/e_rem_pio2l.h,v 1.3 2011/06/18 13:56:33 benl Exp $"); /* ld80 version of __ieee754_rem_pio2l(x,y) * * return the remainder of x rem pi/2 in y[0]+y[1] * use __kernel_rem_pio2() */ #include #include #include "math_private.h" #define BIAS (LDBL_MAX_EXP - 1) /* * invpio2: 64 bits of 2/pi * pio2_1: first 39 bits of pi/2 * pio2_1t: pi/2 - pio2_1 * pio2_2: second 39 bits of pi/2 * pio2_2t: pi/2 - (pio2_1+pio2_2) * pio2_3: third 39 bits of pi/2 * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) */ static const double zero = 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */ pio2_1 = 1.57079632679597125389e+00, /* 0x3FF921FB, 0x54444000 */ pio2_2 = -1.07463465549783099519e-12, /* -0x12e7b967674000.0p-92 */ pio2_3 = 6.36831716351370313614e-25; /* 0x18a2e037074000.0p-133 */ #if defined(__amd64__) || defined(__i386__) /* Long double constants are slow on these arches, and broken on i386. */ static const volatile double invpio2hi = 6.3661977236758138e-01, /* 0x145f306dc9c883.0p-53 */ invpio2lo = -3.9356538861223811e-17, /* -0x16b00000000000.0p-107 */ pio2_1thi = -1.0746346554971943e-12, /* -0x12e7b9676733af.0p-92 */ pio2_1tlo = 8.8451028997905949e-29, /* 0x1c080000000000.0p-146 */ pio2_2thi = 6.3683171635109499e-25, /* 0x18a2e03707344a.0p-133 */ pio2_2tlo = 2.3183081793789774e-41, /* 0x10280000000000.0p-187 */ pio2_3thi = -2.7529965190440717e-37, /* -0x176b7ed8fbbacc.0p-174 */ pio2_3tlo = -4.2006647512740502e-54; /* -0x19c00000000000.0p-230 */ #define invpio2 ((long double)invpio2hi + invpio2lo) #define pio2_1t ((long double)pio2_1thi + pio2_1tlo) #define pio2_2t ((long double)pio2_2thi + pio2_2tlo) #define pio2_3t ((long double)pio2_3thi + pio2_3tlo) #else static const long double invpio2 = 6.36619772367581343076e-01L, /* 0xa2f9836e4e44152a.0p-64 */ pio2_1t = -1.07463465549719416346e-12L, /* -0x973dcb3b399d747f.0p-103 */ pio2_2t = 6.36831716351095013979e-25L, /* 0xc51701b839a25205.0p-144 */ pio2_3t = -2.75299651904407171810e-37L; /* -0xbb5bf6c7ddd660ce.0p-185 */ #endif //VBS //static inline __always_inline int //__ieee754_rem_pio2l(long double x, long double *y) static inline int __ieee754_rem_pio2l(long double x, long double *y) { union IEEEl2bits u,u1; long double z,w,t,r,fn; double tx[3],ty[2]; int e0,ex,i,j,nx,n; int16_t expsign; u.e = x; expsign = u.xbits.expsign; ex = expsign & 0x7fff; if (ex < BIAS + 25 || (ex == BIAS + 25 && u.bits.manh < 0xc90fdaa2)) { /* |x| ~< 2^25*(pi/2), medium size */ /* Use a specialized rint() to get fn. Assume round-to-nearest. */ fn = x*invpio2+0x1.8p63; fn = fn-0x1.8p63; #ifdef HAVE_EFFICIENT_IRINT n = irint(fn); #else n = fn; #endif r = x-fn*pio2_1; w = fn*pio2_1t; /* 1st round good to 102 bit */ { union IEEEl2bits u2; int ex1; j = ex; y[0] = r-w; u2.e = y[0]; ex1 = u2.xbits.expsign & 0x7fff; i = j-ex1; if(i>22) { /* 2nd iteration needed, good to 141 */ t = r; w = fn*pio2_2; r = t-w; w = fn*pio2_2t-((t-r)-w); y[0] = r-w; u2.e = y[0]; ex1 = u2.xbits.expsign & 0x7fff; i = j-ex1; if(i>61) { /* 3rd iteration need, 180 bits acc */ t = r; /* will cover all possible cases */ w = fn*pio2_3; r = t-w; w = fn*pio2_3t-((t-r)-w); y[0] = r-w; } } } y[1] = (r-y[0])-w; return n; } /* * all other (large) arguments */ if(ex==0x7fff) { /* x is inf or NaN */ y[0]=y[1]=x-x; return 0; } /* set z = scalbn(|x|,ilogb(x)-23) */ u1.e = x; e0 = ex - BIAS - 23; /* e0 = ilogb(|x|)-23; */ u1.xbits.expsign = ex - e0; z = u1.e; for(i=0;i<2;i++) { tx[i] = (double)((int32_t)(z)); z = (z-tx[i])*two24; } tx[2] = z; nx = 3; while(tx[nx-1]==zero) nx--; /* skip zero term */ n = __kernel_rem_pio2(tx,ty,e0,nx,2); r = (long double)ty[0] + ty[1]; w = ty[1] - (r - ty[0]); if(expsign<0) {y[0] = -r; y[1] = -w; return -n;} y[0] = r; y[1] = w; return n; } openlibm-0.5.0/ld80/e_sinhl.c000066400000000000000000000041521266752446200156750ustar00rootroot00000000000000/* @(#)e_sinh.c 5.1 93/09/24 */ /* * ==================================================== * 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. * ==================================================== */ /* sinhl(x) * Method : * mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2 * 1. Replace x by |x| (sinhl(-x) = -sinhl(x)). * 2. * E + E/(E+1) * 0 <= x <= 25 : sinhl(x) := --------------, E=expm1l(x) * 2 * * 25 <= x <= lnovft : sinhl(x) := expl(x)/2 * lnovft <= x <= ln2ovft: sinhl(x) := expl(x/2)/2 * expl(x/2) * ln2ovft < x : sinhl(x) := x*shuge (overflow) * * Special cases: * sinhl(x) is |x| if x is +INF, -INF, or NaN. * only sinhl(0)=0 is exact for finite x. */ #include #include "math_private.h" static const long double one = 1.0, shuge = 1.0e4931L; long double sinhl(long double x) { long double t,w,h; u_int32_t jx,ix,i0,i1; /* Words of |x|. */ GET_LDOUBLE_WORDS(jx,i0,i1,x); ix = jx&0x7fff; /* x is INF or NaN */ if(ix==0x7fff) return x+x; h = 0.5; if (jx & 0x8000) h = -h; /* |x| in [0,25], return sign(x)*0.5*(E+E/(E+1))) */ if (ix < 0x4003 || (ix == 0x4003 && i0 <= 0xc8000000)) { /* |x|<25 */ if (ix<0x3fdf) /* |x|<2**-32 */ if(shuge+x>one) return x;/* sinh(tiny) = tiny with inexact */ t = expm1l(fabsl(x)); if(ix<0x3fff) return h*(2.0*t-t*t/(t+one)); return h*(t+t/(t+one)); } /* |x| in [25, log(maxdouble)] return 0.5*exp(|x|) */ if (ix < 0x400c || (ix == 0x400c && i0 < 0xb17217f7)) return h*expl(fabsl(x)); /* |x| in [log(maxdouble), overflowthreshold] */ if (ix<0x400c || (ix == 0x400c && (i0 < 0xb174ddc0 || (i0 == 0xb174ddc0 && i1 <= 0x31aec0ea)))) { w = expl(0.5*fabsl(x)); t = h*w; return t*w; } /* |x| > overflowthreshold, sinhl(x) overflow */ return x*shuge; } openlibm-0.5.0/ld80/e_tgammal.c000066400000000000000000000146651266752446200162140ustar00rootroot00000000000000/* $OpenBSD: e_tgammal.c,v 1.4 2013/11/12 20:35:19 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* tgammal.c * * Gamma function * * * * SYNOPSIS: * * long double x, y, tgammal(); * * y = tgammal( x ); * * * * DESCRIPTION: * * Returns gamma function of the argument. The result is correctly * signed. This variable is also filled in by the logarithmic gamma * function lgamma(). * * Arguments |x| <= 13 are reduced by recurrence and the function * approximated by a rational function of degree 7/8 in the * interval (2,3). Large arguments are handled by Stirling's * formula. Large negative arguments are made positive using * a reflection formula. * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE -40,+40 10000 3.6e-19 7.9e-20 * IEEE -1755,+1755 10000 4.8e-18 6.5e-19 * * Accuracy for large arguments is dominated by error in powl(). * */ #include #include #include "math_private.h" /* tgamma(x+2) = tgamma(x+2) P(x)/Q(x) 0 <= x <= 1 Relative error n=7, d=8 Peak error = 1.83e-20 Relative error spread = 8.4e-23 */ static long double P[8] = { 4.212760487471622013093E-5L, 4.542931960608009155600E-4L, 4.092666828394035500949E-3L, 2.385363243461108252554E-2L, 1.113062816019361559013E-1L, 3.629515436640239168939E-1L, 8.378004301573126728826E-1L, 1.000000000000000000009E0L, }; static long double Q[9] = { -1.397148517476170440917E-5L, 2.346584059160635244282E-4L, -1.237799246653152231188E-3L, -7.955933682494738320586E-4L, 2.773706565840072979165E-2L, -4.633887671244534213831E-2L, -2.243510905670329164562E-1L, 4.150160950588455434583E-1L, 9.999999999999999999908E-1L, }; /* static long double P[] = { -3.01525602666895735709e0L, -3.25157411956062339893e1L, -2.92929976820724030353e2L, -1.70730828800510297666e3L, -7.96667499622741999770e3L, -2.59780216007146401957e4L, -5.99650230220855581642e4L, -7.15743521530849602425e4L }; static long double Q[] = { 1.00000000000000000000e0L, -1.67955233807178858919e1L, 8.85946791747759881659e1L, 5.69440799097468430177e1L, -1.98526250512761318471e3L, 3.31667508019495079814e3L, 1.60577839621734713377e4L, -2.97045081369399940529e4L, -7.15743521530849602412e4L }; */ #define MAXGAML 1755.455L /*static const long double LOGPI = 1.14472988584940017414L;*/ /* Stirling's formula for the gamma function tgamma(x) = sqrt(2 pi) x^(x-.5) exp(-x) (1 + 1/x P(1/x)) z(x) = x 13 <= x <= 1024 Relative error n=8, d=0 Peak error = 9.44e-21 Relative error spread = 8.8e-4 */ static long double STIR[9] = { 7.147391378143610789273E-4L, -2.363848809501759061727E-5L, -5.950237554056330156018E-4L, 6.989332260623193171870E-5L, 7.840334842744753003862E-4L, -2.294719747873185405699E-4L, -2.681327161876304418288E-3L, 3.472222222230075327854E-3L, 8.333333333333331800504E-2L, }; #define MAXSTIR 1024.0L static const long double SQTPI = 2.50662827463100050242E0L; /* 1/tgamma(x) = z P(z) * z(x) = 1/x * 0 < x < 0.03125 * Peak relative error 4.2e-23 */ static long double S[9] = { -1.193945051381510095614E-3L, 7.220599478036909672331E-3L, -9.622023360406271645744E-3L, -4.219773360705915470089E-2L, 1.665386113720805206758E-1L, -4.200263503403344054473E-2L, -6.558780715202540684668E-1L, 5.772156649015328608253E-1L, 1.000000000000000000000E0L, }; /* 1/tgamma(-x) = z P(z) * z(x) = 1/x * 0 < x < 0.03125 * Peak relative error 5.16e-23 * Relative error spread = 2.5e-24 */ static long double SN[9] = { 1.133374167243894382010E-3L, 7.220837261893170325704E-3L, 9.621911155035976733706E-3L, -4.219773343731191721664E-2L, -1.665386113944413519335E-1L, -4.200263503402112910504E-2L, 6.558780715202536547116E-1L, 5.772156649015328608727E-1L, -1.000000000000000000000E0L, }; static const long double PIL = 3.1415926535897932384626L; static long double stirf ( long double ); /* Gamma function computed by Stirling's formula. */ static long double stirf(long double x) { long double y, w, v; w = 1.0L/x; /* For large x, use rational coefficients from the analytical expansion. */ if( x > 1024.0L ) w = (((((6.97281375836585777429E-5L * w + 7.84039221720066627474E-4L) * w - 2.29472093621399176955E-4L) * w - 2.68132716049382716049E-3L) * w + 3.47222222222222222222E-3L) * w + 8.33333333333333333333E-2L) * w + 1.0L; else w = 1.0L + w * __polevll( w, STIR, 8 ); y = expl(x); if( x > MAXSTIR ) { /* Avoid overflow in pow() */ v = powl( x, 0.5L * x - 0.25L ); y = v * (v / y); } else { y = powl( x, x - 0.5L ) / y; } y = SQTPI * y * w; return( y ); } long double tgammal(long double x) { long double p, q, z; int i; if( isnan(x) ) return(NAN); if(x == INFINITY) return(INFINITY); if(x == -INFINITY) return(x - x); if( x == 0.0L ) return( 1.0L / x ); q = fabsl(x); if( q > 13.0L ) { int sign = 1; if( q > MAXGAML ) goto goverf; if( x < 0.0L ) { p = floorl(q); if( p == q ) return (x - x) / (x - x); i = p; if( (i & 1) == 0 ) sign = -1; z = q - p; if( z > 0.5L ) { p += 1.0L; z = q - p; } z = q * sinl( PIL * z ); z = fabsl(z) * stirf(q); if( z <= PIL/LDBL_MAX ) { goverf: return( sign * INFINITY); } z = PIL/z; } else { z = stirf(x); } return( sign * z ); } z = 1.0L; while( x >= 3.0L ) { x -= 1.0L; z *= x; } while( x < -0.03125L ) { z /= x; x += 1.0L; } if( x <= 0.03125L ) goto small; while( x < 2.0L ) { z /= x; x += 1.0L; } if( x == 2.0L ) return(z); x -= 2.0L; p = __polevll( x, P, 7 ); q = __polevll( x, Q, 8 ); z = z * p / q; return z; small: if( x == 0.0L ) return (x - x) / (x - x); else { if( x < 0.0L ) { x = -x; q = z / (x * __polevll( x, SN, 8 )); } else q = z / (x * __polevll( x, S, 8 )); } return q; } openlibm-0.5.0/ld80/invtrig.c000066400000000000000000000054101266752446200157340ustar00rootroot00000000000000/*- * Copyright (c) 2008 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/ld80/invtrig.c,v 1.1 2008/07/31 22:41:26 das Exp $"); #include "ld80/invtrig.h" /* * asinl() and acosl() */ const long double pS0 = 1.66666666666666666631e-01L, pS1 = -4.16313987993683104320e-01L, pS2 = 3.69068046323246813704e-01L, pS3 = -1.36213932016738603108e-01L, pS4 = 1.78324189708471965733e-02L, pS5 = -2.19216428382605211588e-04L, pS6 = -7.10526623669075243183e-06L, qS1 = -2.94788392796209867269e+00L, qS2 = 3.27309890266528636716e+00L, qS3 = -1.68285799854822427013e+00L, qS4 = 3.90699412641738801874e-01L, qS5 = -3.14365703596053263322e-02L; /* * atanl() */ const long double atanhi[] = { 4.63647609000806116202e-01L, 7.85398163397448309628e-01L, 9.82793723247329067960e-01L, 1.57079632679489661926e+00L, }; const long double atanlo[] = { 1.18469937025062860669e-20L, -1.25413940316708300586e-20L, 2.55232234165405176172e-20L, -2.50827880633416601173e-20L, }; const long double aT[] = { 3.33333333333333333017e-01L, -1.99999999999999632011e-01L, 1.42857142857046531280e-01L, -1.11111111100562372733e-01L, 9.09090902935647302252e-02L, -7.69230552476207730353e-02L, 6.66661718042406260546e-02L, -5.88158892835030888692e-02L, 5.25499891539726639379e-02L, -4.70119845393155721494e-02L, 4.03539201366454414072e-02L, -2.91303858419364158725e-02L, 1.24822046299269234080e-02L, }; const long double pi_lo = -5.01655761266833202345e-20L; openlibm-0.5.0/ld80/invtrig.h000066400000000000000000000063301266752446200157430ustar00rootroot00000000000000/*- * Copyright (c) 2008 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/lib/msun/ld80/invtrig.h,v 1.2 2008/08/02 03:56:22 das Exp $ */ #include #include #define BIAS (LDBL_MAX_EXP - 1) #define MANH_SIZE LDBL_MANH_SIZE /* Approximation thresholds. */ #define ASIN_LINEAR (BIAS - 32) /* 2**-32 */ #define ACOS_CONST (BIAS - 65) /* 2**-65 */ #define ATAN_CONST (BIAS + 65) /* 2**65 */ #define ATAN_LINEAR (BIAS - 32) /* 2**-32 */ /* 0.95 */ #define THRESH ((0xe666666666666666ULL>>(64-(MANH_SIZE-1)))|LDBL_NBIT) /* Constants shared by the long double inverse trig functions. */ #define pS0 _ItL_pS0 #define pS1 _ItL_pS1 #define pS2 _ItL_pS2 #define pS3 _ItL_pS3 #define pS4 _ItL_pS4 #define pS5 _ItL_pS5 #define pS6 _ItL_pS6 #define qS1 _ItL_qS1 #define qS2 _ItL_qS2 #define qS3 _ItL_qS3 #define qS4 _ItL_qS4 #define qS5 _ItL_qS5 #define atanhi _ItL_atanhi #define atanlo _ItL_atanlo #define aT _ItL_aT #define pi_lo _ItL_pi_lo #define pio2_hi atanhi[3] #define pio2_lo atanlo[3] #define pio4_hi atanhi[1] #ifdef STRUCT_DECLS typedef struct longdouble { uint64_t mant; uint16_t expsign; } LONGDOUBLE; #else typedef long double LONGDOUBLE; #endif extern const LONGDOUBLE pS0, pS1, pS2, pS3, pS4, pS5, pS6; extern const LONGDOUBLE qS1, qS2, qS3, qS4, qS5; extern const LONGDOUBLE atanhi[], atanlo[], aT[]; extern const LONGDOUBLE pi_lo; #ifndef STRUCT_DECLS static inline long double P(long double x) { return (x * (pS0 + x * (pS1 + x * (pS2 + x * (pS3 + x * \ (pS4 + x * (pS5 + x * pS6))))))); } static inline long double Q(long double x) { return (1.0 + x * (qS1 + x * (qS2 + x * (qS3 + x * (qS4 + x * qS5))))); } static inline long double T_even(long double x) { return (aT[0] + x * (aT[2] + x * (aT[4] + x * (aT[6] + x * \ (aT[8] + x * (aT[10] + x * aT[12])))))); } static inline long double T_odd(long double x) { return (aT[1] + x * (aT[3] + x * (aT[5] + x * (aT[7] + x * \ (aT[9] + x * aT[11]))))); } #endif openlibm-0.5.0/ld80/k_cosl.c000066400000000000000000000055511266752446200155320ustar00rootroot00000000000000/* From: @(#)k_cos.c 1.3 95/01/18 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/ld80/k_cosl.c,v 1.1 2008/02/17 07:32:14 das Exp $"); /* * ld80 version of k_cos.c. See ../src/k_cos.c for most comments. */ #include "math_private.h" /* * Domain [-0.7854, 0.7854], range ~[-2.43e-23, 2.425e-23]: * |cos(x) - c(x)| < 2**-75.1 * * The coefficients of c(x) were generated by a pari-gp script using * a Remez algorithm that searches for the best higher coefficients * after rounding leading coefficients to a specified precision. * * Simpler methods like Chebyshev or basic Remez barely suffice for * cos() in 64-bit precision, because we want the coefficient of x^2 * to be precisely -0.5 so that multiplying by it is exact, and plain * rounding of the coefficients of a good polynomial approximation only * gives this up to about 64-bit precision. Plain rounding also gives * a mediocre approximation for the coefficient of x^4, but a rounding * error of 0.5 ulps for this coefficient would only contribute ~0.01 * ulps to the final error, so this is unimportant. Rounding errors in * higher coefficients are even less important. * * In fact, coefficients above the x^4 one only need to have 53-bit * precision, and this is more efficient. We get this optimization * almost for free from the complications needed to search for the best * higher coefficients. */ static const double one = 1.0; #if defined(__amd64__) || defined(__i386__) /* Long double constants are slow on these arches, and broken on i386. */ static const volatile double C1hi = 0.041666666666666664, /* 0x15555555555555.0p-57 */ C1lo = 2.2598839032744733e-18; /* 0x14d80000000000.0p-111 */ #define C1 ((long double)C1hi + C1lo) #else static const long double C1 = 0.0416666666666666666136L; /* 0xaaaaaaaaaaaaaa9b.0p-68 */ #endif static const double C2 = -0.0013888888888888874, /* -0x16c16c16c16c10.0p-62 */ C3 = 0.000024801587301571716, /* 0x1a01a01a018e22.0p-68 */ C4 = -0.00000027557319215507120, /* -0x127e4fb7602f22.0p-74 */ C5 = 0.0000000020876754400407278, /* 0x11eed8caaeccf1.0p-81 */ C6 = -1.1470297442401303e-11, /* -0x19393412bd1529.0p-89 */ C7 = 4.7383039476436467e-14; /* 0x1aac9d9af5c43e.0p-97 */ DLLEXPORT long double __kernel_cosl(long double x, long double y) { long double hz,z,r,w; z = x*x; r = z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*(C6+z*C7)))))); hz = 0.5*z; w = one-hz; return w + (((one-w)-hz) + (z*r-x*y)); } openlibm-0.5.0/ld80/k_sinl.c000066400000000000000000000037451266752446200155420ustar00rootroot00000000000000/* From: @(#)k_sin.c 1.3 95/01/18 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/ld80/k_sinl.c,v 1.1 2008/02/17 07:32:14 das Exp $"); /* * ld80 version of k_sin.c. See ../src/k_sin.c for most comments. */ #include "math_private.h" static const double half = 0.5; /* * Domain [-0.7854, 0.7854], range ~[-1.89e-22, 1.915e-22] * |sin(x)/x - s(x)| < 2**-72.1 * * See ../ld80/k_cosl.c for more details about the polynomial. */ #if defined(__amd64__) || defined(__i386__) /* Long double constants are slow on these arches, and broken on i386. */ static const volatile double S1hi = -0.16666666666666666, /* -0x15555555555555.0p-55 */ S1lo = -9.2563760475949941e-18; /* -0x15580000000000.0p-109 */ #define S1 ((long double)S1hi + S1lo) #else static const long double S1 = -0.166666666666666666671L; /* -0xaaaaaaaaaaaaaaab.0p-66 */ #endif static const double S2 = 0.0083333333333333332, /* 0x11111111111111.0p-59 */ S3 = -0.00019841269841269427, /* -0x1a01a01a019f81.0p-65 */ S4 = 0.0000027557319223597490, /* 0x171de3a55560f7.0p-71 */ S5 = -0.000000025052108218074604, /* -0x1ae64564f16cad.0p-78 */ S6 = 1.6059006598854211e-10, /* 0x161242b90243b5.0p-85 */ S7 = -7.6429779983024564e-13, /* -0x1ae42ebd1b2e00.0p-93 */ S8 = 2.6174587166648325e-15; /* 0x179372ea0b3f64.0p-101 */ DLLEXPORT long double __kernel_sinl(long double x, long double y, int iy) { long double z,r,v; z = x*x; v = z*x; r = S2+z*(S3+z*(S4+z*(S5+z*(S6+z*(S7+z*S8))))); if(iy==0) return x+v*(S1+z*r); else return x-((z*(half*y-v*r)-y)-v*S1); } openlibm-0.5.0/ld80/k_tanl.c000066400000000000000000000101421266752446200155200ustar00rootroot00000000000000/* From: @(#)k_tan.c 1.5 04/04/22 SMI */ /* * ==================================================== * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved. * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans. * * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/ld80/k_tanl.c,v 1.3 2008/02/18 15:39:52 bde Exp $"); /* * ld80 version of k_tan.c. See ../src/k_tan.c for most comments. */ #include #include "math_private.h" /* * Domain [-0.67434, 0.67434], range ~[-2.25e-22, 1.921e-22] * |tan(x)/x - t(x)| < 2**-71.9 * * See k_cosl.c for more details about the polynomial. */ #if defined(__amd64__) || defined(__i386__) /* Long double constants are slow on these arches, and broken on i386. */ static const volatile double T3hi = 0.33333333333333331, /* 0x15555555555555.0p-54 */ T3lo = 1.8350121769317163e-17, /* 0x15280000000000.0p-108 */ T5hi = 0.13333333333333336, /* 0x11111111111112.0p-55 */ T5lo = 1.3051083651294260e-17, /* 0x1e180000000000.0p-109 */ T7hi = 0.053968253968250494, /* 0x1ba1ba1ba1b827.0p-57 */ T7lo = 3.1509625637859973e-18, /* 0x1d100000000000.0p-111 */ pio4_hi = 0.78539816339744828, /* 0x1921fb54442d18.0p-53 */ pio4_lo = 3.0628711372715500e-17, /* 0x11a80000000000.0p-107 */ pio4lo_hi = -1.2541394031670831e-20, /* -0x1d9cceba3f91f2.0p-119 */ pio4lo_lo = 6.1493048227390915e-37; /* 0x1a280000000000.0p-173 */ #define T3 ((long double)T3hi + T3lo) #define T5 ((long double)T5hi + T5lo) #define T7 ((long double)T7hi + T7lo) #define pio4 ((long double)pio4_hi + pio4_lo) #define pio4lo ((long double)pio4lo_hi + pio4lo_lo) #else static const long double T3 = 0.333333333333333333180L, /* 0xaaaaaaaaaaaaaaa5.0p-65 */ T5 = 0.133333333333333372290L, /* 0x88888888888893c3.0p-66 */ T7 = 0.0539682539682504975744L, /* 0xdd0dd0dd0dc13ba2.0p-68 */ pio4 = 0.785398163397448309628L, /* 0xc90fdaa22168c235.0p-64 */ pio4lo = -1.25413940316708300586e-20L; /* -0xece675d1fc8f8cbb.0p-130 */ #endif static const double T9 = 0.021869488536312216, /* 0x1664f4882cc1c2.0p-58 */ T11 = 0.0088632355256619590, /* 0x1226e355c17612.0p-59 */ T13 = 0.0035921281113786528, /* 0x1d6d3d185d7ff8.0p-61 */ T15 = 0.0014558334756312418, /* 0x17da354aa3f96b.0p-62 */ T17 = 0.00059003538700862256, /* 0x13559358685b83.0p-63 */ T19 = 0.00023907843576635544, /* 0x1f56242026b5be.0p-65 */ T21 = 0.000097154625656538905, /* 0x1977efc26806f4.0p-66 */ T23 = 0.000038440165747303162, /* 0x14275a09b3ceac.0p-67 */ T25 = 0.000018082171885432524, /* 0x12f5e563e5487e.0p-68 */ T27 = 0.0000024196006108814377, /* 0x144c0d80cc6896.0p-71 */ T29 = 0.0000078293456938132840, /* 0x106b59141a6cb3.0p-69 */ T31 = -0.0000032609076735050182, /* -0x1b5abef3ba4b59.0p-71 */ T33 = 0.0000023261313142559411; /* 0x13835436c0c87f.0p-71 */ DLLEXPORT long double __kernel_tanl(long double x, long double y, int iy) { long double z, r, v, w, s; long double osign; int i; iy = (iy == 1 ? -1 : 1); /* XXX recover original interface */ osign = (x >= 0 ? 1.0 : -1.0); /* XXX slow, probably wrong for -0 */ if (fabsl(x) >= 0.67434) { if (x < 0) { x = -x; y = -y; } z = pio4 - x; w = pio4lo - y; x = z + w; y = 0.0; i = 1; } else i = 0; z = x * x; w = z * z; r = T5 + w * (T9 + w * (T13 + w * (T17 + w * (T21 + w * (T25 + w * (T29 + w * T33)))))); v = z * (T7 + w * (T11 + w * (T15 + w * (T19 + w * (T23 + w * (T27 + w * T31)))))); s = z * x; r = y + z * (s * (r + v) + y); r += T3 * s; w = x + r; if (i == 1) { v = (long double) iy; return osign * (v - 2.0 * (x - (w * w / (w + v) - r))); } if (iy == 1) return w; else { /* * if allow error up to 2 ulp, simply return * -1.0 / (x+r) here */ /* compute -1.0 / (x+r) accurately */ long double a, t; z = w; z = z + 0x1p32 - 0x1p32; v = r - (z - x); /* z+v = r+x */ t = a = -1.0 / w; /* a = -1.0/w */ t = t + 0x1p32 - 0x1p32; s = 1.0 + t * z; return t + a * (s + t * v); } } openlibm-0.5.0/ld80/s_asinhl.c000066400000000000000000000030451266752446200160540ustar00rootroot00000000000000/* @(#)s_asinh.c 5.1 93/09/24 */ /* * ==================================================== * 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. * ==================================================== */ /* asinhl(x) * Method : * Based on * asinhl(x) = signl(x) * logl [ |x| + sqrtl(x*x+1) ] * we have * asinhl(x) := x if 1+x*x=1, * := signl(x)*(logl(x)+ln2)) for large |x|, else * := signl(x)*logl(2|x|+1/(|x|+sqrtl(x*x+1))) if|x|>2, else * := signl(x)*log1pl(|x| + x^2/(1 + sqrtl(1+x^2))) */ #include #include "math_private.h" static const long double one = 1.000000000000000000000e+00L, /* 0x3FFF, 0x00000000, 0x00000000 */ ln2 = 6.931471805599453094287e-01L, /* 0x3FFE, 0xB17217F7, 0xD1CF79AC */ huge= 1.000000000000000000e+4900L; long double asinhl(long double x) { long double t,w; int32_t hx,ix; GET_LDOUBLE_EXP(hx,x); ix = hx&0x7fff; if(ix==0x7fff) return x+x; /* x is inf or NaN */ if(ix< 0x3fde) { /* |x|<2**-34 */ if(huge+x>one) return x; /* return x inexact except 0 */ } if(ix>0x4020) { /* |x| > 2**34 */ w = logl(fabsl(x))+ln2; } else if (ix>0x4000) { /* 2**34 > |x| > 2.0 */ t = fabsl(x); w = logl(2.0*t+one/(sqrtl(x*x+one)+t)); } else { /* 2.0 > |x| > 2**-28 */ t = x*x; w =log1pl(fabsl(x)+t/(one+sqrtl(one+t))); } if(hx&0x8000) return -w; else return w; } openlibm-0.5.0/ld80/s_ceill.c000066400000000000000000000034421266752446200156670ustar00rootroot00000000000000/* @(#)s_ceil.c 5.1 93/09/24 */ /* * ==================================================== * 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. * ==================================================== */ /* * ceill(x) * Return x rounded toward -inf to integral value * Method: * Bit twiddling. * Exception: * Inexact flag raised if x not equal to ceil(x). */ #include #include "math_private.h" static const long double huge = 1.0e4930L; long double ceill(long double x) { int32_t i1,jj0; u_int32_t i,j,se,i0,sx; GET_LDOUBLE_WORDS(se,i0,i1,x); sx = (se>>15)&1; jj0 = (se&0x7fff)-0x3fff; if(jj0<31) { if(jj0<0) { /* raise inexact if x != 0 */ if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */ if(sx) {se=0x8000;i0=0;i1=0;} else if((i0|i1)!=0) { se=0x3fff;i0=0;i1=0;} } } else { i = (0x7fffffff)>>jj0; if(((i0&i)|i1)==0) return x; /* x is integral */ if(huge+x>0.0) { /* raise inexact flag */ if(sx==0) { if (jj0>0 && (i0+(0x80000000>>jj0))>i0) i0+=0x80000000>>jj0; else { i = 0x7fffffff; ++se; } } i0 &= (~i); i1=0; } } } else if (jj0>62) { if(jj0==0x4000) return x+x; /* inf or NaN */ else return x; /* x is integral */ } else { i = ((u_int32_t)(0xffffffff))>>(jj0-31); if((i1&i)==0) return x; /* x is integral */ if(huge+x>0.0) { /* raise inexact flag */ if(sx==0) { if(jj0==31) i0+=1; else { j = i1 + (1<<(63-jj0)); if(j * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* double erf(double x) * double erfc(double x) * x * 2 |\ * erf(x) = --------- | exp(-t*t)dt * sqrt(pi) \| * 0 * * erfc(x) = 1-erf(x) * Note that * erf(-x) = -erf(x) * erfc(-x) = 2 - erfc(x) * * Method: * 1. For |x| in [0, 0.84375] * erf(x) = x + x*R(x^2) * erfc(x) = 1 - erf(x) if x in [-.84375,0.25] * = 0.5 + ((0.5-x)-x*R) if x in [0.25,0.84375] * Remark. The formula is derived by noting * erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....) * and that * 2/sqrt(pi) = 1.128379167095512573896158903121545171688 * is close to one. The interval is chosen because the fix * point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is * near 0.6174), and by some experiment, 0.84375 is chosen to * guarantee the error is less than one ulp for erf. * * 2. For |x| in [0.84375,1.25], let s = |x| - 1, and * c = 0.84506291151 rounded to single (24 bits) * erf(x) = sign(x) * (c + P1(s)/Q1(s)) * erfc(x) = (1-c) - P1(s)/Q1(s) if x > 0 * 1+(c+P1(s)/Q1(s)) if x < 0 * Remark: here we use the taylor series expansion at x=1. * erf(1+s) = erf(1) + s*Poly(s) * = 0.845.. + P1(s)/Q1(s) * Note that |P1/Q1|< 0.078 for x in [0.84375,1.25] * * 3. For x in [1.25,1/0.35(~2.857143)], * erfc(x) = (1/x)*exp(-x*x-0.5625+R1(z)/S1(z)) * z=1/x^2 * erf(x) = 1 - erfc(x) * * 4. For x in [1/0.35,107] * erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0 * = 2.0 - (1/x)*exp(-x*x-0.5625+R2(z)/S2(z)) * if -6.666 x >= 107 * erf(x) = sign(x) *(1 - tiny) (raise inexact) * erfc(x) = tiny*tiny (raise underflow) if x > 0 * = 2 - tiny if x<0 * * 7. Special case: * erf(0) = 0, erf(inf) = 1, erf(-inf) = -1, * erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2, * erfc/erf(NaN) is NaN */ #include #include "math_private.h" static const long double tiny = 1e-4931L, half = 0.5L, one = 1.0L, two = 2.0L, /* c = (float)0.84506291151 */ erx = 0.845062911510467529296875L, /* * Coefficients for approximation to erf on [0,0.84375] */ /* 2/sqrt(pi) - 1 */ efx = 1.2837916709551257389615890312154517168810E-1L, /* 8 * (2/sqrt(pi) - 1) */ efx8 = 1.0270333367641005911692712249723613735048E0L, pp[6] = { 1.122751350964552113068262337278335028553E6L, -2.808533301997696164408397079650699163276E6L, -3.314325479115357458197119660818768924100E5L, -6.848684465326256109712135497895525446398E4L, -2.657817695110739185591505062971929859314E3L, -1.655310302737837556654146291646499062882E2L, }, qq[6] = { 8.745588372054466262548908189000448124232E6L, 3.746038264792471129367533128637019611485E6L, 7.066358783162407559861156173539693900031E5L, 7.448928604824620999413120955705448117056E4L, 4.511583986730994111992253980546131408924E3L, 1.368902937933296323345610240009071254014E2L, /* 1.000000000000000000000000000000000000000E0 */ }, /* * Coefficients for approximation to erf in [0.84375,1.25] */ /* erf(x+1) = 0.845062911510467529296875 + pa(x)/qa(x) -0.15625 <= x <= +.25 Peak relative error 8.5e-22 */ pa[8] = { -1.076952146179812072156734957705102256059E0L, 1.884814957770385593365179835059971587220E2L, -5.339153975012804282890066622962070115606E1L, 4.435910679869176625928504532109635632618E1L, 1.683219516032328828278557309642929135179E1L, -2.360236618396952560064259585299045804293E0L, 1.852230047861891953244413872297940938041E0L, 9.394994446747752308256773044667843200719E-2L, }, qa[7] = { 4.559263722294508998149925774781887811255E2L, 3.289248982200800575749795055149780689738E2L, 2.846070965875643009598627918383314457912E2L, 1.398715859064535039433275722017479994465E2L, 6.060190733759793706299079050985358190726E1L, 2.078695677795422351040502569964299664233E1L, 4.641271134150895940966798357442234498546E0L, /* 1.000000000000000000000000000000000000000E0 */ }, /* * Coefficients for approximation to erfc in [1.25,1/0.35] */ /* erfc(1/x) = x exp (-1/x^2 - 0.5625 + ra(x^2)/sa(x^2)) 1/2.85711669921875 < 1/x < 1/1.25 Peak relative error 3.1e-21 */ ra[] = { 1.363566591833846324191000679620738857234E-1L, 1.018203167219873573808450274314658434507E1L, 1.862359362334248675526472871224778045594E2L, 1.411622588180721285284945138667933330348E3L, 5.088538459741511988784440103218342840478E3L, 8.928251553922176506858267311750789273656E3L, 7.264436000148052545243018622742770549982E3L, 2.387492459664548651671894725748959751119E3L, 2.220916652813908085449221282808458466556E2L, }, sa[] = { -1.382234625202480685182526402169222331847E1L, -3.315638835627950255832519203687435946482E2L, -2.949124863912936259747237164260785326692E3L, -1.246622099070875940506391433635999693661E4L, -2.673079795851665428695842853070996219632E4L, -2.880269786660559337358397106518918220991E4L, -1.450600228493968044773354186390390823713E4L, -2.874539731125893533960680525192064277816E3L, -1.402241261419067750237395034116942296027E2L, /* 1.000000000000000000000000000000000000000E0 */ }, /* * Coefficients for approximation to erfc in [1/.35,107] */ /* erfc(1/x) = x exp (-1/x^2 - 0.5625 + rb(x^2)/sb(x^2)) 1/6.6666259765625 < 1/x < 1/2.85711669921875 Peak relative error 4.2e-22 */ rb[] = { -4.869587348270494309550558460786501252369E-5L, -4.030199390527997378549161722412466959403E-3L, -9.434425866377037610206443566288917589122E-2L, -9.319032754357658601200655161585539404155E-1L, -4.273788174307459947350256581445442062291E0L, -8.842289940696150508373541814064198259278E0L, -7.069215249419887403187988144752613025255E0L, -1.401228723639514787920274427443330704764E0L, }, sb[] = { 4.936254964107175160157544545879293019085E-3L, 1.583457624037795744377163924895349412015E-1L, 1.850647991850328356622940552450636420484E0L, 9.927611557279019463768050710008450625415E0L, 2.531667257649436709617165336779212114570E1L, 2.869752886406743386458304052862814690045E1L, 1.182059497870819562441683560749192539345E1L, /* 1.000000000000000000000000000000000000000E0 */ }, /* erfc(1/x) = x exp (-1/x^2 - 0.5625 + rc(x^2)/sc(x^2)) 1/107 <= 1/x <= 1/6.6666259765625 Peak relative error 1.1e-21 */ rc[] = { -8.299617545269701963973537248996670806850E-5L, -6.243845685115818513578933902532056244108E-3L, -1.141667210620380223113693474478394397230E-1L, -7.521343797212024245375240432734425789409E-1L, -1.765321928311155824664963633786967602934E0L, -1.029403473103215800456761180695263439188E0L, }, sc[] = { 8.413244363014929493035952542677768808601E-3L, 2.065114333816877479753334599639158060979E-1L, 1.639064941530797583766364412782135680148E0L, 4.936788463787115555582319302981666347450E0L, 5.005177727208955487404729933261347679090E0L, /* 1.000000000000000000000000000000000000000E0 */ }; long double erfl(long double x) { long double R, S, P, Q, s, y, z, r; int32_t ix, i; u_int32_t se, i0, i1; GET_LDOUBLE_WORDS (se, i0, i1, x); ix = se & 0x7fff; if (ix >= 0x7fff) { /* erf(nan)=nan */ i = ((se & 0xffff) >> 15) << 1; return (long double) (1 - i) + one / x; /* erf(+-inf)=+-1 */ } ix = (ix << 16) | (i0 >> 16); if (ix < 0x3ffed800) /* |x|<0.84375 */ { if (ix < 0x3fde8000) /* |x|<2**-33 */ { if (ix < 0x00080000) return 0.125 * (8.0 * x + efx8 * x); /*avoid underflow */ return x + efx * x; } z = x * x; r = pp[0] + z * (pp[1] + z * (pp[2] + z * (pp[3] + z * (pp[4] + z * pp[5])))); s = qq[0] + z * (qq[1] + z * (qq[2] + z * (qq[3] + z * (qq[4] + z * (qq[5] + z))))); y = r / s; return x + x * y; } if (ix < 0x3fffa000) /* 1.25 */ { /* 0.84375 <= |x| < 1.25 */ s = fabsl (x) - one; P = pa[0] + s * (pa[1] + s * (pa[2] + s * (pa[3] + s * (pa[4] + s * (pa[5] + s * (pa[6] + s * pa[7])))))); Q = qa[0] + s * (qa[1] + s * (qa[2] + s * (qa[3] + s * (qa[4] + s * (qa[5] + s * (qa[6] + s)))))); if ((se & 0x8000) == 0) return erx + P / Q; else return -erx - P / Q; } if (ix >= 0x4001d555) /* 6.6666259765625 */ { /* inf>|x|>=6.666 */ if ((se & 0x8000) == 0) return one - tiny; else return tiny - one; } x = fabsl (x); s = one / (x * x); if (ix < 0x4000b6db) /* 2.85711669921875 */ { R = ra[0] + s * (ra[1] + s * (ra[2] + s * (ra[3] + s * (ra[4] + s * (ra[5] + s * (ra[6] + s * (ra[7] + s * ra[8]))))))); S = sa[0] + s * (sa[1] + s * (sa[2] + s * (sa[3] + s * (sa[4] + s * (sa[5] + s * (sa[6] + s * (sa[7] + s * (sa[8] + s)))))))); } else { /* |x| >= 1/0.35 */ R = rb[0] + s * (rb[1] + s * (rb[2] + s * (rb[3] + s * (rb[4] + s * (rb[5] + s * (rb[6] + s * rb[7])))))); S = sb[0] + s * (sb[1] + s * (sb[2] + s * (sb[3] + s * (sb[4] + s * (sb[5] + s * (sb[6] + s)))))); } z = x; GET_LDOUBLE_WORDS (i, i0, i1, z); i1 = 0; SET_LDOUBLE_WORDS (z, i, i0, i1); r = expl (-z * z - 0.5625) * expl ((z - x) * (z + x) + R / S); if ((se & 0x8000) == 0) return one - r / x; else return r / x - one; } long double erfcl(long double x) { int32_t hx, ix; long double R, S, P, Q, s, y, z, r; u_int32_t se, i0, i1; GET_LDOUBLE_WORDS (se, i0, i1, x); ix = se & 0x7fff; if (ix >= 0x7fff) { /* erfc(nan)=nan */ /* erfc(+-inf)=0,2 */ return (long double) (((se & 0xffff) >> 15) << 1) + one / x; } ix = (ix << 16) | (i0 >> 16); if (ix < 0x3ffed800) /* |x|<0.84375 */ { if (ix < 0x3fbe0000) /* |x|<2**-65 */ return one - x; z = x * x; r = pp[0] + z * (pp[1] + z * (pp[2] + z * (pp[3] + z * (pp[4] + z * pp[5])))); s = qq[0] + z * (qq[1] + z * (qq[2] + z * (qq[3] + z * (qq[4] + z * (qq[5] + z))))); y = r / s; if (ix < 0x3ffd8000) /* x<1/4 */ { return one - (x + x * y); } else { r = x * y; r += (x - half); return half - r; } } if (ix < 0x3fffa000) /* 1.25 */ { /* 0.84375 <= |x| < 1.25 */ s = fabsl (x) - one; P = pa[0] + s * (pa[1] + s * (pa[2] + s * (pa[3] + s * (pa[4] + s * (pa[5] + s * (pa[6] + s * pa[7])))))); Q = qa[0] + s * (qa[1] + s * (qa[2] + s * (qa[3] + s * (qa[4] + s * (qa[5] + s * (qa[6] + s)))))); if ((se & 0x8000) == 0) { z = one - erx; return z - P / Q; } else { z = erx + P / Q; return one + z; } } if (ix < 0x4005d600) /* 107 */ { /* |x|<107 */ x = fabsl (x); s = one / (x * x); if (ix < 0x4000b6db) /* 2.85711669921875 */ { /* |x| < 1/.35 ~ 2.857143 */ R = ra[0] + s * (ra[1] + s * (ra[2] + s * (ra[3] + s * (ra[4] + s * (ra[5] + s * (ra[6] + s * (ra[7] + s * ra[8]))))))); S = sa[0] + s * (sa[1] + s * (sa[2] + s * (sa[3] + s * (sa[4] + s * (sa[5] + s * (sa[6] + s * (sa[7] + s * (sa[8] + s)))))))); } else if (ix < 0x4001d555) /* 6.6666259765625 */ { /* 6.666 > |x| >= 1/.35 ~ 2.857143 */ R = rb[0] + s * (rb[1] + s * (rb[2] + s * (rb[3] + s * (rb[4] + s * (rb[5] + s * (rb[6] + s * rb[7])))))); S = sb[0] + s * (sb[1] + s * (sb[2] + s * (sb[3] + s * (sb[4] + s * (sb[5] + s * (sb[6] + s)))))); } else { /* |x| >= 6.666 */ if (se & 0x8000) return two - tiny; /* x < -6.666 */ R = rc[0] + s * (rc[1] + s * (rc[2] + s * (rc[3] + s * (rc[4] + s * rc[5])))); S = sc[0] + s * (sc[1] + s * (sc[2] + s * (sc[3] + s * (sc[4] + s)))); } z = x; GET_LDOUBLE_WORDS (hx, i0, i1, z); i1 = 0; i0 &= 0xffffff00; SET_LDOUBLE_WORDS (z, hx, i0, i1); r = expl (-z * z - 0.5625) * expl ((z - x) * (z + x) + R / S); if ((se & 0x8000) == 0) return r / x; else return two - r / x; } else { if ((se & 0x8000) == 0) return tiny * tiny; else return two - tiny; } } openlibm-0.5.0/ld80/s_exp2l.c000066400000000000000000000254171266752446200156370ustar00rootroot00000000000000/*- * Copyright (c) 2005-2008 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/ld80/s_exp2l.c,v 1.3 2008/02/13 10:44:44 bde Exp $"); #include #include #include "bsd_cdefs.h" #include "amd64/bsd_ieeefp.h" #include #include "math_private.h" #define TBLBITS 7 #define TBLSIZE (1 << TBLBITS) #define BIAS (LDBL_MAX_EXP - 1) #define EXPMASK (BIAS + LDBL_MAX_EXP) static const long double huge = 0x1p10000L; #if 0 /* XXX Prevent gcc from erroneously constant folding this. */ static const long double twom10000 = 0x1p-10000L; #else static volatile long double twom10000 = 0x1p-10000L; #endif static const double redux = 0x1.8p63 / TBLSIZE, P1 = 0x1.62e42fefa39efp-1, P2 = 0x1.ebfbdff82c58fp-3, P3 = 0x1.c6b08d7049fap-5, P4 = 0x1.3b2ab6fba4da5p-7, P5 = 0x1.5d8804780a736p-10, P6 = 0x1.430918835e33dp-13; static const double tbl[TBLSIZE * 2] = { 0x1.6a09e667f3bcdp-1, -0x1.bdd3413b2648p-55, 0x1.6c012750bdabfp-1, -0x1.2895667ff0cp-57, 0x1.6dfb23c651a2fp-1, -0x1.bbe3a683c88p-58, 0x1.6ff7df9519484p-1, -0x1.83c0f25860fp-56, 0x1.71f75e8ec5f74p-1, -0x1.16e4786887bp-56, 0x1.73f9a48a58174p-1, -0x1.0a8d96c65d5p-55, 0x1.75feb564267c9p-1, -0x1.0245957316ep-55, 0x1.780694fde5d3fp-1, 0x1.866b80a0216p-55, 0x1.7a11473eb0187p-1, -0x1.41577ee0499p-56, 0x1.7c1ed0130c132p-1, 0x1.f124cd1164ep-55, 0x1.7e2f336cf4e62p-1, 0x1.05d02ba157ap-57, 0x1.80427543e1a12p-1, -0x1.27c86626d97p-55, 0x1.82589994cce13p-1, -0x1.d4c1dd41533p-55, 0x1.8471a4623c7adp-1, -0x1.8d684a341cep-56, 0x1.868d99b4492edp-1, -0x1.fc6f89bd4f68p-55, 0x1.88ac7d98a6699p-1, 0x1.994c2f37cb5p-55, 0x1.8ace5422aa0dbp-1, 0x1.6e9f156864bp-55, 0x1.8cf3216b5448cp-1, -0x1.0d55e32e9e4p-57, 0x1.8f1ae99157736p-1, 0x1.5cc13a2e397p-56, 0x1.9145b0b91ffc6p-1, -0x1.dd6792e5825p-55, 0x1.93737b0cdc5e5p-1, -0x1.75fc781b58p-58, 0x1.95a44cbc8520fp-1, -0x1.64b7c96a5fp-57, 0x1.97d829fde4e5p-1, -0x1.d185b7c1b86p-55, 0x1.9a0f170ca07bap-1, -0x1.173bd91cee6p-55, 0x1.9c49182a3f09p-1, 0x1.c7c46b071f2p-57, 0x1.9e86319e32323p-1, 0x1.824ca78e64cp-57, 0x1.a0c667b5de565p-1, -0x1.359495d1cd5p-55, 0x1.a309bec4a2d33p-1, 0x1.6305c7ddc368p-55, 0x1.a5503b23e255dp-1, -0x1.d2f6edb8d42p-55, 0x1.a799e1330b358p-1, 0x1.bcb7ecac564p-55, 0x1.a9e6b5579fdbfp-1, 0x1.0fac90ef7fdp-55, 0x1.ac36bbfd3f37ap-1, -0x1.f9234cae76dp-56, 0x1.ae89f995ad3adp-1, 0x1.7a1cd345dcc8p-55, 0x1.b0e07298db666p-1, -0x1.bdef54c80e4p-55, 0x1.b33a2b84f15fbp-1, -0x1.2805e3084d8p-58, 0x1.b59728de5593ap-1, -0x1.c71dfbbba6ep-55, 0x1.b7f76f2fb5e47p-1, -0x1.5584f7e54acp-57, 0x1.ba5b030a1064ap-1, -0x1.efcd30e5429p-55, 0x1.bcc1e904bc1d2p-1, 0x1.23dd07a2d9fp-56, 0x1.bf2c25bd71e09p-1, -0x1.efdca3f6b9c8p-55, 0x1.c199bdd85529cp-1, 0x1.11065895049p-56, 0x1.c40ab5fffd07ap-1, 0x1.b4537e083c6p-55, 0x1.c67f12e57d14bp-1, 0x1.2884dff483c8p-55, 0x1.c8f6d9406e7b5p-1, 0x1.1acbc48805cp-57, 0x1.cb720dcef9069p-1, 0x1.503cbd1e94ap-57, 0x1.cdf0b555dc3fap-1, -0x1.dd83b53829dp-56, 0x1.d072d4a07897cp-1, -0x1.cbc3743797a8p-55, 0x1.d2f87080d89f2p-1, -0x1.d487b719d858p-55, 0x1.d5818dcfba487p-1, 0x1.2ed02d75b37p-56, 0x1.d80e316c98398p-1, -0x1.11ec18bedep-55, 0x1.da9e603db3285p-1, 0x1.c2300696db5p-55, 0x1.dd321f301b46p-1, 0x1.2da5778f019p-55, 0x1.dfc97337b9b5fp-1, -0x1.1a5cd4f184b8p-55, 0x1.e264614f5a129p-1, -0x1.7b627817a148p-55, 0x1.e502ee78b3ff6p-1, 0x1.39e8980a9cdp-56, 0x1.e7a51fbc74c83p-1, 0x1.2d522ca0c8ep-55, 0x1.ea4afa2a490dap-1, -0x1.e9c23179c288p-55, 0x1.ecf482d8e67f1p-1, -0x1.c93f3b411ad8p-55, 0x1.efa1bee615a27p-1, 0x1.dc7f486a4b68p-55, 0x1.f252b376bba97p-1, 0x1.3a1a5bf0d8e8p-55, 0x1.f50765b6e454p-1, 0x1.9d3e12dd8a18p-55, 0x1.f7bfdad9cbe14p-1, -0x1.dbb12d00635p-55, 0x1.fa7c1819e90d8p-1, 0x1.74853f3a593p-56, 0x1.fd3c22b8f71f1p-1, 0x1.2eb74966578p-58, 0x1p+0, 0x0p+0, 0x1.0163da9fb3335p+0, 0x1.b61299ab8cd8p-54, 0x1.02c9a3e778061p+0, -0x1.19083535b08p-56, 0x1.04315e86e7f85p+0, -0x1.0a31c1977c98p-54, 0x1.059b0d3158574p+0, 0x1.d73e2a475b4p-55, 0x1.0706b29ddf6dep+0, -0x1.c91dfe2b13cp-55, 0x1.0874518759bc8p+0, 0x1.186be4bb284p-57, 0x1.09e3ecac6f383p+0, 0x1.14878183161p-54, 0x1.0b5586cf9890fp+0, 0x1.8a62e4adc61p-54, 0x1.0cc922b7247f7p+0, 0x1.01edc16e24f8p-54, 0x1.0e3ec32d3d1a2p+0, 0x1.03a1727c58p-59, 0x1.0fb66affed31bp+0, -0x1.b9bedc44ebcp-57, 0x1.11301d0125b51p+0, -0x1.6c51039449bp-54, 0x1.12abdc06c31ccp+0, -0x1.1b514b36ca8p-58, 0x1.1429aaea92dep+0, -0x1.32fbf9af1368p-54, 0x1.15a98c8a58e51p+0, 0x1.2406ab9eeabp-55, 0x1.172b83c7d517bp+0, -0x1.19041b9d78ap-55, 0x1.18af9388c8deap+0, -0x1.11023d1970f8p-54, 0x1.1a35beb6fcb75p+0, 0x1.e5b4c7b4969p-55, 0x1.1bbe084045cd4p+0, -0x1.95386352ef6p-54, 0x1.1d4873168b9aap+0, 0x1.e016e00a264p-54, 0x1.1ed5022fcd91dp+0, -0x1.1df98027bb78p-54, 0x1.2063b88628cd6p+0, 0x1.dc775814a85p-55, 0x1.21f49917ddc96p+0, 0x1.2a97e9494a6p-55, 0x1.2387a6e756238p+0, 0x1.9b07eb6c7058p-54, 0x1.251ce4fb2a63fp+0, 0x1.ac155bef4f5p-55, 0x1.26b4565e27cddp+0, 0x1.2bd339940eap-55, 0x1.284dfe1f56381p+0, -0x1.a4c3a8c3f0d8p-54, 0x1.29e9df51fdee1p+0, 0x1.612e8afad12p-55, 0x1.2b87fd0dad99p+0, -0x1.10adcd6382p-59, 0x1.2d285a6e4030bp+0, 0x1.0024754db42p-54, 0x1.2ecafa93e2f56p+0, 0x1.1ca0f45d524p-56, 0x1.306fe0a31b715p+0, 0x1.6f46ad23183p-55, 0x1.32170fc4cd831p+0, 0x1.a9ce78e1804p-55, 0x1.33c08b26416ffp+0, 0x1.327218436598p-54, 0x1.356c55f929ff1p+0, -0x1.b5cee5c4e46p-55, 0x1.371a7373aa9cbp+0, -0x1.63aeabf42ebp-54, 0x1.38cae6d05d866p+0, -0x1.e958d3c99048p-54, 0x1.3a7db34e59ff7p+0, -0x1.5e436d661f6p-56, 0x1.3c32dc313a8e5p+0, -0x1.efff8375d2ap-54, 0x1.3dea64c123422p+0, 0x1.ada0911f09fp-55, 0x1.3fa4504ac801cp+0, -0x1.7d023f956fap-54, 0x1.4160a21f72e2ap+0, -0x1.ef3691c309p-58, 0x1.431f5d950a897p+0, -0x1.1c7dde35f7ap-55, 0x1.44e086061892dp+0, 0x1.89b7a04ef8p-59, 0x1.46a41ed1d0057p+0, 0x1.c944bd1648a8p-54, 0x1.486a2b5c13cdp+0, 0x1.3c1a3b69062p-56, 0x1.4a32af0d7d3dep+0, 0x1.9cb62f3d1be8p-54, 0x1.4bfdad5362a27p+0, 0x1.d4397afec42p-56, 0x1.4dcb299fddd0dp+0, 0x1.8ecdbbc6a78p-54, 0x1.4f9b2769d2ca7p+0, -0x1.4b309d25958p-54, 0x1.516daa2cf6642p+0, -0x1.f768569bd94p-55, 0x1.5342b569d4f82p+0, -0x1.07abe1db13dp-55, 0x1.551a4ca5d920fp+0, -0x1.d689cefede6p-55, 0x1.56f4736b527dap+0, 0x1.9bb2c011d938p-54, 0x1.58d12d497c7fdp+0, 0x1.295e15b9a1ep-55, 0x1.5ab07dd485429p+0, 0x1.6324c0546478p-54, 0x1.5c9268a5946b7p+0, 0x1.c4b1b81698p-60, 0x1.5e76f15ad2148p+0, 0x1.ba6f93080e68p-54, 0x1.605e1b976dc09p+0, -0x1.3e2429b56de8p-54, 0x1.6247eb03a5585p+0, -0x1.383c17e40b48p-54, 0x1.6434634ccc32p+0, -0x1.c483c759d89p-55, 0x1.6623882552225p+0, -0x1.bb60987591cp-54, 0x1.68155d44ca973p+0, 0x1.038ae44f74p-57, }; /* * exp2l(x): compute the base 2 exponential of x * * Accuracy: Peak error < 0.511 ulp. * * Method: (equally-spaced tables) * * Reduce x: * x = 2**k + y, for integer k and |y| <= 1/2. * Thus we have exp2l(x) = 2**k * exp2(y). * * Reduce y: * y = i/TBLSIZE + z for integer i near y * TBLSIZE. * Thus we have exp2(y) = exp2(i/TBLSIZE) * exp2(z), * with |z| <= 2**-(TBLBITS+1). * * We compute exp2(i/TBLSIZE) via table lookup and exp2(z) via a * degree-6 minimax polynomial with maximum error under 2**-69. * The table entries each have 104 bits of accuracy, encoded as * a pair of double precision values. */ DLLEXPORT long double exp2l(long double x) { union IEEEl2bits u, v; long double r, twopk, twopkp10000, z; uint32_t hx, ix, i0; int k; /* Filter out exceptional cases. */ u.e = x; hx = u.xbits.expsign; ix = hx & EXPMASK; if (ix >= BIAS + 14) { /* |x| >= 16384 or x is NaN */ if (ix == BIAS + LDBL_MAX_EXP) { if (u.xbits.man != 1ULL << 63 || (hx & 0x8000) == 0) return (x + x); /* x is +Inf or NaN */ else return (0.0); /* x is -Inf */ } if (x >= 16384) return (huge * huge); /* overflow */ if (x <= -16446) return (twom10000 * twom10000); /* underflow */ } else if (ix <= BIAS - 66) { /* |x| < 0x1p-66 */ return (1.0 + x); } #ifdef __i386__ /* * The default precision on i386 is 53 bits, so long doubles are * broken. Call exp2() to get an accurate (double precision) result. */ if (__fpgetprec() != FP_PE) return (exp2(x)); #endif /* * Reduce x, computing z, i0, and k. The low bits of x + redux * contain the 16-bit integer part of the exponent (k) followed by * TBLBITS fractional bits (i0). We use bit tricks to extract these * as integers, then set z to the remainder. * * Example: Suppose x is 0xabc.123456p0 and TBLBITS is 8. * Then the low-order word of x + redux is 0x000abc12, * We split this into k = 0xabc and i0 = 0x12 (adjusted to * index into the table), then we compute z = 0x0.003456p0. * * XXX If the exponent is negative, the computation of k depends on * '>>' doing sign extension. */ u.e = x + redux; i0 = u.bits.manl + TBLSIZE / 2; k = (int)i0 >> TBLBITS; i0 = (i0 & (TBLSIZE - 1)) << 1; u.e -= redux; z = x - u.e; v.xbits.man = 1ULL << 63; if (k >= LDBL_MIN_EXP) { v.xbits.expsign = LDBL_MAX_EXP - 1 + k; twopk = v.e; } else { v.xbits.expsign = LDBL_MAX_EXP - 1 + k + 10000; twopkp10000 = v.e; } /* Compute r = exp2l(y) = exp2lt[i0] * p(z). */ long double t_hi = tbl[i0]; long double t_lo = tbl[i0 + 1]; /* XXX This gives > 1 ulp errors outside of FE_TONEAREST mode */ r = t_lo + (t_hi + t_lo) * z * (P1 + z * (P2 + z * (P3 + z * (P4 + z * (P5 + z * P6))))) + t_hi; /* Scale by 2**k. */ if (k >= LDBL_MIN_EXP) { if (k == LDBL_MAX_EXP) return (r * 2.0 * 0x1p16383L); return (r * twopk); } else { return (r * twopkp10000 * twom10000); } } openlibm-0.5.0/ld80/s_expm1l.c000066400000000000000000000070241266752446200160050ustar00rootroot00000000000000/* $OpenBSD: s_expm1l.c,v 1.2 2011/07/20 21:02:51 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* expm1l.c * * Exponential function, minus 1 * Long double precision * * * SYNOPSIS: * * long double x, y, expm1l(); * * y = expm1l( x ); * * * * DESCRIPTION: * * Returns e (2.71828...) raised to the x power, minus 1. * * Range reduction is accomplished by separating the argument * into an integer k and fraction f such that * * x k f * e = 2 e. * * An expansion x + .5 x^2 + x^3 R(x) approximates exp(f) - 1 * in the basic range [-0.5 ln 2, 0.5 ln 2]. * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE -45,+MAXLOG 200,000 1.2e-19 2.5e-20 * * ERROR MESSAGES: * * message condition value returned * expm1l overflow x > MAXLOG MAXNUM * */ #include static const long double MAXLOGL = 1.1356523406294143949492E4L; /* exp(x) - 1 = x + 0.5 x^2 + x^3 P(x)/Q(x) -.5 ln 2 < x < .5 ln 2 Theoretical peak relative error = 3.4e-22 */ static const long double P0 = -1.586135578666346600772998894928250240826E4L, P1 = 2.642771505685952966904660652518429479531E3L, P2 = -3.423199068835684263987132888286791620673E2L, P3 = 1.800826371455042224581246202420972737840E1L, P4 = -5.238523121205561042771939008061958820811E-1L, Q0 = -9.516813471998079611319047060563358064497E4L, Q1 = 3.964866271411091674556850458227710004570E4L, Q2 = -7.207678383830091850230366618190187434796E3L, Q3 = 7.206038318724600171970199625081491823079E2L, Q4 = -4.002027679107076077238836622982900945173E1L, /* Q5 = 1.000000000000000000000000000000000000000E0 */ /* C1 + C2 = ln 2 */ C1 = 6.93145751953125E-1L, C2 = 1.428606820309417232121458176568075500134E-6L, /* ln 2^-65 */ minarg = -4.5054566736396445112120088E1L; static const long double huge = 0x1p10000L; long double expm1l(long double x) { long double px, qx, xx; int k; /* Overflow. */ if (x > MAXLOGL) return (huge*huge); /* overflow */ if (x == 0.0) return x; /* Minimum value. */ if (x < minarg) return -1.0L; xx = C1 + C2; /* Express x = ln 2 (k + remainder), remainder not exceeding 1/2. */ px = floorl (0.5 + x / xx); k = px; /* remainder times ln 2 */ x -= px * C1; x -= px * C2; /* Approximate exp(remainder ln 2). */ px = (((( P4 * x + P3) * x + P2) * x + P1) * x + P0) * x; qx = (((( x + Q4) * x + Q3) * x + Q2) * x + Q1) * x + Q0; xx = x * x; qx = x + (0.5 * xx + xx * px / qx); /* exp(x) = exp(k ln 2) exp(remainder ln 2) = 2^k exp(remainder ln 2). We have qx = exp(remainder ln 2) - 1, so exp(x) - 1 = 2^k (qx + 1) - 1 = 2^k qx + 2^k - 1. */ px = ldexpl(1.0L, k); x = px * qx + (px - 1.0); return x; } openlibm-0.5.0/ld80/s_floorl.c000066400000000000000000000034041266752446200160720ustar00rootroot00000000000000/* @(#)s_floor.c 5.1 93/09/24 */ /* * ==================================================== * 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. * ==================================================== */ /* * floorl(x) * Return x rounded toward -inf to integral value * Method: * Bit twiddling. * Exception: * Inexact flag raised if x not equal to floor(x). */ #include #include "math_private.h" static const long double huge = 1.0e4930L; long double floorl(long double x) { int32_t i1,jj0; u_int32_t i,j,se,i0,sx; GET_LDOUBLE_WORDS(se,i0,i1,x); sx = (se>>15)&1; jj0 = (se&0x7fff)-0x3fff; if(jj0<31) { if(jj0<0) { /* raise inexact if x != 0 */ if(huge+x>0.0) { if(sx==0) return 0.0L; else if(((se&0x7fff)|i0|i1)!=0) return -1.0L; } } else { i = (0x7fffffff)>>jj0; if(((i0&i)|i1)==0) return x; /* x is integral */ if(huge+x>0.0) { /* raise inexact flag */ if(sx) { if (jj0>0 && (i0+(0x80000000>>jj0))>i0) i0 += (0x80000000)>>jj0; else { i = 0x7fffffff; ++se; } } i0 &= (~i); i1=0; } } } else if (jj0>62) { if(jj0==0x4000) return x+x; /* inf or NaN */ else return x; /* x is integral */ } else { i = ((u_int32_t)(0xffffffff))>>(jj0-31); if((i1&i)==0) return x; /* x is integral */ if(huge+x>0.0) { /* raise inexact flag */ if(sx) { if(jj0==31) i0+=1; else { j = i1+(1<<(63-jj0)); if(j * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* log1pl.c * * Relative error logarithm * Natural logarithm of 1+x, long double precision * * * * SYNOPSIS: * * long double x, y, log1pl(); * * y = log1pl( x ); * * * * DESCRIPTION: * * Returns the base e (2.718...) logarithm of 1+x. * * The argument 1+x is separated into its exponent and fractional * parts. If the exponent is between -1 and +1, the logarithm * of the fraction is approximated by * * log(1+x) = x - 0.5 x^2 + x^3 P(x)/Q(x). * * Otherwise, setting z = 2(x-1)/x+1), * * log(x) = z + z^3 P(z)/Q(z). * * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE -1.0, 9.0 100000 8.2e-20 2.5e-20 * * ERROR MESSAGES: * * log singularity: x-1 = 0; returns -INFINITY * log domain: x-1 < 0; returns NAN */ #include #include "math_private.h" /* Coefficients for log(1+x) = x - x^2 / 2 + x^3 P(x)/Q(x) * 1/sqrt(2) <= x < sqrt(2) * Theoretical peak relative error = 2.32e-20 */ static long double P[] = { 4.5270000862445199635215E-5L, 4.9854102823193375972212E-1L, 6.5787325942061044846969E0L, 2.9911919328553073277375E1L, 6.0949667980987787057556E1L, 5.7112963590585538103336E1L, 2.0039553499201281259648E1L, }; static long double Q[] = { /* 1.0000000000000000000000E0,*/ 1.5062909083469192043167E1L, 8.3047565967967209469434E1L, 2.2176239823732856465394E2L, 3.0909872225312059774938E2L, 2.1642788614495947685003E2L, 6.0118660497603843919306E1L, }; /* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2), * where z = 2(x-1)/(x+1) * 1/sqrt(2) <= x < sqrt(2) * Theoretical peak relative error = 6.16e-22 */ static long double R[4] = { 1.9757429581415468984296E-3L, -7.1990767473014147232598E-1L, 1.0777257190312272158094E1L, -3.5717684488096787370998E1L, }; static long double S[4] = { /* 1.00000000000000000000E0L,*/ -2.6201045551331104417768E1L, 1.9361891836232102174846E2L, -4.2861221385716144629696E2L, }; static const long double C1 = 6.9314575195312500000000E-1L; static const long double C2 = 1.4286068203094172321215E-6L; #define SQRTH 0.70710678118654752440L long double log1pl(long double xm1) { long double x, y, z; int e; if( isnan(xm1) ) return(xm1); if( xm1 == INFINITY ) return(xm1); if(xm1 == 0.0) return(xm1); x = xm1 + 1.0L; /* Test for domain errors. */ if( x <= 0.0L ) { if( x == 0.0L ) return( -INFINITY ); else return( NAN ); } /* Separate mantissa from exponent. Use frexp so that denormal numbers will be handled properly. */ x = frexpl( x, &e ); /* logarithm using log(x) = z + z^3 P(z)/Q(z), where z = 2(x-1)/x+1) */ if( (e > 2) || (e < -2) ) { if( x < SQRTH ) { /* 2( 2x-1 )/( 2x+1 ) */ e -= 1; z = x - 0.5L; y = 0.5L * z + 0.5L; } else { /* 2 (x-1)/(x+1) */ z = x - 0.5L; z -= 0.5L; y = 0.5L * x + 0.5L; } x = z / y; z = x*x; z = x * ( z * __polevll( z, R, 3 ) / __p1evll( z, S, 3 ) ); z = z + e * C2; z = z + x; z = z + e * C1; return( z ); } /* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */ if( x < SQRTH ) { e -= 1; if (e != 0) x = 2.0 * x - 1.0L; else x = xm1; } else { if (e != 0) x = x - 1.0L; else x = xm1; } z = x*x; y = x * ( z * __polevll( x, P, 6 ) / __p1evll( x, Q, 6 ) ); y = y + e * C2; z = y - 0.5 * z; z = z + x; z = z + e * C1; return( z ); } openlibm-0.5.0/ld80/s_modfl.c000066400000000000000000000034411266752446200156770ustar00rootroot00000000000000/* @(#)s_modf.c 5.1 93/09/24 */ /* * ==================================================== * 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. * ==================================================== */ /* * modfl(long double x, long double *iptr) * return fraction part of x, and return x's integral part in *iptr. * Method: * Bit twiddling. * * Exception: * No exception. */ #include #include "math_private.h" static const long double one = 1.0; long double modfl(long double x, long double *iptr) { int32_t i0,i1,jj0; u_int32_t i,se; GET_LDOUBLE_WORDS(se,i0,i1,x); jj0 = (se&0x7fff)-0x3fff; /* exponent of x */ if(jj0<32) { /* integer part in high x */ if(jj0<0) { /* |x|<1 */ SET_LDOUBLE_WORDS(*iptr,se&0x8000,0,0); /* *iptr = +-0 */ return x; } else { i = (0x7fffffff)>>jj0; if(((i0&i)|i1)==0) { /* x is integral */ *iptr = x; SET_LDOUBLE_WORDS(x,se&0x8000,0,0); /* return +-0 */ return x; } else { SET_LDOUBLE_WORDS(*iptr,se,i0&(~i),0); return x - *iptr; } } } else if (jj0>63) { /* no fraction part */ *iptr = x*one; /* We must handle NaNs separately. */ if (jj0 == 0x4000 && ((i0 & 0x7fffffff) | i1)) return x*one; SET_LDOUBLE_WORDS(x,se&0x8000,0,0); /* return +-0 */ return x; } else { /* fraction part in low x */ i = ((u_int32_t)(0x7fffffff))>>(jj0-32); if((i1&i)==0) { /* x is integral */ *iptr = x; SET_LDOUBLE_WORDS(x,se&0x8000,0,0); /* return +-0 */ return x; } else { SET_LDOUBLE_WORDS(*iptr,se,i0,i1&(~i)); return x - *iptr; } } } openlibm-0.5.0/ld80/s_nanl.c000066400000000000000000000032721266752446200155300ustar00rootroot00000000000000/*- * Copyright (c) 2007 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/lib/msun/ld80/s_nanl.c,v 1.2 2007/12/18 23:46:31 das Exp $ */ #include #include "math_private.h" DLLEXPORT long double nanl(const char *s) { union { union IEEEl2bits ieee; uint32_t bits[3]; } u; __scan_nan(u.bits, 3, s); u.ieee.bits.exp = 0x7fff; u.ieee.bits.manh |= 0xc0000000; /* make it a quiet NaN */ return (u.ieee.e); } openlibm-0.5.0/ld80/s_nextafterl.c000066400000000000000000000044141266752446200167530ustar00rootroot00000000000000/* @(#)s_nextafter.c 5.1 93/09/24 */ /* * ==================================================== * 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. * ==================================================== */ /* IEEE functions * nextafterl(x,y) * return the next machine floating-point number of x in the * direction toward y. * Special cases: */ #include #include "math_private.h" long double nextafterl(long double x, long double y) { int32_t hx,hy,ix,iy; u_int32_t lx,ly,esx,esy; GET_LDOUBLE_WORDS(esx,hx,lx,x); GET_LDOUBLE_WORDS(esy,hy,ly,y); ix = esx&0x7fff; /* |x| */ iy = esy&0x7fff; /* |y| */ if (((ix==0x7fff)&&((hx&0x7fffffff|lx)!=0)) || /* x is nan */ ((iy==0x7fff)&&((hy&0x7fffffff|ly)!=0))) /* y is nan */ return x+y; if(x==y) return y; /* x=y, return y */ if((ix|hx|lx)==0) { /* x == 0 */ volatile long double u; SET_LDOUBLE_WORDS(x,esy&0x8000,0,1);/* return +-minsubnormal */ u = x; u = u * u; /* raise underflow flag */ return x; } if(esx<0x8000) { /* x > 0 */ if(ix>iy||((ix==iy) && (hx>hy||((hx==hy)&&(lx>ly))))) { /* x > y, x -= ulp */ if(lx==0) { if ((hx&0x7fffffff)==0) esx -= 1; hx = (hx - 1) | (hx & 0x80000000); } lx -= 1; } else { /* x < y, x += ulp */ lx += 1; if(lx==0) { hx = (hx + 1) | (hx & 0x80000000); if ((hx&0x7fffffff)==0) esx += 1; } } } else { /* x < 0 */ if(esy>=0||(ix>iy||((ix==iy)&&(hx>hy||((hx==hy)&&(lx>ly)))))){ /* x < y, x -= ulp */ if(lx==0) { if ((hx&0x7fffffff)==0) esx -= 1; hx = (hx - 1) | (hx & 0x80000000); } lx -= 1; } else { /* x > y, x += ulp */ lx += 1; if(lx==0) { hx = (hx + 1) | (hx & 0x80000000); if ((hx&0x7fffffff)==0) esx += 1; } } } esy = esx&0x7fff; if(esy==0x7fff) return x+x; /* overflow */ if(esy==0) { volatile long double u = x*x; /* underflow */ if(u==x) { SET_LDOUBLE_WORDS(x,esx,hx,lx); return x; } } SET_LDOUBLE_WORDS(x,esx,hx,lx); return x; } //__strong_alias(nexttowardl, nextafterl); openlibm-0.5.0/ld80/s_nexttoward.c000066400000000000000000000042351266752446200167770ustar00rootroot00000000000000/* @(#)s_nextafter.c 5.1 93/09/24 */ /* * ==================================================== * 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. * ==================================================== */ /* IEEE functions * nexttoward(x,y) * return the next machine floating-point number of x in the * direction toward y. * Special cases: */ #include #include #include "math_private.h" double nexttoward(double x, long double y) { int32_t hx,ix,iy; u_int32_t lx,hy,ly,esy; EXTRACT_WORDS(hx,lx,x); GET_LDOUBLE_WORDS(esy,hy,ly,y); ix = hx&0x7fffffff; /* |x| */ iy = esy&0x7fff; /* |y| */ if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) || /* x is nan */ ((iy>=0x7fff)&&(hy|ly)!=0)) /* y is nan */ return x+y; if((long double) x==y) return y; /* x=y, return y */ if((ix|lx)==0) { /* x == 0 */ volatile double u; INSERT_WORDS(x,(esy&0x8000)<<16,1); /* return +-minsub */ u = x; u = u * u; /* raise underflow flag */ return x; } if(hx>=0) { /* x > 0 */ if (esy>=0x8000||((ix>>20)&0x7ff)>iy-0x3c00 || (((ix>>20)&0x7ff)==iy-0x3c00 && (((hx<<11)|(lx>>21))>(hy&0x7fffffff) || (((hx<<11)|(lx>>21))==(hy&0x7fffffff) && (lx<<11)>ly)))) { /* x > y, x -= ulp */ if(lx==0) hx -= 1; lx -= 1; } else { /* x < y, x += ulp */ lx += 1; if(lx==0) hx += 1; } } else { /* x < 0 */ if (esy<0x8000||((ix>>20)&0x7ff)>iy-0x3c00 || (((ix>>20)&0x7ff)==iy-0x3c00 && (((hx<<11)|(lx>>21))>(hy&0x7fffffff) || (((hx<<11)|(lx>>21))==(hy&0x7fffffff) && (lx<<11)>ly)))) {/* x < y, x -= ulp */ if(lx==0) hx -= 1; lx -= 1; } else { /* x > y, x += ulp */ lx += 1; if(lx==0) hx += 1; } } hy = hx&0x7ff00000; if(hy>=0x7ff00000) { x = x+x; /* overflow */ return x; } if(hy<0x00100000) { volatile double u = x*x; /* underflow */ if(u==x) { INSERT_WORDS(x,hx,lx); return x; } } INSERT_WORDS(x,hx,lx); return x; } openlibm-0.5.0/ld80/s_nexttowardf.c000066400000000000000000000033131266752446200171410ustar00rootroot00000000000000/* @(#)s_nextafter.c 5.1 93/09/24 */ /* * ==================================================== * 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 #include #include "math_private.h" float nexttowardf(float x, long double y) { int32_t hx,ix,iy; u_int32_t hy,ly,esy; GET_FLOAT_WORD(hx,x); GET_LDOUBLE_WORDS(esy,hy,ly,y); ix = hx&0x7fffffff; /* |x| */ iy = esy&0x7fff; /* |y| */ if((ix>0x7f800000) || /* x is nan */ (iy>=0x7fff&&((hy|ly)!=0))) /* y is nan */ return x+y; if((long double) x==y) return y; /* x=y, return y */ if(ix==0) { /* x == 0 */ volatile float u; SET_FLOAT_WORD(x,((esy&0x8000)<<16)|1);/* return +-minsub*/ u = x; u = u * u; /* raise underflow flag */ return x; } if(hx>=0) { /* x > 0 */ if(esy>=0x8000||((ix>>23)&0xff)>iy-0x3f80 || (((ix>>23)&0xff)==iy-0x3f80 && ((ix&0x7fffff)<<8)>(hy&0x7fffffff))) {/* x > y, x -= ulp */ hx -= 1; } else { /* x < y, x += ulp */ hx += 1; } } else { /* x < 0 */ if(esy<0x8000||((ix>>23)&0xff)>iy-0x3f80 || (((ix>>23)&0xff)==iy-0x3f80 && ((ix&0x7fffff)<<8)>(hy&0x7fffffff))) {/* x < y, x -= ulp */ hx -= 1; } else { /* x > y, x += ulp */ hx += 1; } } hy = hx&0x7f800000; if(hy>=0x7f800000) { x = x+x; /* overflow */ return x; } if(hy<0x00800000) { volatile float u = x*x; /* underflow */ } SET_FLOAT_WORD(x,hx); return x; } openlibm-0.5.0/ld80/s_remquol.c000066400000000000000000000101711266752446200162600ustar00rootroot00000000000000/* @(#)e_fmod.c 1.3 95/01/18 */ /*- * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include #include #include #include #include #include "math_private.h" #define BIAS (LDBL_MAX_EXP - 1) /* * These macros add and remove an explicit integer bit in front of the * fractional mantissa, if the architecture doesn't have such a bit by * default already. */ #ifdef LDBL_IMPLICIT_NBIT #define LDBL_NBIT 0 #define SET_NBIT(hx) ((hx) | (1ULL << LDBL_MANH_SIZE)) #define HFRAC_BITS EXT_FRACHBITS #else #define LDBL_NBIT 0x80000000 #define SET_NBIT(hx) (hx) #define HFRAC_BITS (EXT_FRACHBITS - 1) #endif #define MANL_SHIFT (EXT_FRACLBITS - 1) static const long double Zero[] = {0.0L, -0.0L}; /* * Return the IEEE remainder and set *quo to the last n bits of the * quotient, rounded to the nearest integer. We choose n=31 because * we wind up computing all the integer bits of the quotient anyway as * a side-effect of computing the remainder by the shift and subtract * method. In practice, this is far more bits than are needed to use * remquo in reduction algorithms. * * Assumptions: * - The low part of the mantissa fits in a manl_t exactly. * - The high part of the mantissa fits in an int64_t with enough room * for an explicit integer bit in front of the fractional bits. */ long double remquol(long double x, long double y, int *quo) { int64_t hx,hz; /* We need a carry bit even if LDBL_MANH_SIZE is 32. */ uint32_t hy; uint32_t lx,ly,lz; uint32_t esx, esy; int ix,iy,n,q,sx,sxy; GET_LDOUBLE_WORDS(esx,hx,lx,x); GET_LDOUBLE_WORDS(esy,hy,ly,y); sx = esx & 0x8000; sxy = sx ^ (esy & 0x8000); esx &= 0x7fff; /* |x| */ esy &= 0x7fff; /* |y| */ SET_LDOUBLE_EXP(x,esx); SET_LDOUBLE_EXP(y,esy); /* purge off exception values */ if((esy|hy|ly)==0 || /* y=0 */ (esx == BIAS + LDBL_MAX_EXP) || /* or x not finite */ (esy == BIAS + LDBL_MAX_EXP && ((hy&~LDBL_NBIT)|ly)!=0)) /* or y is NaN */ return (x*y)/(x*y); if(esx<=esy) { if((esx>MANL_SHIFT); lx = lx+lx;} else {hx = hz+hz+(lz>>MANL_SHIFT); lx = lz+lz; q++;} q <<= 1; } hz=hx-hy;lz=lx-ly; if(lx=0) {hx=hz;lx=lz;q++;} /* convert back to floating value and restore the sign */ if((hx|lx)==0) { /* return sign(x)*0 */ *quo = (sxy ? -q : q); return Zero[sx!=0]; } while(hx<(1ULL<>MANL_SHIFT); lx = lx+lx; iy -= 1; } if (iy < LDBL_MIN_EXP) { esx = (iy + BIAS + 512) & 0x7fff; SET_LDOUBLE_WORDS(x,esx,hx,lx); x *= 0x1p-512; GET_LDOUBLE_WORDS(esx,hx,lx,x); } else { esx = (iy + BIAS) & 0x7fff; } SET_LDOUBLE_WORDS(x,esx,hx,lx); fixup: y = fabsl(y); if (y < LDBL_MIN * 2) { if (x+x>y || (x+x==y && (q & 1))) { q++; x-=y; } } else if (x>0.5*y || (x==0.5*y && (q & 1))) { q++; x-=y; } GET_LDOUBLE_EXP(esx,x); esx ^= sx; SET_LDOUBLE_EXP(x,esx); q &= 0x7fffffff; *quo = (sxy ? -q : q); return x; } openlibm-0.5.0/ld80/s_tanhl.c000066400000000000000000000040621266752446200157040ustar00rootroot00000000000000/* @(#)s_tanh.c 5.1 93/09/24 */ /* * ==================================================== * 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. * ==================================================== */ /* tanhl(x) * Return the Hyperbolic Tangent of x * * Method : * x -x * e - e * 0. tanhl(x) is defined to be ----------- * x -x * e + e * 1. reduce x to non-negative by tanhl(-x) = -tanhl(x). * 2. 0 <= x <= 2**-55 : tanhl(x) := x*(one+x) * -t * 2**-55 < x <= 1 : tanhl(x) := -----; t = expm1l(-2x) * t + 2 * 2 * 1 <= x <= 23.0 : tanhl(x) := 1- ----- ; t=expm1l(2x) * t + 2 * 23.0 < x <= INF : tanhl(x) := 1. * * Special cases: * tanhl(NaN) is NaN; * only tanhl(0)=0 is exact for finite argument. */ #include #include "math_private.h" static const long double one=1.0, two=2.0, tiny = 1.0e-4900L; long double tanhl(long double x) { long double t,z; int32_t se; u_int32_t jj0,jj1,ix; /* High word of |x|. */ GET_LDOUBLE_WORDS(se,jj0,jj1,x); ix = se&0x7fff; /* x is INF or NaN */ if(ix==0x7fff) { /* for NaN it's not important which branch: tanhl(NaN) = NaN */ if (se&0x8000) return one/x-one; /* tanhl(-inf)= -1; */ else return one/x+one; /* tanhl(+inf)=+1 */ } /* |x| < 23 */ if (ix < 0x4003 || (ix == 0x4003 && jj0 < 0xb8000000u)) {/* |x|<23 */ if ((ix|jj0|jj1) == 0) return x; /* x == +- 0 */ if (ix<0x3fc8) /* |x|<2**-55 */ return x*(one+tiny); /* tanh(small) = small */ if (ix>=0x3fff) { /* |x|>=1 */ t = expm1l(two*fabsl(x)); z = one - two/(t+two); } else { t = expm1l(-two*fabsl(x)); z= -t/(t+two); } /* |x| > 23, return +-1 */ } else { z = one - tiny; /* raised inexact flag */ } return (se&0x8000)? -z: z; } openlibm-0.5.0/ld80/s_truncl.c000066400000000000000000000032241266752446200161040ustar00rootroot00000000000000/* * ==================================================== * 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. * ==================================================== * * From: @(#)s_floor.c 5.1 93/09/24 */ /* * truncl(x) * Return x rounded toward 0 to integral value * Method: * Bit twiddling. * Exception: * Inexact flag raised if x not equal to truncl(x). */ #include //#include #include #include #include #include "math_private.h" #ifdef LDBL_IMPLICIT_NBIT #define MANH_SIZE (EXT_FRACHBITS + 1) #else #define MANH_SIZE EXT_FRACHBITS #endif static const long double huge = 1.0e300; static const float zero[] = { 0.0, -0.0 }; long double truncl(long double x) { int e, es; uint32_t ix0, ix1; GET_LDOUBLE_WORDS(es,ix0,ix1,x); e = (es&0x7fff) - LDBL_MAX_EXP + 1; if (e < MANH_SIZE - 1) { if (e < 0) { /* raise inexact if x != 0 */ if (huge + x > 0.0) return (zero[(es&0x8000)!=0]); } else { uint64_t m = ((1llu << MANH_SIZE) - 1) >> (e + 1); if (((ix0 & m) | ix1) == 0) return (x); /* x is integral */ if (huge + x > 0.0) { /* raise inexact flag */ ix0 &= ~m; ix1 = 0; } } } else if (e < LDBL_MANT_DIG - 1) { uint64_t m = (uint64_t)-1 >> (64 - LDBL_MANT_DIG + e + 1); if ((ix1 & m) == 0) return (x); /* x is integral */ if (huge + x > 0.0) /* raise inexact flag */ ix1 &= ~m; } SET_LDOUBLE_WORDS(x,es,ix0,ix1); return (x); } openlibm-0.5.0/openlibm.pc.in000066400000000000000000000004211266752446200160720ustar00rootroot00000000000000exec_prefix=${prefix} includedir=${prefix}/include libdir=${exec_prefix}/lib Name: openlibm Version: ${version} URL: https://github.com/JuliaLang/openlibm Description: High quality system independent, open source libm. Cflags: -I${includedir} Libs: -L${libdir} -lopenlibm openlibm-0.5.0/powerpc/000077500000000000000000000000001266752446200150165ustar00rootroot00000000000000openlibm-0.5.0/powerpc/Make.files000066400000000000000000000000251266752446200167140ustar00rootroot00000000000000$(CUR_SRCS) = fenv.c openlibm-0.5.0/powerpc/fenv.c000066400000000000000000000041371266752446200161250ustar00rootroot00000000000000/*- * Copyright (c) 2004 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #define __fenv_static #include #ifdef __GNUC_GNU_INLINE__ #error "This file must be compiled with C99 'inline' semantics" #endif const fenv_t __fe_dfl_env = 0x00000000; extern inline int feclearexcept(int __excepts); extern inline int fegetexceptflag(fexcept_t *__flagp, int __excepts); extern inline int fesetexceptflag(const fexcept_t *__flagp, int __excepts); extern inline int feraiseexcept(int __excepts); extern inline int fetestexcept(int __excepts); extern inline int fegetround(void); extern inline int fesetround(int __round); extern inline int fegetenv(fenv_t *__envp); extern inline int feholdexcept(fenv_t *__envp); extern inline int fesetenv(const fenv_t *__envp); extern inline int feupdateenv(const fenv_t *__envp); openlibm-0.5.0/src/000077500000000000000000000000001266752446200141265ustar00rootroot00000000000000openlibm-0.5.0/src/Make.files000066400000000000000000000055171266752446200160370ustar00rootroot00000000000000$(CUR_SRCS) = common.c \ e_acos.c e_acosf.c e_acosh.c e_acoshf.c e_asin.c e_asinf.c \ e_atan2.c e_atan2f.c e_atanh.c e_atanhf.c e_cosh.c e_coshf.c e_exp.c \ e_expf.c e_fmod.c e_fmodf.c \ e_hypot.c e_hypotf.c e_j0.c e_j0f.c e_j1.c e_j1f.c \ e_jn.c e_jnf.c e_lgamma.c e_lgamma_r.c e_lgammaf.c e_lgammaf_r.c \ e_log.c e_log10.c e_log10f.c e_log2.c e_log2f.c e_logf.c \ e_pow.c e_powf.c e_remainder.c e_remainderf.c \ e_rem_pio2.c e_rem_pio2f.c \ e_sinh.c e_sinhf.c e_sqrt.c e_sqrtf.c \ k_cos.c k_exp.c k_expf.c k_rem_pio2.c k_sin.c k_tan.c \ k_cosf.c k_sinf.c k_tanf.c \ s_asinh.c s_asinhf.c s_atan.c s_atanf.c s_carg.c s_cargf.c \ s_cbrt.c s_cbrtf.c s_ceil.c s_ceilf.c \ s_copysign.c s_copysignf.c s_cos.c s_cosf.c \ s_csqrt.c s_csqrtf.c s_erf.c s_erff.c \ s_exp2.c s_exp2f.c s_expm1.c s_expm1f.c s_fabs.c s_fabsf.c s_fdim.c \ s_floor.c s_floorf.c s_fma.c s_fmaf.c \ s_fmax.c s_fmaxf.c s_fmin.c \ s_fminf.c s_fpclassify.c \ s_frexp.c s_frexpf.c s_ilogb.c s_ilogbf.c \ s_isinf.c s_isfinite.c s_isnormal.c s_isnan.c \ s_llrint.c s_llrintf.c s_llround.c s_llroundf.c \ s_log1p.c s_log1pf.c s_logb.c s_logbf.c s_lrint.c s_lrintf.c \ s_lround.c s_lroundf.c s_modf.c s_modff.c \ s_nearbyint.c s_nextafter.c s_nextafterf.c \ s_nexttowardf.c s_remquo.c s_remquof.c \ s_rint.c s_rintf.c s_round.c s_roundf.c \ s_scalbln.c s_scalbn.c s_scalbnf.c s_signbit.c \ s_signgam.c s_sin.c s_sincos.c \ s_sinf.c s_sincosf.c s_tan.c s_tanf.c s_tanh.c s_tanhf.c s_tgammaf.c \ s_trunc.c s_truncf.c s_cpow.c s_cpowf.c \ w_cabs.c w_cabsf.c ifneq ($(OS), WINNT) $(CUR_SRCS) += s_nan.c endif ifneq ($(ARCH), arm) ifneq ($(ARCH), powerpc) # C99 long double functions $(CUR_SRCS) += s_copysignl.c s_fabsl.c s_llrintl.c s_lrintl.c s_modfl.c # If long double != double use these; otherwise, we alias the double versions. $(CUR_SRCS) += e_acosl.c e_asinl.c e_atan2l.c e_fmodl.c \ s_fmaxl.c s_fminl.c s_ilogbl.c \ e_hypotl.c e_lgammal.c e_remainderl.c e_sqrtl.c \ s_atanl.c s_ceill.c s_cosl.c s_cprojl.c \ s_csqrtl.c s_floorl.c s_fmal.c \ s_frexpl.c s_logbl.c s_nexttoward.c \ s_remquol.c s_roundl.c s_lroundl.c s_llroundl.c \ s_cpowl.c s_cargl.c \ s_sinl.c s_sincosl.c s_tanl.c s_truncl.c w_cabsl.c \ s_nextafterl.c s_rintl.c s_scalbnl.c polevll.c \ s_casinl.c s_ctanl.c \ s_cimagl.c s_conjl.c s_creall.c s_cacoshl.c s_catanhl.c s_casinhl.c \ s_catanl.c s_csinl.c s_cacosl.c s_cexpl.c s_csinhl.c s_ccoshl.c \ s_clogl.c s_ctanhl.c s_ccosl.c s_cbrtl.c endif endif # C99 complex functions $(CUR_SRCS) += s_ccosh.c s_ccoshf.c s_cexp.c s_cexpf.c \ s_cimag.c s_cimagf.c \ s_conj.c s_conjf.c \ s_cproj.c s_cprojf.c s_creal.c s_crealf.c \ s_csinh.c s_csinhf.c s_ctanh.c s_ctanhf.c \ s_cacos.c s_cacosf.c \ s_cacosh.c s_cacoshf.c \ s_casin.c s_casinf.c s_casinh.c s_casinhf.c \ s_catan.c s_catanf.c s_catanh.c s_catanhf.c \ s_clog.c s_clogf.c openlibm-0.5.0/src/aarch64_fpmath.h000066400000000000000000000041611266752446200170700ustar00rootroot00000000000000/*- * Copyright (c) 2002, 2003 David Schultz * Copyright (2) 2014 The FreeBSD Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: head/lib/libc/aarch64/_fpmath.h 281197 2015-04-07 09:52:14Z andrew $ */ union IEEEl2bits { long double e; struct { unsigned long manl :64; unsigned long manh :48; unsigned int exp :15; unsigned int sign :1; } bits; /* TODO andrew: Check the packing here */ struct { unsigned long manl :64; unsigned long manh :48; unsigned int expsign :16; } xbits; }; #define LDBL_NBIT 0 #define LDBL_IMPLICIT_NBIT #define mask_nbit_l(u) ((void)0) #define LDBL_MANH_SIZE 48 #define LDBL_MANL_SIZE 64 #define LDBL_TO_ARRAY32(u, a) do { \ (a)[0] = (uint32_t)(u).bits.manl; \ (a)[1] = (uint32_t)((u).bits.manl >> 32); \ (a)[2] = (uint32_t)(u).bits.manh; \ (a)[3] = (uint32_t)((u).bits.manh >> 32); \ } while(0) openlibm-0.5.0/src/amd64_fpmath.h000066400000000000000000000037571266752446200165650ustar00rootroot00000000000000/*- * Copyright (c) 2002, 2003 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/lib/libc/amd64/_fpmath.h,v 1.7 2008/01/17 16:39:06 bde Exp $ */ union IEEEl2bits { long double e; struct { unsigned int manl :32; unsigned int manh :32; unsigned int exp :15; unsigned int sign :1; unsigned int junkl :16; unsigned int junkh :32; } bits; struct { unsigned long man :64; unsigned int expsign :16; unsigned long junk :48; } xbits; }; #define LDBL_NBIT 0x80000000 #define mask_nbit_l(u) ((u).bits.manh &= ~LDBL_NBIT) #define LDBL_MANH_SIZE 32 #define LDBL_MANL_SIZE 32 #define LDBL_TO_ARRAY32(u, a) do { \ (a)[0] = (uint32_t)(u).bits.manl; \ (a)[1] = (uint32_t)(u).bits.manh; \ } while (0) openlibm-0.5.0/src/bsd_cdefs.h000066400000000000000000000072741266752446200162250ustar00rootroot00000000000000/*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Berkeley Software Design, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)cdefs.h 8.8 (Berkeley) 1/9/95 * $FreeBSD: src/sys/sys/cdefs.h,v 1.114 2011/02/18 21:44:53 nwhitehorn Exp $ */ /* Do not redefine macros if the system provides them in sys/cdefs.h. * The two macros correspond to different platforms. */ #ifndef _BSD_CDEFS_H_ #define _BSD_CDEFS_H_ /* * This code has been put in place to help reduce the addition of * compiler specific defines in FreeBSD code. It helps to aid in * having a compiler-agnostic source tree. */ #if defined(__GNUC__) || defined(__INTEL_COMPILER) #if __GNUC__ >= 3 || defined(__INTEL_COMPILER) #define __GNUCLIKE_ASM 3 #else #define __GNUCLIKE_ASM 2 #endif #define __CC_SUPPORTS___INLINE__ 1 #endif /* __GNUC__ || __INTEL_COMPILER */ #if defined(__STDC__) || defined(__cplusplus) #define __volatile volatile #if defined(__cplusplus) #define __inline inline /* convert to C++ keyword */ #else #if !defined(__CC_SUPPORTS___INLINE) #define __inline /* delete GCC keyword */ #endif /* ! __CC_SUPPORTS___INLINE */ #endif /* !__cplusplus */ #else /* !(__STDC__ || __cplusplus) */ #if !defined(__CC_SUPPORTS___INLINE) #define __inline #define __volatile #endif /* !__CC_SUPPORTS___INLINE */ #endif /* !(__STDC__ || __cplusplus) */ /* * Macro to test if we're using a specific version of gcc or later. */ #if defined(__GNUC__) && !defined(__INTEL_COMPILER) #define __GNUC_PREREQ__(ma, mi) \ (__GNUC__ > (ma) || __GNUC__ == (ma) && __GNUC_MINOR__ >= (mi)) #else #define __GNUC_PREREQ__(ma, mi) 0 #endif /* * Compiler-dependent macro to help declare pure (no side effects) functions. * It is null except for versions of gcc that are known to support the features * properly (old versions of gcc-2 supported the dead and pure features * in a different (wrong) way), and for icc. If we do not provide an implementation * for a given compiler, let the compile fail if it is told to use * a feature that we cannot live without. */ #if !defined(__pure2) && (__GNUC_PREREQ__(2, 7) || defined(__INTEL_COMPILER)) #define __pure2 __attribute__((__const__)) #endif #endif /* !_BSD_CDEFS_H_ */ openlibm-0.5.0/src/cdefs-compat.h000066400000000000000000000037301266752446200166470ustar00rootroot00000000000000#ifndef _CDEFS_COMPAT_H_ #define _CDEFS_COMPAT_H_ #if defined(__cplusplus) #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS #define __END_DECLS #endif #ifdef __GNUC__ #ifndef __strong_reference #ifdef __APPLE__ #define __strong_reference(sym,aliassym) __weak_reference(sym,aliassym) #else #define __strong_reference(sym,aliassym) \ DLLEXPORT extern __typeof (sym) aliassym __attribute__ ((__alias__ (#sym))); #endif /* __APPLE__ */ #endif /* __strong_reference */ #ifndef __weak_reference #ifdef __ELF__ #ifdef __STDC__ #define __weak_reference(sym,alias) \ __asm__(".weak " #alias); \ __asm__(".equ " #alias ", " #sym) #define __warn_references(sym,msg) \ __asm__(".section .gnu.warning." #sym); \ __asm__(".asciz \"" msg "\""); \ __asm__(".previous") #else #define __weak_reference(sym,alias) \ __asm__(".weak alias"); \ __asm__(".equ alias, sym") #define __warn_references(sym,msg) \ __asm__(".section .gnu.warning.sym"); \ __asm__(".asciz \"msg\""); \ __asm__(".previous") #endif /* __STDC__ */ #elif defined(__clang__) /* CLANG */ #ifdef __STDC__ #define __weak_reference(sym,alias) \ __asm__(".weak_reference " #alias); \ __asm__(".set " #alias ", " #sym) #else #define __weak_reference(sym,alias) \ __asm__(".weak_reference alias");\ __asm__(".set alias, sym") #endif #else /* !__ELF__ */ #ifdef __STDC__ #define __weak_reference(sym,alias) \ __asm__(".stabs \"_" #alias "\",11,0,0,0"); \ __asm__(".stabs \"_" #sym "\",1,0,0,0") #define __warn_references(sym,msg) \ __asm__(".stabs \"" msg "\",30,0,0,0"); \ __asm__(".stabs \"_" #sym "\",1,0,0,0") #else #define __weak_reference(sym,alias) \ __asm__(".stabs \"_/**/alias\",11,0,0,0"); \ __asm__(".stabs \"_/**/sym\",1,0,0,0") #define __warn_references(sym,msg) \ __asm__(".stabs msg,30,0,0,0"); \ __asm__(".stabs \"_/**/sym\",1,0,0,0") #endif /* __STDC__ */ #endif /* __ELF__ */ #endif /* __weak_reference */ #endif /* __GNUC__ */ #endif /* _CDEFS_COMPAT_H_ */ openlibm-0.5.0/src/common.c000066400000000000000000000001501266752446200155560ustar00rootroot00000000000000#include #include "math_private.h" DLLEXPORT int isopenlibm(void) { return 1; } openlibm-0.5.0/src/e_acos.c000066400000000000000000000067331266752446200155340ustar00rootroot00000000000000 /* @(#)e_acos.c 1.3 95/01/18 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_acos.c,v 1.13 2008/07/31 22:41:26 das Exp $"); /* __ieee754_acos(x) * Method : * acos(x) = pi/2 - asin(x) * acos(-x) = pi/2 + asin(x) * For |x|<=0.5 * acos(x) = pi/2 - (x + x*x^2*R(x^2)) (see asin.c) * For x>0.5 * acos(x) = pi/2 - (pi/2 - 2asin(sqrt((1-x)/2))) * = 2asin(sqrt((1-x)/2)) * = 2s + 2s*z*R(z) ...z=(1-x)/2, s=sqrt(z) * = 2f + (2c + 2s*z*R(z)) * where f=hi part of s, and c = (z-f*f)/(s+f) is the correction term * for f so that f+c ~ sqrt(z). * For x<-0.5 * acos(x) = pi - 2asin(sqrt((1-|x|)/2)) * = pi - 0.5*(s+s*z*R(z)), where z=(1-|x|)/2,s=sqrt(z) * * Special cases: * if x is NaN, return x itself; * if |x|>1, return NaN with invalid signal. * * Function needed: sqrt */ #include #include #include "math_private.h" static const double one= 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ pi = 3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */ pio2_hi = 1.57079632679489655800e+00; /* 0x3FF921FB, 0x54442D18 */ static volatile double pio2_lo = 6.12323399573676603587e-17; /* 0x3C91A626, 0x33145C07 */ static const double pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */ pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */ pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */ pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */ pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */ pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */ qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */ qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */ qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */ qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */ DLLEXPORT double __ieee754_acos(double x) { double z,p,q,r,w,s,c,df; int32_t hx,ix; GET_HIGH_WORD(hx,x); ix = hx&0x7fffffff; if(ix>=0x3ff00000) { /* |x| >= 1 */ u_int32_t lx; GET_LOW_WORD(lx,x); if(((ix-0x3ff00000)|lx)==0) { /* |x|==1 */ if(hx>0) return 0.0; /* acos(1) = 0 */ else return pi+2.0*pio2_lo; /* acos(-1)= pi */ } return (x-x)/(x-x); /* acos(|x|>1) is NaN */ } if(ix<0x3fe00000) { /* |x| < 0.5 */ if(ix<=0x3c600000) return pio2_hi+pio2_lo;/*if|x|<2**-57*/ z = x*x; p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); r = p/q; return pio2_hi - (x - (pio2_lo-x*r)); } else if (hx<0) { /* x < -0.5 */ z = (one+x)*0.5; p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); s = sqrt(z); r = p/q; w = r*s-pio2_lo; return pi - 2.0*(s+w); } else { /* x > 0.5 */ z = (one-x)*0.5; s = sqrt(z); df = s; SET_LOW_WORD(df,0); c = (z-df*df)/(s+df); p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); r = p/q; w = r*s+c; return 2.0*(df+w); } } #if LDBL_MANT_DIG == 53 __weak_reference(acos, acosl); #endif openlibm-0.5.0/src/e_acosf.c000066400000000000000000000041211266752446200156670ustar00rootroot00000000000000/* e_acosf.c -- float version of e_acos.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_acosf.c,v 1.11 2008/08/03 17:39:54 das Exp $"); #include #include "math_private.h" static const float one = 1.0000000000e+00, /* 0x3F800000 */ pi = 3.1415925026e+00, /* 0x40490fda */ pio2_hi = 1.5707962513e+00; /* 0x3fc90fda */ static volatile float pio2_lo = 7.5497894159e-08; /* 0x33a22168 */ static const float pS0 = 1.6666586697e-01, pS1 = -4.2743422091e-02, pS2 = -8.6563630030e-03, qS1 = -7.0662963390e-01; DLLEXPORT float __ieee754_acosf(float x) { float z,p,q,r,w,s,c,df; int32_t hx,ix; GET_FLOAT_WORD(hx,x); ix = hx&0x7fffffff; if(ix>=0x3f800000) { /* |x| >= 1 */ if(ix==0x3f800000) { /* |x| == 1 */ if(hx>0) return 0.0; /* acos(1) = 0 */ else return pi+(float)2.0*pio2_lo; /* acos(-1)= pi */ } return (x-x)/(x-x); /* acos(|x|>1) is NaN */ } if(ix<0x3f000000) { /* |x| < 0.5 */ if(ix<=0x32800000) return pio2_hi+pio2_lo;/*if|x|<2**-26*/ z = x*x; p = z*(pS0+z*(pS1+z*pS2)); q = one+z*qS1; r = p/q; return pio2_hi - (x - (pio2_lo-x*r)); } else if (hx<0) { /* x < -0.5 */ z = (one+x)*(float)0.5; p = z*(pS0+z*(pS1+z*pS2)); q = one+z*qS1; s = sqrtf(z); r = p/q; w = r*s-pio2_lo; return pi - (float)2.0*(s+w); } else { /* x > 0.5 */ int32_t idf; z = (one-x)*(float)0.5; s = sqrtf(z); df = s; GET_FLOAT_WORD(idf,df); SET_FLOAT_WORD(df,idf&0xfffff000); c = (z-df*df)/(s+df); p = z*(pS0+z*(pS1+z*pS2)); q = one+z*qS1; r = p/q; w = r*s+c; return (float)2.0*(df+w); } } openlibm-0.5.0/src/e_acosh.c000066400000000000000000000032111266752446200156700ustar00rootroot00000000000000 /* @(#)e_acosh.c 1.3 95/01/18 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== * */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_acosh.c,v 1.9 2008/02/22 02:30:34 das Exp $"); /* __ieee754_acosh(x) * Method : * Based on * acosh(x) = log [ x + sqrt(x*x-1) ] * we have * acosh(x) := log(x)+ln2, if x is large; else * acosh(x) := log(2x-1/(sqrt(x*x-1)+x)) if x>2; else * acosh(x) := log1p(t+sqrt(2.0*t+t*t)); where t=x-1. * * Special cases: * acosh(x) is NaN with signal if x<1. * acosh(NaN) is NaN without signal. */ #include #include "math_private.h" static const double one = 1.0, ln2 = 6.93147180559945286227e-01; /* 0x3FE62E42, 0xFEFA39EF */ DLLEXPORT double __ieee754_acosh(double x) { double t; int32_t hx; u_int32_t lx; EXTRACT_WORDS(hx,lx,x); if(hx<0x3ff00000) { /* x < 1 */ return (x-x)/(x-x); } else if(hx >=0x41b00000) { /* x > 2**28 */ if(hx >=0x7ff00000) { /* x is inf of NaN */ return x+x; } else return __ieee754_log(x)+ln2; /* acosh(huge)=log(2x) */ } else if(((hx-0x3ff00000)|lx)==0) { return 0.0; /* acosh(1) = 0 */ } else if (hx > 0x40000000) { /* 2**28 > x > 2 */ t=x*x; return __ieee754_log(2.0*x-one/(x+sqrt(t-one))); } else { /* 1 #include "math_private.h" static const float one = 1.0, ln2 = 6.9314718246e-01; /* 0x3f317218 */ DLLEXPORT float __ieee754_acoshf(float x) { float t; int32_t hx; GET_FLOAT_WORD(hx,x); if(hx<0x3f800000) { /* x < 1 */ return (x-x)/(x-x); } else if(hx >=0x4d800000) { /* x > 2**28 */ if(hx >=0x7f800000) { /* x is inf of NaN */ return x+x; } else return __ieee754_logf(x)+ln2; /* acosh(huge)=log(2x) */ } else if (hx==0x3f800000) { return 0.0; /* acosh(1) = 0 */ } else if (hx > 0x40000000) { /* 2**28 > x > 2 */ t=x*x; return __ieee754_logf((float)2.0*x-one/(x+__ieee754_sqrtf(t-one))); } else { /* 1. */ #include #include #include "invtrig.h" #include "math_private.h" static const long double one= 1.00000000000000000000e+00; #ifdef __i386__ /* XXX Work around the fact that gcc truncates long double constants on i386 */ static volatile double pi1 = 3.14159265358979311600e+00, /* 0x1.921fb54442d18p+1 */ pi2 = 1.22514845490862001043e-16; /* 0x1.1a80000000000p-53 */ #define pi ((long double)pi1 + pi2) #else static const long double pi = 3.14159265358979323846264338327950280e+00L; #endif DLLEXPORT long double acosl(long double x) { union IEEEl2bits u; long double z,p,q,r,w,s,c,df; int16_t expsign, expt; u.e = x; expsign = u.xbits.expsign; expt = expsign & 0x7fff; if(expt >= BIAS) { /* |x| >= 1 */ if(expt==BIAS && ((u.bits.manh&~LDBL_NBIT)|u.bits.manl)==0) { if (expsign>0) return 0.0; /* acos(1) = 0 */ else return pi+2.0*pio2_lo; /* acos(-1)= pi */ } return (x-x)/(x-x); /* acos(|x|>1) is NaN */ } if(expt 0.5 */ z = (one-x)*0.5; s = sqrtl(z); u.e = s; u.bits.manl = 0; df = u.e; c = (z-df*df)/(s+df); p = P(z); q = Q(z); r = p/q; w = r*s+c; return 2.0*(df+w); } } openlibm-0.5.0/src/e_asin.c000066400000000000000000000072171266752446200155370ustar00rootroot00000000000000 /* @(#)e_asin.c 1.3 95/01/18 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_asin.c,v 1.15 2011/02/10 07:37:50 das Exp $"); /* __ieee754_asin(x) * Method : * Since asin(x) = x + x^3/6 + x^5*3/40 + x^7*15/336 + ... * we approximate asin(x) on [0,0.5] by * asin(x) = x + x*x^2*R(x^2) * where * R(x^2) is a rational approximation of (asin(x)-x)/x^3 * and its remez error is bounded by * |(asin(x)-x)/x^3 - R(x^2)| < 2^(-58.75) * * For x in [0.5,1] * asin(x) = pi/2-2*asin(sqrt((1-x)/2)) * Let y = (1-x), z = y/2, s := sqrt(z), and pio2_hi+pio2_lo=pi/2; * then for x>0.98 * asin(x) = pi/2 - 2*(s+s*z*R(z)) * = pio2_hi - (2*(s+s*z*R(z)) - pio2_lo) * For x<=0.98, let pio4_hi = pio2_hi/2, then * f = hi part of s; * c = sqrt(z) - f = (z-f*f)/(s+f) ...f+c=sqrt(z) * and * asin(x) = pi/2 - 2*(s+s*z*R(z)) * = pio4_hi+(pio4-2s)-(2s*z*R(z)-pio2_lo) * = pio4_hi+(pio4-2f)-(2s*z*R(z)-(pio2_lo+2c)) * * Special cases: * if x is NaN, return x itself; * if |x|>1, return NaN with invalid signal. * */ #include #include #include "math_private.h" static const double one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ huge = 1.000e+300, pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */ pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */ pio4_hi = 7.85398163397448278999e-01, /* 0x3FE921FB, 0x54442D18 */ /* coefficient for R(x^2) */ pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */ pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */ pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */ pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */ pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */ pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */ qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */ qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */ qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */ qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */ DLLEXPORT double __ieee754_asin(double x) { double t=0.0,w,p,q,c,r,s; int32_t hx,ix; GET_HIGH_WORD(hx,x); ix = hx&0x7fffffff; if(ix>= 0x3ff00000) { /* |x|>= 1 */ u_int32_t lx; GET_LOW_WORD(lx,x); if(((ix-0x3ff00000)|lx)==0) /* asin(1)=+-pi/2 with inexact */ return x*pio2_hi+x*pio2_lo; return (x-x)/(x-x); /* asin(|x|>1) is NaN */ } else if (ix<0x3fe00000) { /* |x|<0.5 */ if(ix<0x3e500000) { /* if |x| < 2**-26 */ if(huge+x>one) return x;/* return x with inexact if x!=0*/ } t = x*x; p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5))))); q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4))); w = p/q; return x+x*w; } /* 1> |x|>= 0.5 */ w = one-fabs(x); t = w*0.5; p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5))))); q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4))); s = sqrt(t); if(ix>=0x3FEF3333) { /* if |x| > 0.975 */ w = p/q; t = pio2_hi-(2.0*(s+s*w)-pio2_lo); } else { w = s; SET_LOW_WORD(w,0); c = (t-w*w)/(s+w); r = p/q; p = 2.0*s*r-(pio2_lo-2.0*c); q = pio4_hi-2.0*w; t = pio4_hi-(p-q); } if(hx>0) return t; else return -t; } #if LDBL_MANT_DIG == 53 __weak_reference(asin, asinl); #endif openlibm-0.5.0/src/e_asinf.c000066400000000000000000000032461266752446200157030ustar00rootroot00000000000000/* e_asinf.c -- float version of e_asin.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_asinf.c,v 1.13 2008/08/08 00:21:27 das Exp $"); #include #include "math_private.h" static const float one = 1.0000000000e+00, /* 0x3F800000 */ huge = 1.000e+30, /* coefficient for R(x^2) */ pS0 = 1.6666586697e-01, pS1 = -4.2743422091e-02, pS2 = -8.6563630030e-03, qS1 = -7.0662963390e-01; static const double pio2 = 1.570796326794896558e+00; DLLEXPORT float __ieee754_asinf(float x) { double s; float t,w,p,q; int32_t hx,ix; GET_FLOAT_WORD(hx,x); ix = hx&0x7fffffff; if(ix>=0x3f800000) { /* |x| >= 1 */ if(ix==0x3f800000) /* |x| == 1 */ return x*pio2; /* asin(+-1) = +-pi/2 with inexact */ return (x-x)/(x-x); /* asin(|x|>1) is NaN */ } else if (ix<0x3f000000) { /* |x|<0.5 */ if(ix<0x39800000) { /* |x| < 2**-12 */ if(huge+x>one) return x;/* return x with inexact if x!=0*/ } t = x*x; p = t*(pS0+t*(pS1+t*pS2)); q = one+t*qS1; w = p/q; return x+x*w; } /* 1> |x|>= 0.5 */ w = one-fabsf(x); t = w*(float)0.5; p = t*(pS0+t*(pS1+t*pS2)); q = one+t*qS1; s = sqrt(t); w = p/q; t = pio2-2.0*(s+s*w); if(hx>0) return t; else return -t; } openlibm-0.5.0/src/e_asinl.c000066400000000000000000000036741266752446200157160ustar00rootroot00000000000000 /* @(#)e_asin.c 1.3 95/01/18 */ /* FreeBSD: head/lib/msun/src/e_asin.c 176451 2008-02-22 02:30:36Z das */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_asinl.c,v 1.2 2008/08/03 17:49:05 das Exp $"); /* * See comments in e_asin.c. * Converted to long double by David Schultz . */ #include #include #include "invtrig.h" #include "math_private.h" static const long double one = 1.00000000000000000000e+00, huge = 1.000e+300; DLLEXPORT long double asinl(long double x) { union IEEEl2bits u; long double t=0.0,w,p,q,c,r,s; int16_t expsign, expt; u.e = x; expsign = u.xbits.expsign; expt = expsign & 0x7fff; if(expt >= BIAS) { /* |x|>= 1 */ if(expt==BIAS && ((u.bits.manh&~LDBL_NBIT)|u.bits.manl)==0) /* asin(1)=+-pi/2 with inexact */ return x*pio2_hi+x*pio2_lo; return (x-x)/(x-x); /* asin(|x|>1) is NaN */ } else if (exptone) return x;/* return x with inexact if x!=0*/ } t = x*x; p = P(t); q = Q(t); w = p/q; return x+x*w; } /* 1> |x|>= 0.5 */ w = one-fabsl(x); t = w*0.5; p = P(t); q = Q(t); s = sqrtl(t); if(u.bits.manh>=THRESH) { /* if |x| is close to 1 */ w = p/q; t = pio2_hi-(2.0*(s+s*w)-pio2_lo); } else { u.e = s; u.bits.manl = 0; w = u.e; c = (t-w*w)/(s+w); r = p/q; p = 2.0*s*r-(pio2_lo-2.0*c); q = pio4_hi-2.0*w; t = pio4_hi-(p-q); } if(expsign>0) return t; else return -t; } openlibm-0.5.0/src/e_atan2.c000066400000000000000000000075001266752446200156050ustar00rootroot00000000000000 /* @(#)e_atan2.c 1.3 95/01/18 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== * */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_atan2.c,v 1.14 2008/08/02 19:17:00 das Exp $"); /* __ieee754_atan2(y,x) * Method : * 1. Reduce y to positive by atan2(y,x)=-atan2(-y,x). * 2. Reduce x to positive by (if x and y are unexceptional): * ARG (x+iy) = arctan(y/x) ... if x > 0, * ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0, * * Special cases: * * ATAN2((anything), NaN ) is NaN; * ATAN2(NAN , (anything) ) is NaN; * ATAN2(+-0, +(anything but NaN)) is +-0 ; * ATAN2(+-0, -(anything but NaN)) is +-pi ; * ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2; * ATAN2(+-(anything but INF and NaN), +INF) is +-0 ; * ATAN2(+-(anything but INF and NaN), -INF) is +-pi; * ATAN2(+-INF,+INF ) is +-pi/4 ; * ATAN2(+-INF,-INF ) is +-3pi/4; * ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2; * * Constants: * The hexadecimal values are the intended ones for the following * constants. The decimal values may be used, provided that the * compiler will convert from decimal to binary accurately enough * to produce the hexadecimal values shown. */ #include #include #include "math_private.h" static volatile double tiny = 1.0e-300; static const double zero = 0.0, pi_o_4 = 7.8539816339744827900E-01, /* 0x3FE921FB, 0x54442D18 */ pi_o_2 = 1.5707963267948965580E+00, /* 0x3FF921FB, 0x54442D18 */ pi = 3.1415926535897931160E+00; /* 0x400921FB, 0x54442D18 */ static volatile double pi_lo = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */ DLLEXPORT double __ieee754_atan2(double y, double x) { double z; int32_t k,m,hx,hy,ix,iy; u_int32_t lx,ly; EXTRACT_WORDS(hx,lx,x); ix = hx&0x7fffffff; EXTRACT_WORDS(hy,ly,y); iy = hy&0x7fffffff; if(((ix|((lx|-lx)>>31))>0x7ff00000)|| ((iy|((ly|-ly)>>31))>0x7ff00000)) /* x or y is NaN */ return x+y; if(((hx-0x3ff00000)|lx)==0) return atan(y); /* x=1.0 */ m = ((hy>>31)&1)|((hx>>30)&2); /* 2*sign(x)+sign(y) */ /* when y = 0 */ if((iy|ly)==0) { switch(m) { case 0: case 1: return y; /* atan(+-0,+anything)=+-0 */ case 2: return pi+tiny;/* atan(+0,-anything) = pi */ case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */ } } /* when x = 0 */ if((ix|lx)==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; /* when x is INF */ if(ix==0x7ff00000) { if(iy==0x7ff00000) { switch(m) { case 0: return pi_o_4+tiny;/* atan(+INF,+INF) */ case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */ case 2: return 3.0*pi_o_4+tiny;/*atan(+INF,-INF)*/ case 3: return -3.0*pi_o_4-tiny;/*atan(-INF,-INF)*/ } } else { switch(m) { case 0: return zero ; /* atan(+...,+INF) */ case 1: return -zero ; /* atan(-...,+INF) */ case 2: return pi+tiny ; /* atan(+...,-INF) */ case 3: return -pi-tiny ; /* atan(-...,-INF) */ } } } /* when y is INF */ if(iy==0x7ff00000) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; /* compute y/x */ k = (iy-ix)>>20; if(k > 60) { /* |y/x| > 2**60 */ z=pi_o_2+0.5*pi_lo; m&=1; } else if(hx<0&&k<-60) z=0.0; /* 0 > |y|/x > -2**-60 */ else z=atan(fabs(y/x)); /* safe to do y/x */ switch (m) { case 0: return z ; /* atan(+,+) */ case 1: return -z ; /* atan(-,+) */ case 2: return pi-(z-pi_lo);/* atan(+,-) */ default: /* case 3 */ return (z-pi_lo)-pi;/* atan(-,-) */ } } #if LDBL_MANT_DIG == 53 __weak_reference(atan2, atan2l); #endif openlibm-0.5.0/src/e_atan2f.c000066400000000000000000000053201266752446200157510ustar00rootroot00000000000000/* e_atan2f.c -- float version of e_atan2.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_atan2f.c,v 1.12 2008/08/03 17:39:54 das Exp $"); #include #include "math_private.h" static volatile float tiny = 1.0e-30; static const float zero = 0.0, pi_o_4 = 7.8539818525e-01, /* 0x3f490fdb */ pi_o_2 = 1.5707963705e+00, /* 0x3fc90fdb */ pi = 3.1415927410e+00; /* 0x40490fdb */ static volatile float pi_lo = -8.7422776573e-08; /* 0xb3bbbd2e */ DLLEXPORT float __ieee754_atan2f(float y, float x) { float z; int32_t k,m,hx,hy,ix,iy; GET_FLOAT_WORD(hx,x); ix = hx&0x7fffffff; GET_FLOAT_WORD(hy,y); iy = hy&0x7fffffff; if((ix>0x7f800000)|| (iy>0x7f800000)) /* x or y is NaN */ return x+y; if(hx==0x3f800000) return atanf(y); /* x=1.0 */ m = ((hy>>31)&1)|((hx>>30)&2); /* 2*sign(x)+sign(y) */ /* when y = 0 */ if(iy==0) { switch(m) { case 0: case 1: return y; /* atan(+-0,+anything)=+-0 */ case 2: return pi+tiny;/* atan(+0,-anything) = pi */ case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */ } } /* when x = 0 */ if(ix==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; /* when x is INF */ if(ix==0x7f800000) { if(iy==0x7f800000) { switch(m) { case 0: return pi_o_4+tiny;/* atan(+INF,+INF) */ case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */ case 2: return (float)3.0*pi_o_4+tiny;/*atan(+INF,-INF)*/ case 3: return (float)-3.0*pi_o_4-tiny;/*atan(-INF,-INF)*/ } } else { switch(m) { case 0: return zero ; /* atan(+...,+INF) */ case 1: return -zero ; /* atan(-...,+INF) */ case 2: return pi+tiny ; /* atan(+...,-INF) */ case 3: return -pi-tiny ; /* atan(-...,-INF) */ } } } /* when y is INF */ if(iy==0x7f800000) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; /* compute y/x */ k = (iy-ix)>>23; if(k > 26) { /* |y/x| > 2**26 */ z=pi_o_2+(float)0.5*pi_lo; m&=1; } else if(k<-26&&hx<0) z=0.0; /* 0 > |y|/x > -2**-26 */ else z=atanf(fabsf(y/x)); /* safe to do y/x */ switch (m) { case 0: return z ; /* atan(+,+) */ case 1: return -z ; /* atan(-,+) */ case 2: return pi-(z-pi_lo);/* atan(+,-) */ default: /* case 3 */ return (z-pi_lo)-pi;/* atan(-,-) */ } } openlibm-0.5.0/src/e_atan2l.c000066400000000000000000000067761266752446200157770ustar00rootroot00000000000000 /* @(#)e_atan2.c 1.3 95/01/18 */ /* FreeBSD: head/lib/msun/src/e_atan2.c 176451 2008-02-22 02:30:36Z das */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== * */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_atan2l.c,v 1.3 2008/08/02 19:17:00 das Exp $"); /* * See comments in e_atan2.c. * Converted to long double by David Schultz . */ #include #include #include "invtrig.h" #include "math_private.h" static volatile long double tiny = 1.0e-300; static const long double zero = 0.0; #ifdef __i386__ /* XXX Work around the fact that gcc truncates long double constants on i386 */ static volatile double pi1 = 3.14159265358979311600e+00, /* 0x1.921fb54442d18p+1 */ pi2 = 1.22514845490862001043e-16; /* 0x1.1a80000000000p-53 */ #define pi ((long double)pi1 + pi2) #else static const long double pi = 3.14159265358979323846264338327950280e+00L; #endif DLLEXPORT long double atan2l(long double y, long double x) { union IEEEl2bits ux, uy; long double z; int32_t k,m; int16_t exptx, expsignx, expty, expsigny; uy.e = y; expsigny = uy.xbits.expsign; expty = expsigny & 0x7fff; ux.e = x; expsignx = ux.xbits.expsign; exptx = expsignx & 0x7fff; if ((exptx==BIAS+LDBL_MAX_EXP && ((ux.bits.manh&~LDBL_NBIT)|ux.bits.manl)!=0) || /* x is NaN */ (expty==BIAS+LDBL_MAX_EXP && ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl)!=0)) /* y is NaN */ return x+y; if (expsignx==BIAS && ((ux.bits.manh&~LDBL_NBIT)|ux.bits.manl)==0) return atanl(y); /* x=1.0 */ m = ((expsigny>>15)&1)|((expsignx>>14)&2); /* 2*sign(x)+sign(y) */ /* when y = 0 */ if(expty==0 && ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl)==0) { switch(m) { case 0: case 1: return y; /* atan(+-0,+anything)=+-0 */ case 2: return pi+tiny;/* atan(+0,-anything) = pi */ case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */ } } /* when x = 0 */ if(exptx==0 && ((ux.bits.manh&~LDBL_NBIT)|ux.bits.manl)==0) return (expsigny<0)? -pio2_hi-tiny: pio2_hi+tiny; /* when x is INF */ if(exptx==BIAS+LDBL_MAX_EXP) { if(expty==BIAS+LDBL_MAX_EXP) { switch(m) { case 0: return pio2_hi*0.5+tiny;/* atan(+INF,+INF) */ case 1: return -pio2_hi*0.5-tiny;/* atan(-INF,+INF) */ case 2: return 1.5*pio2_hi+tiny;/*atan(+INF,-INF)*/ case 3: return -1.5*pio2_hi-tiny;/*atan(-INF,-INF)*/ } } else { switch(m) { case 0: return zero ; /* atan(+...,+INF) */ case 1: return -zero ; /* atan(-...,+INF) */ case 2: return pi+tiny ; /* atan(+...,-INF) */ case 3: return -pi-tiny ; /* atan(-...,-INF) */ } } } /* when y is INF */ if(expty==BIAS+LDBL_MAX_EXP) return (expsigny<0)? -pio2_hi-tiny: pio2_hi+tiny; /* compute y/x */ k = expty-exptx; if(k > LDBL_MANT_DIG+2) { /* |y/x| huge */ z=pio2_hi+pio2_lo; m&=1; } else if(expsignx<0&&k<-LDBL_MANT_DIG-2) z=0.0; /* |y/x| tiny, x<0 */ else z=atanl(fabsl(y/x)); /* safe to do y/x */ switch (m) { case 0: return z ; /* atan(+,+) */ case 1: return -z ; /* atan(-,+) */ case 2: return pi-(z-pi_lo);/* atan(+,-) */ default: /* case 3 */ return (z-pi_lo)-pi;/* atan(-,-) */ } } openlibm-0.5.0/src/e_atanh.c000066400000000000000000000032171266752446200156740ustar00rootroot00000000000000 /* @(#)e_atanh.c 1.3 95/01/18 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== * */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_atanh.c,v 1.8 2008/02/22 02:30:34 das Exp $"); /* __ieee754_atanh(x) * Method : * 1.Reduced x to positive by atanh(-x) = -atanh(x) * 2.For x>=0.5 * 1 2x x * atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------) * 2 1 - x 1 - x * * For x<0.5 * atanh(x) = 0.5*log1p(2x+2x*x/(1-x)) * * Special cases: * atanh(x) is NaN if |x| > 1 with signal; * atanh(NaN) is that NaN with no signal; * atanh(+-1) is +-INF with signal. * */ #include #include "math_private.h" static const double one = 1.0, huge = 1e300; static const double zero = 0.0; DLLEXPORT double __ieee754_atanh(double x) { double t; int32_t hx,ix; u_int32_t lx; EXTRACT_WORDS(hx,lx,x); ix = hx&0x7fffffff; if ((ix|((lx|(-lx))>>31))>0x3ff00000) /* |x|>1 */ return (x-x)/(x-x); if(ix==0x3ff00000) return x/zero; if(ix<0x3e300000&&(huge+x)>zero) return x; /* x<2**-28 */ SET_HIGH_WORD(x,ix); if(ix<0x3fe00000) { /* x < 0.5 */ t = x+x; t = 0.5*log1p(t+t*x/(one-x)); } else t = 0.5*log1p((x+x)/(one-x)); if(hx>=0) return t; else return -t; } openlibm-0.5.0/src/e_atanhf.c000066400000000000000000000023201266752446200160340ustar00rootroot00000000000000/* e_atanhf.c -- float version of e_atanh.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_atanhf.c,v 1.7 2008/02/22 02:30:34 das Exp $"); #include #include "math_private.h" static const float one = 1.0, huge = 1e30; static const float zero = 0.0; DLLEXPORT float __ieee754_atanhf(float x) { float t; int32_t hx,ix; GET_FLOAT_WORD(hx,x); ix = hx&0x7fffffff; if (ix>0x3f800000) /* |x|>1 */ return (x-x)/(x-x); if(ix==0x3f800000) return x/zero; if(ix<0x31800000&&(huge+x)>zero) return x; /* x<2**-28 */ SET_FLOAT_WORD(x,ix); if(ix<0x3f000000) { /* x < 0.5 */ t = x+x; t = (float)0.5*log1pf(t+t*x/(one-x)); } else t = (float)0.5*log1pf((x+x)/(one-x)); if(hx>=0) return t; else return -t; } openlibm-0.5.0/src/e_cosh.c000066400000000000000000000043351266752446200155370ustar00rootroot00000000000000 /* @(#)e_cosh.c 1.3 95/01/18 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_cosh.c,v 1.10 2011/10/21 06:28:47 das Exp $"); /* __ieee754_cosh(x) * Method : * mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2 * 1. Replace x by |x| (cosh(x) = cosh(-x)). * 2. * [ exp(x) - 1 ]^2 * 0 <= x <= ln2/2 : cosh(x) := 1 + ------------------- * 2*exp(x) * * exp(x) + 1/exp(x) * ln2/2 <= x <= 22 : cosh(x) := ------------------- * 2 * 22 <= x <= lnovft : cosh(x) := exp(x)/2 * lnovft <= x <= ln2ovft: cosh(x) := exp(x/2)/2 * exp(x/2) * ln2ovft < x : cosh(x) := huge*huge (overflow) * * Special cases: * cosh(x) is |x| if x is +INF, -INF, or NaN. * only cosh(0)=1 is exact for finite x. */ #include #include "math_private.h" static const double one = 1.0, half=0.5, huge = 1.0e300; DLLEXPORT double __ieee754_cosh(double x) { double t,w; int32_t ix; /* High word of |x|. */ GET_HIGH_WORD(ix,x); ix &= 0x7fffffff; /* x is INF or NaN */ if(ix>=0x7ff00000) return x*x; /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */ if(ix<0x3fd62e43) { t = expm1(fabs(x)); w = one+t; if (ix<0x3c800000) return w; /* cosh(tiny) = 1 */ return one+(t*t)/(w+w); } /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */ if (ix < 0x40360000) { t = __ieee754_exp(fabs(x)); return half*t+half/t; } /* |x| in [22, log(maxdouble)] return half*exp(|x|) */ if (ix < 0x40862E42) return half*__ieee754_exp(fabs(x)); /* |x| in [log(maxdouble), overflowthresold] */ if (ix<=0x408633CE) return __ldexp_exp(fabs(x), -1); /* |x| > overflowthresold, cosh(x) overflow */ return huge*huge; } openlibm-0.5.0/src/e_coshf.c000066400000000000000000000030431266752446200157000ustar00rootroot00000000000000/* e_coshf.c -- float version of e_cosh.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_coshf.c,v 1.9 2011/10/21 06:28:47 das Exp $"); #include #include "math_private.h" static const float one = 1.0, half=0.5, huge = 1.0e30; DLLEXPORT float __ieee754_coshf(float x) { float t,w; int32_t ix; GET_FLOAT_WORD(ix,x); ix &= 0x7fffffff; /* x is INF or NaN */ if(ix>=0x7f800000) return x*x; /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */ if(ix<0x3eb17218) { t = expm1f(fabsf(x)); w = one+t; if (ix<0x39800000) return one; /* cosh(tiny) = 1 */ return one+(t*t)/(w+w); } /* |x| in [0.5*ln2,9], return (exp(|x|)+1/exp(|x|))/2; */ if (ix < 0x41100000) { t = __ieee754_expf(fabsf(x)); return half*t+half/t; } /* |x| in [9, log(maxfloat)] return half*exp(|x|) */ if (ix < 0x42b17217) return half*__ieee754_expf(fabsf(x)); /* |x| in [log(maxfloat), overflowthresold] */ if (ix<=0x42b2d4fc) return __ldexp_expf(fabsf(x), -1); /* |x| > overflowthresold, cosh(x) overflow */ return huge*huge; } openlibm-0.5.0/src/e_exp.c000066400000000000000000000126471266752446200154040ustar00rootroot00000000000000 /* @(#)e_exp.c 1.6 04/04/22 */ /* * ==================================================== * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved. * * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_exp.c,v 1.14 2011/10/21 06:26:38 das Exp $"); /* __ieee754_exp(x) * Returns the exponential of x. * * Method * 1. Argument reduction: * Reduce x to an r so that |r| <= 0.5*ln2 ~ 0.34658. * Given x, find r and integer k such that * * x = k*ln2 + r, |r| <= 0.5*ln2. * * Here r will be represented as r = hi-lo for better * accuracy. * * 2. Approximation of exp(r) by a special rational function on * the interval [0,0.34658]: * Write * R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ... * We use a special Remes algorithm on [0,0.34658] to generate * a polynomial of degree 5 to approximate R. The maximum error * of this polynomial approximation is bounded by 2**-59. In * other words, * R(z) ~ 2.0 + P1*z + P2*z**2 + P3*z**3 + P4*z**4 + P5*z**5 * (where z=r*r, and the values of P1 to P5 are listed below) * and * | 5 | -59 * | 2.0+P1*z+...+P5*z - R(z) | <= 2 * | | * The computation of exp(r) thus becomes * 2*r * exp(r) = 1 + ------- * R - r * r*R1(r) * = 1 + r + ----------- (for better accuracy) * 2 - R1(r) * where * 2 4 10 * R1(r) = r - (P1*r + P2*r + ... + P5*r ). * * 3. Scale back to obtain exp(x): * From step 1, we have * exp(x) = 2^k * exp(r) * * Special cases: * exp(INF) is INF, exp(NaN) is NaN; * exp(-INF) is 0, and * for finite argument, only exp(0)=1 is exact. * * Accuracy: * according to an error analysis, the error is always less than * 1 ulp (unit in the last place). * * Misc. info. * For IEEE double * if x > 7.09782712893383973096e+02 then exp(x) overflow * if x < -7.45133219101941108420e+02 then exp(x) underflow * * Constants: * The hexadecimal values are the intended ones for the following * constants. The decimal values may be used, provided that the * compiler will convert from decimal to binary accurately enough * to produce the hexadecimal values shown. */ #include #include #include "math_private.h" static const double one = 1.0, halF[2] = {0.5,-0.5,}, huge = 1.0e+300, o_threshold= 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */ u_threshold= -7.45133219101941108420e+02, /* 0xc0874910, 0xD52D3051 */ ln2HI[2] ={ 6.93147180369123816490e-01, /* 0x3fe62e42, 0xfee00000 */ -6.93147180369123816490e-01,},/* 0xbfe62e42, 0xfee00000 */ ln2LO[2] ={ 1.90821492927058770002e-10, /* 0x3dea39ef, 0x35793c76 */ -1.90821492927058770002e-10,},/* 0xbdea39ef, 0x35793c76 */ invln2 = 1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */ P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */ P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */ P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */ P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */ P5 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */ static volatile double twom1000= 9.33263618503218878990e-302; /* 2**-1000=0x01700000,0*/ DLLEXPORT double __ieee754_exp(double x) /* default IEEE double exp */ { double y,hi=0.0,lo=0.0,c,t,twopk; int32_t k=0,xsb; u_int32_t hx; GET_HIGH_WORD(hx,x); xsb = (hx>>31)&1; /* sign bit of x */ hx &= 0x7fffffff; /* high word of |x| */ /* filter out non-finite argument */ if(hx >= 0x40862E42) { /* if |x|>=709.78... */ if(hx>=0x7ff00000) { u_int32_t lx; GET_LOW_WORD(lx,x); if(((hx&0xfffff)|lx)!=0) return x+x; /* NaN */ else return (xsb==0)? x:0.0; /* exp(+-inf)={inf,0} */ } if(x > o_threshold) return huge*huge; /* overflow */ if(x < u_threshold) return twom1000*twom1000; /* underflow */ } /* this implementation gives 2.7182818284590455 for exp(1.0), which is well within the allowable error. however, 2.718281828459045 is closer to the true value so we prefer that answer, given that 1.0 is such an important argument value. */ if (x == 1.0) return 2.718281828459045235360; /* argument reduction */ if(hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */ if(hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */ hi = x-ln2HI[xsb]; lo=ln2LO[xsb]; k = 1-xsb-xsb; } else { k = (int)(invln2*x+halF[xsb]); t = k; hi = x - t*ln2HI[0]; /* t*ln2HI is exact here */ lo = t*ln2LO[0]; } STRICT_ASSIGN(double, x, hi - lo); } else if(hx < 0x3e300000) { /* when |x|<2**-28 */ if(huge+x>one) return one+x;/* trigger inexact */ } else k = 0; /* x is now in primary range */ t = x*x; if(k >= -1021) INSERT_WORDS(twopk,0x3ff00000+(k<<20), 0); else INSERT_WORDS(twopk,0x3ff00000+((k+1000)<<20), 0); c = x - t*(P1+t*(P2+t*(P3+t*(P4+t*P5)))); if(k==0) return one-((x*c)/(c-2.0)-x); else y = one-((lo-(x*c)/(2.0-c))-hi); if(k >= -1021) { if (k==1024) return y*2.0*0x1p1023; return y*twopk; } else { return y*twopk*twom1000; } } openlibm-0.5.0/src/e_expf.c000066400000000000000000000054251266752446200155460ustar00rootroot00000000000000/* e_expf.c -- float version of e_exp.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_expf.c,v 1.16 2011/10/21 06:26:38 das Exp $"); #include #include #include "math_private.h" static const float one = 1.0, halF[2] = {0.5,-0.5,}, huge = 1.0e+30, o_threshold= 8.8721679688e+01, /* 0x42b17180 */ u_threshold= -1.0397208405e+02, /* 0xc2cff1b5 */ ln2HI[2] ={ 6.9314575195e-01, /* 0x3f317200 */ -6.9314575195e-01,}, /* 0xbf317200 */ ln2LO[2] ={ 1.4286067653e-06, /* 0x35bfbe8e */ -1.4286067653e-06,}, /* 0xb5bfbe8e */ invln2 = 1.4426950216e+00, /* 0x3fb8aa3b */ /* * Domain [-0.34568, 0.34568], range ~[-4.278e-9, 4.447e-9]: * |x*(exp(x)+1)/(exp(x)-1) - p(x)| < 2**-27.74 */ P1 = 1.6666625440e-1, /* 0xaaaa8f.0p-26 */ P2 = -2.7667332906e-3; /* -0xb55215.0p-32 */ static volatile float twom100 = 7.8886090522e-31; /* 2**-100=0x0d800000 */ DLLEXPORT float __ieee754_expf(float x) { float y,hi=0.0,lo=0.0,c,t,twopk; int32_t k=0,xsb; u_int32_t hx; GET_FLOAT_WORD(hx,x); xsb = (hx>>31)&1; /* sign bit of x */ hx &= 0x7fffffff; /* high word of |x| */ /* filter out non-finite argument */ if(hx >= 0x42b17218) { /* if |x|>=88.721... */ if(hx>0x7f800000) return x+x; /* NaN */ if(hx==0x7f800000) return (xsb==0)? x:0.0; /* exp(+-inf)={inf,0} */ if(x > o_threshold) return huge*huge; /* overflow */ if(x < u_threshold) return twom100*twom100; /* underflow */ } /* argument reduction */ if(hx > 0x3eb17218) { /* if |x| > 0.5 ln2 */ if(hx < 0x3F851592) { /* and |x| < 1.5 ln2 */ hi = x-ln2HI[xsb]; lo=ln2LO[xsb]; k = 1-xsb-xsb; } else { k = invln2*x+halF[xsb]; t = k; hi = x - t*ln2HI[0]; /* t*ln2HI is exact here */ lo = t*ln2LO[0]; } STRICT_ASSIGN(float, x, hi - lo); } else if(hx < 0x39000000) { /* when |x|<2**-14 */ if(huge+x>one) return one+x;/* trigger inexact */ } else k = 0; /* x is now in primary range */ t = x*x; if(k >= -125) SET_FLOAT_WORD(twopk,0x3f800000+(k<<23)); else SET_FLOAT_WORD(twopk,0x3f800000+((k+100)<<23)); c = x - t*(P1+t*P2); if(k==0) return one-((x*c)/(c-(float)2.0)-x); else y = one-((lo-(x*c)/((float)2.0-c))-hi); if(k >= -125) { if(k==128) return y*2.0F*0x1p127F; return y*twopk; } else { return y*twopk*twom100; } } openlibm-0.5.0/src/e_fmod.c000066400000000000000000000065001266752446200155240ustar00rootroot00000000000000 /* @(#)e_fmod.c 1.3 95/01/18 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_fmod.c,v 1.10 2008/02/22 02:30:34 das Exp $"); /* * __ieee754_fmod(x,y) * Return x mod y in exact arithmetic * Method: shift and subtract */ #include #include "math_private.h" static const double one = 1.0, Zero[] = {0.0, -0.0,}; DLLEXPORT double __ieee754_fmod(double x, double y) { int32_t n,hx,hy,hz,ix,iy,sx,i; u_int32_t lx,ly,lz; EXTRACT_WORDS(hx,lx,x); EXTRACT_WORDS(hy,ly,y); sx = hx&0x80000000; /* sign of x */ hx ^=sx; /* |x| */ hy &= 0x7fffffff; /* |y| */ /* purge off exception values */ if((hy|ly)==0||(hx>=0x7ff00000)|| /* y=0,or x not finite */ ((hy|((ly|-ly)>>31))>0x7ff00000)) /* or y is NaN */ return (x*y)/(x*y); if(hx<=hy) { if((hx>31]; /* |x|=|y| return x*0*/ } /* determine ix = ilogb(x) */ if(hx<0x00100000) { /* subnormal x */ if(hx==0) { for (ix = -1043, i=lx; i>0; i<<=1) ix -=1; } else { for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1; } } else ix = (hx>>20)-1023; /* determine iy = ilogb(y) */ if(hy<0x00100000) { /* subnormal y */ if(hy==0) { for (iy = -1043, i=ly; i>0; i<<=1) iy -=1; } else { for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1; } } else iy = (hy>>20)-1023; /* set up {hx,lx}, {hy,ly} and align y to x */ if(ix >= -1022) hx = 0x00100000|(0x000fffff&hx); else { /* subnormal x, shift x to normal */ n = -1022-ix; if(n<=31) { hx = (hx<>(32-n)); lx <<= n; } else { hx = lx<<(n-32); lx = 0; } } if(iy >= -1022) hy = 0x00100000|(0x000fffff&hy); else { /* subnormal y, shift y to normal */ n = -1022-iy; if(n<=31) { hy = (hy<>(32-n)); ly <<= n; } else { hy = ly<<(n-32); ly = 0; } } /* fix point fmod */ n = ix - iy; while(n--) { hz=hx-hy;lz=lx-ly; if(lx>31); lx = lx+lx;} else { if((hz|lz)==0) /* return sign(x)*0 */ return Zero[(u_int32_t)sx>>31]; hx = hz+hz+(lz>>31); lx = lz+lz; } } hz=hx-hy;lz=lx-ly; if(lx=0) {hx=hz;lx=lz;} /* convert back to floating value and restore the sign */ if((hx|lx)==0) /* return sign(x)*0 */ return Zero[(u_int32_t)sx>>31]; while(hx<0x00100000) { /* normalize x */ hx = hx+hx+(lx>>31); lx = lx+lx; iy -= 1; } if(iy>= -1022) { /* normalize output */ hx = ((hx-0x00100000)|((iy+1023)<<20)); INSERT_WORDS(x,hx|sx,lx); } else { /* subnormal output */ n = -1022 - iy; if(n<=20) { lx = (lx>>n)|((u_int32_t)hx<<(32-n)); hx >>= n; } else if (n<=31) { lx = (hx<<(32-n))|(lx>>n); hx = sx; } else { lx = hx>>(n-32); hx = sx; } INSERT_WORDS(x,hx|sx,lx); x *= one; /* create necessary signal */ } return x; /* exact output */ } openlibm-0.5.0/src/e_fmodf.c000066400000000000000000000052351266752446200156760ustar00rootroot00000000000000/* e_fmodf.c -- float version of e_fmod.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_fmodf.c,v 1.7 2008/02/22 02:30:34 das Exp $"); /* * __ieee754_fmodf(x,y) * Return x mod y in exact arithmetic * Method: shift and subtract */ #include #include "math_private.h" static const float one = 1.0, Zero[] = {0.0, -0.0,}; DLLEXPORT float __ieee754_fmodf(float x, float y) { int32_t n,hx,hy,hz,ix,iy,sx,i; GET_FLOAT_WORD(hx,x); GET_FLOAT_WORD(hy,y); sx = hx&0x80000000; /* sign of x */ hx ^=sx; /* |x| */ hy &= 0x7fffffff; /* |y| */ /* purge off exception values */ if(hy==0||(hx>=0x7f800000)|| /* y=0,or x not finite */ (hy>0x7f800000)) /* or y is NaN */ return (x*y)/(x*y); if(hx>31]; /* |x|=|y| return x*0*/ /* determine ix = ilogb(x) */ if(hx<0x00800000) { /* subnormal x */ for (ix = -126,i=(hx<<8); i>0; i<<=1) ix -=1; } else ix = (hx>>23)-127; /* determine iy = ilogb(y) */ if(hy<0x00800000) { /* subnormal y */ for (iy = -126,i=(hy<<8); i>=0; i<<=1) iy -=1; } else iy = (hy>>23)-127; /* set up {hx,lx}, {hy,ly} and align y to x */ if(ix >= -126) hx = 0x00800000|(0x007fffff&hx); else { /* subnormal x, shift x to normal */ n = -126-ix; hx = hx<= -126) hy = 0x00800000|(0x007fffff&hy); else { /* subnormal y, shift y to normal */ n = -126-iy; hy = hy<>31]; hx = hz+hz; } } hz=hx-hy; if(hz>=0) {hx=hz;} /* convert back to floating value and restore the sign */ if(hx==0) /* return sign(x)*0 */ return Zero[(u_int32_t)sx>>31]; while(hx<0x00800000) { /* normalize x */ hx = hx+hx; iy -= 1; } if(iy>= -126) { /* normalize output */ hx = ((hx-0x00800000)|((iy+127)<<23)); SET_FLOAT_WORD(x,hx|sx); } else { /* subnormal output */ n = -126 - iy; hx >>= n; SET_FLOAT_WORD(x,hx|sx); x *= one; /* create necessary signal */ } return x; /* exact output */ } openlibm-0.5.0/src/e_fmodl.c000066400000000000000000000075271266752446200157120ustar00rootroot00000000000000/* @(#)e_fmod.c 1.3 95/01/18 */ /*- * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_fmodl.c,v 1.2 2008/07/31 20:09:47 das Exp $"); #include #include #include #include "fpmath.h" #include "math_private.h" #define BIAS (LDBL_MAX_EXP - 1) #if LDBL_MANL_SIZE > 32 typedef u_int64_t manl_t; #else typedef u_int32_t manl_t; #endif #if LDBL_MANH_SIZE > 32 typedef u_int64_t manh_t; #else typedef u_int32_t manh_t; #endif /* * These macros add and remove an explicit integer bit in front of the * fractional mantissa, if the architecture doesn't have such a bit by * default already. */ #ifdef LDBL_IMPLICIT_NBIT #define SET_NBIT(hx) ((hx) | (1ULL << LDBL_MANH_SIZE)) #define HFRAC_BITS LDBL_MANH_SIZE #else #define SET_NBIT(hx) (hx) #define HFRAC_BITS (LDBL_MANH_SIZE - 1) #endif #define MANL_SHIFT (LDBL_MANL_SIZE - 1) static const long double one = 1.0, Zero[] = {0.0, -0.0,}; /* * fmodl(x,y) * Return x mod y in exact arithmetic * Method: shift and subtract * * Assumptions: * - The low part of the mantissa fits in a manl_t exactly. * - The high part of the mantissa fits in an int64_t with enough room * for an explicit integer bit in front of the fractional bits. */ DLLEXPORT long double fmodl(long double x, long double y) { union IEEEl2bits ux, uy; int64_t hx,hz; /* We need a carry bit even if LDBL_MANH_SIZE is 32. */ manh_t hy; manl_t lx,ly,lz; int ix,iy,n,sx; ux.e = x; uy.e = y; sx = ux.bits.sign; /* purge off exception values */ if((uy.bits.exp|uy.bits.manh|uy.bits.manl)==0 || /* y=0 */ (ux.bits.exp == BIAS + LDBL_MAX_EXP) || /* or x not finite */ (uy.bits.exp == BIAS + LDBL_MAX_EXP && ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl)!=0)) /* or y is NaN */ return (x*y)/(x*y); if(ux.bits.exp<=uy.bits.exp) { if((ux.bits.exp>MANL_SHIFT); lx = lx+lx;} else { if ((hz|lz)==0) /* return sign(x)*0 */ return Zero[sx]; hx = hz+hz+(lz>>MANL_SHIFT); lx = lz+lz; } } hz=hx-hy;lz=lx-ly; if(lx=0) {hx=hz;lx=lz;} /* convert back to floating value and restore the sign */ if((hx|lx)==0) /* return sign(x)*0 */ return Zero[sx]; while(hx<(1ULL<>MANL_SHIFT); lx = lx+lx; iy -= 1; } ux.bits.manh = hx; /* The mantissa is truncated here if needed. */ ux.bits.manl = lx; if (iy < LDBL_MIN_EXP) { ux.bits.exp = iy + (BIAS + 512); ux.e *= 0x1p-512; } else { ux.bits.exp = iy + BIAS; } x = ux.e * one; /* create necessary signal */ return x; /* exact output */ } openlibm-0.5.0/src/e_hypot.c000066400000000000000000000065561266752446200157550ustar00rootroot00000000000000 /* @(#)e_hypot.c 1.3 95/01/18 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_hypot.c,v 1.14 2011/10/15 07:00:28 das Exp $"); /* __ieee754_hypot(x,y) * * Method : * If (assume round-to-nearest) z=x*x+y*y * has error less than sqrt(2)/2 ulp, than * sqrt(z) has error less than 1 ulp (exercise). * * So, compute sqrt(x*x+y*y) with some care as * follows to get the error below 1 ulp: * * Assume x>y>0; * (if possible, set rounding to round-to-nearest) * 1. if x > 2y use * x1*x1+(y*y+(x2*(x+x1))) for x*x+y*y * where x1 = x with lower 32 bits cleared, x2 = x-x1; else * 2. if x <= 2y use * t1*y1+((x-y)*(x-y)+(t1*y2+t2*y)) * where t1 = 2x with lower 32 bits cleared, t2 = 2x-t1, * y1= y with lower 32 bits chopped, y2 = y-y1. * * NOTE: scaling may be necessary if some argument is too * large or too tiny * * Special cases: * hypot(x,y) is INF if x or y is +INF or -INF; else * hypot(x,y) is NAN if x or y is NAN. * * Accuracy: * hypot(x,y) returns sqrt(x^2+y^2) with error less * than 1 ulps (units in the last place) */ #include #include #include "math_private.h" DLLEXPORT double __ieee754_hypot(double x, double y) { double a,b,t1,t2,y1,y2,w; int32_t j,k,ha,hb; GET_HIGH_WORD(ha,x); ha &= 0x7fffffff; GET_HIGH_WORD(hb,y); hb &= 0x7fffffff; if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;} a = fabs(a); b = fabs(b); if((ha-hb)>0x3c00000) {return a+b;} /* x/y > 2**60 */ k=0; if(ha > 0x5f300000) { /* a>2**500 */ if(ha >= 0x7ff00000) { /* Inf or NaN */ u_int32_t low; /* Use original arg order iff result is NaN; quieten sNaNs. */ w = fabs(x+0.0)-fabs(y+0.0); GET_LOW_WORD(low,a); if(((ha&0xfffff)|low)==0) w = a; GET_LOW_WORD(low,b); if(((hb^0x7ff00000)|low)==0) w = b; return w; } /* scale a and b by 2**-600 */ ha -= 0x25800000; hb -= 0x25800000; k += 600; SET_HIGH_WORD(a,ha); SET_HIGH_WORD(b,hb); } if(hb < 0x20b00000) { /* b < 2**-500 */ if(hb <= 0x000fffff) { /* subnormal b or 0 */ u_int32_t low; GET_LOW_WORD(low,b); if((hb|low)==0) return a; t1=0; SET_HIGH_WORD(t1,0x7fd00000); /* t1=2^1022 */ b *= t1; a *= t1; k -= 1022; } else { /* scale a and b by 2^600 */ ha += 0x25800000; /* a *= 2^600 */ hb += 0x25800000; /* b *= 2^600 */ k -= 600; SET_HIGH_WORD(a,ha); SET_HIGH_WORD(b,hb); } } /* medium size a and b */ w = a-b; if (w>b) { t1 = 0; SET_HIGH_WORD(t1,ha); t2 = a-t1; w = sqrt(t1*t1-(b*(-b)-t2*(a+t1))); } else { a = a+a; y1 = 0; SET_HIGH_WORD(y1,hb); y2 = b - y1; t1 = 0; SET_HIGH_WORD(t1,ha+0x00100000); t2 = a - t1; w = sqrt(t1*y1-(w*(-w)-(t1*y2+t2*b))); } if(k!=0) { u_int32_t high; t1 = 1.0; GET_HIGH_WORD(high,t1); SET_HIGH_WORD(t1,high+(k<<20)); return t1*w; } else return w; } #if LDBL_MANT_DIG == 53 __weak_reference(hypot, hypotl); #endif openlibm-0.5.0/src/e_hypotf.c000066400000000000000000000043711266752446200161140ustar00rootroot00000000000000/* e_hypotf.c -- float version of e_hypot.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_hypotf.c,v 1.14 2011/10/15 07:00:28 das Exp $"); #include #include "math_private.h" DLLEXPORT float __ieee754_hypotf(float x, float y) { float a,b,t1,t2,y1,y2,w; int32_t j,k,ha,hb; GET_FLOAT_WORD(ha,x); ha &= 0x7fffffff; GET_FLOAT_WORD(hb,y); hb &= 0x7fffffff; if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;} a = fabsf(a); b = fabsf(b); if((ha-hb)>0xf000000) {return a+b;} /* x/y > 2**30 */ k=0; if(ha > 0x58800000) { /* a>2**50 */ if(ha >= 0x7f800000) { /* Inf or NaN */ /* Use original arg order iff result is NaN; quieten sNaNs. */ w = fabsf(x+0.0F)-fabsf(y+0.0F); if(ha == 0x7f800000) w = a; if(hb == 0x7f800000) w = b; return w; } /* scale a and b by 2**-68 */ ha -= 0x22000000; hb -= 0x22000000; k += 68; SET_FLOAT_WORD(a,ha); SET_FLOAT_WORD(b,hb); } if(hb < 0x26800000) { /* b < 2**-50 */ if(hb <= 0x007fffff) { /* subnormal b or 0 */ if(hb==0) return a; SET_FLOAT_WORD(t1,0x7e800000); /* t1=2^126 */ b *= t1; a *= t1; k -= 126; } else { /* scale a and b by 2^68 */ ha += 0x22000000; /* a *= 2^68 */ hb += 0x22000000; /* b *= 2^68 */ k -= 68; SET_FLOAT_WORD(a,ha); SET_FLOAT_WORD(b,hb); } } /* medium size a and b */ w = a-b; if (w>b) { SET_FLOAT_WORD(t1,ha&0xfffff000); t2 = a-t1; w = __ieee754_sqrtf(t1*t1-(b*(-b)-t2*(a+t1))); } else { a = a+a; SET_FLOAT_WORD(y1,hb&0xfffff000); y2 = b - y1; SET_FLOAT_WORD(t1,(ha+0x00800000)&0xfffff000); t2 = a - t1; w = __ieee754_sqrtf(t1*y1-(w*(-w)-(t1*y2+t2*b))); } if(k!=0) { SET_FLOAT_WORD(t1,0x3f800000+(k<<23)); return t1*w; } else return w; } openlibm-0.5.0/src/e_hypotl.c000066400000000000000000000063761266752446200161310ustar00rootroot00000000000000/* From: @(#)e_hypot.c 1.3 95/01/18 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_hypotl.c,v 1.3 2011/10/16 05:36:39 das Exp $"); /* long double version of hypot(). See e_hypot.c for most comments. */ #include #include #include "fpmath.h" #include "math_private.h" #define GET_LDBL_MAN(h, l, v) do { \ union IEEEl2bits uv; \ \ uv.e = v; \ h = uv.bits.manh; \ l = uv.bits.manl; \ } while (0) #undef GET_HIGH_WORD #define GET_HIGH_WORD(i, v) GET_LDBL_EXPSIGN(i, v) #undef SET_HIGH_WORD #define SET_HIGH_WORD(v, i) SET_LDBL_EXPSIGN(v, i) #define DESW(exp) (exp) /* delta expsign word */ #define ESW(exp) (MAX_EXP - 1 + (exp)) /* expsign word */ #define MANT_DIG LDBL_MANT_DIG #define MAX_EXP LDBL_MAX_EXP #if LDBL_MANL_SIZE > 32 typedef u_int64_t man_t; #else typedef u_int32_t man_t; #endif DLLEXPORT long double hypotl(long double x, long double y) { long double a=x,b=y,t1,t2,y1,y2,w; int32_t j,k,ha,hb; GET_HIGH_WORD(ha,x); ha &= 0x7fff; GET_HIGH_WORD(hb,y); hb &= 0x7fff; if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;} a = fabsl(a); b = fabsl(b); if((ha-hb)>DESW(MANT_DIG+7)) {return a+b;} /* x/y > 2**(MANT_DIG+7) */ k=0; if(ha > ESW(MAX_EXP/2-12)) { /* a>2**(MAX_EXP/2-12) */ if(ha >= ESW(MAX_EXP)) { /* Inf or NaN */ man_t manh, manl; /* Use original arg order iff result is NaN; quieten sNaNs. */ w = fabsl(x+0.0)-fabsl(y+0.0); GET_LDBL_MAN(manh,manl,a); if (manh == LDBL_NBIT && manl == 0) w = a; GET_LDBL_MAN(manh,manl,b); if (hb >= ESW(MAX_EXP) && manh == LDBL_NBIT && manl == 0) w = b; return w; } /* scale a and b by 2**-(MAX_EXP/2+88) */ ha -= DESW(MAX_EXP/2+88); hb -= DESW(MAX_EXP/2+88); k += MAX_EXP/2+88; SET_HIGH_WORD(a,ha); SET_HIGH_WORD(b,hb); } if(hb < ESW(-(MAX_EXP/2-12))) { /* b < 2**-(MAX_EXP/2-12) */ if(hb <= 0) { /* subnormal b or 0 */ man_t manh, manl; GET_LDBL_MAN(manh,manl,b); if((manh|manl)==0) return a; t1=0; SET_HIGH_WORD(t1,ESW(MAX_EXP-2)); /* t1=2^(MAX_EXP-2) */ b *= t1; a *= t1; k -= MAX_EXP-2; } else { /* scale a and b by 2^(MAX_EXP/2+88) */ ha += DESW(MAX_EXP/2+88); hb += DESW(MAX_EXP/2+88); k -= MAX_EXP/2+88; SET_HIGH_WORD(a,ha); SET_HIGH_WORD(b,hb); } } /* medium size a and b */ w = a-b; if (w>b) { t1 = a; union IEEEl2bits uv; uv.e = t1; uv.bits.manl = 0; t1 = uv.e; t2 = a-t1; w = sqrtl(t1*t1-(b*(-b)-t2*(a+t1))); } else { a = a+a; y1 = b; union IEEEl2bits uv; uv.e = y1; uv.bits.manl = 0; y1 = uv.e; y2 = b - y1; t1 = a; uv.e = t1; uv.bits.manl = 0; t1 = uv.e; t2 = a - t1; w = sqrtl(t1*y1-(w*(-w)-(t1*y2+t2*b))); } if(k!=0) { u_int32_t high; t1 = 1.0; GET_HIGH_WORD(high,t1); SET_HIGH_WORD(t1,high+DESW(k)); return t1*w; } else return w; } openlibm-0.5.0/src/e_j0.c000066400000000000000000000347731266752446200151250ustar00rootroot00000000000000 /* @(#)e_j0.c 1.3 95/01/18 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_j0.c,v 1.9 2008/02/22 02:30:35 das Exp $"); /* __ieee754_j0(x), __ieee754_y0(x) * Bessel function of the first and second kinds of order zero. * Method -- j0(x): * 1. For tiny x, we use j0(x) = 1 - x^2/4 + x^4/64 - ... * 2. Reduce x to |x| since j0(x)=j0(-x), and * for x in (0,2) * j0(x) = 1-z/4+ z^2*R0/S0, where z = x*x; * (precision: |j0-1+z/4-z^2R0/S0 |<2**-63.67 ) * for x in (2,inf) * j0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)-q0(x)*sin(x0)) * where x0 = x-pi/4. It is better to compute sin(x0),cos(x0) * as follow: * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4) * = 1/sqrt(2) * (cos(x) + sin(x)) * sin(x0) = sin(x)cos(pi/4)-cos(x)sin(pi/4) * = 1/sqrt(2) * (sin(x) - cos(x)) * (To avoid cancellation, use * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) * to compute the worse one.) * * 3 Special cases * j0(nan)= nan * j0(0) = 1 * j0(inf) = 0 * * Method -- y0(x): * 1. For x<2. * Since * y0(x) = 2/pi*(j0(x)*(ln(x/2)+Euler) + x^2/4 - ...) * therefore y0(x)-2/pi*j0(x)*ln(x) is an even function. * We use the following function to approximate y0, * y0(x) = U(z)/V(z) + (2/pi)*(j0(x)*ln(x)), z= x^2 * where * U(z) = u00 + u01*z + ... + u06*z^6 * V(z) = 1 + v01*z + ... + v04*z^4 * with absolute approximation error bounded by 2**-72. * Note: For tiny x, U/V = u0 and j0(x)~1, hence * y0(tiny) = u0 + (2/pi)*ln(tiny), (choose tiny<2**-27) * 2. For x>=2. * y0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)+q0(x)*sin(x0)) * where x0 = x-pi/4. It is better to compute sin(x0),cos(x0) * by the method mentioned above. * 3. Special cases: y0(0)=-inf, y0(x<0)=NaN, y0(inf)=0. */ #include #include "math_private.h" static double pzero(double), qzero(double); static const double huge = 1e300, one = 1.0, invsqrtpi= 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */ tpi = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ /* R0/S0 on [0, 2.00] */ R02 = 1.56249999999999947958e-02, /* 0x3F8FFFFF, 0xFFFFFFFD */ R03 = -1.89979294238854721751e-04, /* 0xBF28E6A5, 0xB61AC6E9 */ R04 = 1.82954049532700665670e-06, /* 0x3EBEB1D1, 0x0C503919 */ R05 = -4.61832688532103189199e-09, /* 0xBE33D5E7, 0x73D63FCE */ S01 = 1.56191029464890010492e-02, /* 0x3F8FFCE8, 0x82C8C2A4 */ S02 = 1.16926784663337450260e-04, /* 0x3F1EA6D2, 0xDD57DBF4 */ S03 = 5.13546550207318111446e-07, /* 0x3EA13B54, 0xCE84D5A9 */ S04 = 1.16614003333790000205e-09; /* 0x3E1408BC, 0xF4745D8F */ static const double zero = 0.0; DLLEXPORT double __ieee754_j0(double x) { double z, s,c,ss,cc,r,u,v; int32_t hx,ix; GET_HIGH_WORD(hx,x); ix = hx&0x7fffffff; if(ix>=0x7ff00000) return one/(x*x); x = fabs(x); if(ix >= 0x40000000) { /* |x| >= 2.0 */ s = sin(x); c = cos(x); ss = s-c; cc = s+c; if(ix<0x7fe00000) { /* make sure x+x not overflow */ z = -cos(x+x); if ((s*c)0x48000000) z = (invsqrtpi*cc)/sqrt(x); else { u = pzero(x); v = qzero(x); z = invsqrtpi*(u*cc-v*ss)/sqrt(x); } return z; } if(ix<0x3f200000) { /* |x| < 2**-13 */ if(huge+x>one) { /* raise inexact if x != 0 */ if(ix<0x3e400000) return one; /* |x|<2**-27 */ else return one - 0.25*x*x; } } z = x*x; r = z*(R02+z*(R03+z*(R04+z*R05))); s = one+z*(S01+z*(S02+z*(S03+z*S04))); if(ix < 0x3FF00000) { /* |x| < 1.00 */ return one + z*(-0.25+(r/s)); } else { u = 0.5*x; return((one+u)*(one-u)+z*(r/s)); } } static const double u00 = -7.38042951086872317523e-02, /* 0xBFB2E4D6, 0x99CBD01F */ u01 = 1.76666452509181115538e-01, /* 0x3FC69D01, 0x9DE9E3FC */ u02 = -1.38185671945596898896e-02, /* 0xBF8C4CE8, 0xB16CFA97 */ u03 = 3.47453432093683650238e-04, /* 0x3F36C54D, 0x20B29B6B */ u04 = -3.81407053724364161125e-06, /* 0xBECFFEA7, 0x73D25CAD */ u05 = 1.95590137035022920206e-08, /* 0x3E550057, 0x3B4EABD4 */ u06 = -3.98205194132103398453e-11, /* 0xBDC5E43D, 0x693FB3C8 */ v01 = 1.27304834834123699328e-02, /* 0x3F8A1270, 0x91C9C71A */ v02 = 7.60068627350353253702e-05, /* 0x3F13ECBB, 0xF578C6C1 */ v03 = 2.59150851840457805467e-07, /* 0x3E91642D, 0x7FF202FD */ v04 = 4.41110311332675467403e-10; /* 0x3DFE5018, 0x3BD6D9EF */ DLLEXPORT double __ieee754_y0(double x) { double z, s,c,ss,cc,u,v; int32_t hx,ix,lx; EXTRACT_WORDS(hx,lx,x); ix = 0x7fffffff&hx; /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0 */ if(ix>=0x7ff00000) return one/(x+x*x); if((ix|lx)==0) return -one/zero; if(hx<0) return zero/zero; if(ix >= 0x40000000) { /* |x| >= 2.0 */ /* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0)) * where x0 = x-pi/4 * Better formula: * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4) * = 1/sqrt(2) * (sin(x) + cos(x)) * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) * = 1/sqrt(2) * (sin(x) - cos(x)) * To avoid cancellation, use * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) * to compute the worse one. */ s = sin(x); c = cos(x); ss = s-c; cc = s+c; /* * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x) * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x) */ if(ix<0x7fe00000) { /* make sure x+x not overflow */ z = -cos(x+x); if ((s*c)0x48000000) z = (invsqrtpi*ss)/sqrt(x); else { u = pzero(x); v = qzero(x); z = invsqrtpi*(u*ss+v*cc)/sqrt(x); } return z; } if(ix<=0x3e400000) { /* x < 2**-27 */ return(u00 + tpi*__ieee754_log(x)); } z = x*x; u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06))))); v = one+z*(v01+z*(v02+z*(v03+z*v04))); return(u/v + tpi*(__ieee754_j0(x)*__ieee754_log(x))); } /* The asymptotic expansions of pzero is * 1 - 9/128 s^2 + 11025/98304 s^4 - ..., where s = 1/x. * For x >= 2, We approximate pzero by * pzero(x) = 1 + (R/S) * where R = pR0 + pR1*s^2 + pR2*s^4 + ... + pR5*s^10 * S = 1 + pS0*s^2 + ... + pS4*s^10 * and * | pzero(x)-1-R/S | <= 2 ** ( -60.26) */ static const double pR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ -7.03124999999900357484e-02, /* 0xBFB1FFFF, 0xFFFFFD32 */ -8.08167041275349795626e+00, /* 0xC02029D0, 0xB44FA779 */ -2.57063105679704847262e+02, /* 0xC0701102, 0x7B19E863 */ -2.48521641009428822144e+03, /* 0xC0A36A6E, 0xCD4DCAFC */ -5.25304380490729545272e+03, /* 0xC0B4850B, 0x36CC643D */ }; static const double pS8[5] = { 1.16534364619668181717e+02, /* 0x405D2233, 0x07A96751 */ 3.83374475364121826715e+03, /* 0x40ADF37D, 0x50596938 */ 4.05978572648472545552e+04, /* 0x40E3D2BB, 0x6EB6B05F */ 1.16752972564375915681e+05, /* 0x40FC810F, 0x8F9FA9BD */ 4.76277284146730962675e+04, /* 0x40E74177, 0x4F2C49DC */ }; static const double pR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ -1.14125464691894502584e-11, /* 0xBDA918B1, 0x47E495CC */ -7.03124940873599280078e-02, /* 0xBFB1FFFF, 0xE69AFBC6 */ -4.15961064470587782438e+00, /* 0xC010A370, 0xF90C6BBF */ -6.76747652265167261021e+01, /* 0xC050EB2F, 0x5A7D1783 */ -3.31231299649172967747e+02, /* 0xC074B3B3, 0x6742CC63 */ -3.46433388365604912451e+02, /* 0xC075A6EF, 0x28A38BD7 */ }; static const double pS5[5] = { 6.07539382692300335975e+01, /* 0x404E6081, 0x0C98C5DE */ 1.05125230595704579173e+03, /* 0x40906D02, 0x5C7E2864 */ 5.97897094333855784498e+03, /* 0x40B75AF8, 0x8FBE1D60 */ 9.62544514357774460223e+03, /* 0x40C2CCB8, 0xFA76FA38 */ 2.40605815922939109441e+03, /* 0x40A2CC1D, 0xC70BE864 */ }; static const double pR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */ -2.54704601771951915620e-09, /* 0xBE25E103, 0x6FE1AA86 */ -7.03119616381481654654e-02, /* 0xBFB1FFF6, 0xF7C0E24B */ -2.40903221549529611423e+00, /* 0xC00345B2, 0xAEA48074 */ -2.19659774734883086467e+01, /* 0xC035F74A, 0x4CB94E14 */ -5.80791704701737572236e+01, /* 0xC04D0A22, 0x420A1A45 */ -3.14479470594888503854e+01, /* 0xC03F72AC, 0xA892D80F */ }; static const double pS3[5] = { 3.58560338055209726349e+01, /* 0x4041ED92, 0x84077DD3 */ 3.61513983050303863820e+02, /* 0x40769839, 0x464A7C0E */ 1.19360783792111533330e+03, /* 0x4092A66E, 0x6D1061D6 */ 1.12799679856907414432e+03, /* 0x40919FFC, 0xB8C39B7E */ 1.73580930813335754692e+02, /* 0x4065B296, 0xFC379081 */ }; static const double pR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ -8.87534333032526411254e-08, /* 0xBE77D316, 0xE927026D */ -7.03030995483624743247e-02, /* 0xBFB1FF62, 0x495E1E42 */ -1.45073846780952986357e+00, /* 0xBFF73639, 0x8A24A843 */ -7.63569613823527770791e+00, /* 0xC01E8AF3, 0xEDAFA7F3 */ -1.11931668860356747786e+01, /* 0xC02662E6, 0xC5246303 */ -3.23364579351335335033e+00, /* 0xC009DE81, 0xAF8FE70F */ }; static const double pS2[5] = { 2.22202997532088808441e+01, /* 0x40363865, 0x908B5959 */ 1.36206794218215208048e+02, /* 0x4061069E, 0x0EE8878F */ 2.70470278658083486789e+02, /* 0x4070E786, 0x42EA079B */ 1.53875394208320329881e+02, /* 0x40633C03, 0x3AB6FAFF */ 1.46576176948256193810e+01, /* 0x402D50B3, 0x44391809 */ }; /* Note: This function is only called for ix>=0x40000000 (see above) */ static double pzero(double x) { const double *p,*q; double z,r,s; int32_t ix; GET_HIGH_WORD(ix,x); ix &= 0x7fffffff; assert(ix>=0x40000000 && ix<=0x48000000); if(ix>=0x40200000) {p = pR8; q= pS8;} else if(ix>=0x40122E8B){p = pR5; q= pS5;} else if(ix>=0x4006DB6D){p = pR3; q= pS3;} else {p = pR2; q= pS2;} z = one/(x*x); r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4])))); return one+ r/s; } /* For x >= 8, the asymptotic expansions of qzero is * -1/8 s + 75/1024 s^3 - ..., where s = 1/x. * We approximate pzero by * qzero(x) = s*(-1.25 + (R/S)) * where R = qR0 + qR1*s^2 + qR2*s^4 + ... + qR5*s^10 * S = 1 + qS0*s^2 + ... + qS5*s^12 * and * | qzero(x)/s +1.25-R/S | <= 2 ** ( -61.22) */ static const double qR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ 7.32421874999935051953e-02, /* 0x3FB2BFFF, 0xFFFFFE2C */ 1.17682064682252693899e+01, /* 0x40278952, 0x5BB334D6 */ 5.57673380256401856059e+02, /* 0x40816D63, 0x15301825 */ 8.85919720756468632317e+03, /* 0x40C14D99, 0x3E18F46D */ 3.70146267776887834771e+04, /* 0x40E212D4, 0x0E901566 */ }; static const double qS8[6] = { 1.63776026895689824414e+02, /* 0x406478D5, 0x365B39BC */ 8.09834494656449805916e+03, /* 0x40BFA258, 0x4E6B0563 */ 1.42538291419120476348e+05, /* 0x41016652, 0x54D38C3F */ 8.03309257119514397345e+05, /* 0x412883DA, 0x83A52B43 */ 8.40501579819060512818e+05, /* 0x4129A66B, 0x28DE0B3D */ -3.43899293537866615225e+05, /* 0xC114FD6D, 0x2C9530C5 */ }; static const double qR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ 1.84085963594515531381e-11, /* 0x3DB43D8F, 0x29CC8CD9 */ 7.32421766612684765896e-02, /* 0x3FB2BFFF, 0xD172B04C */ 5.83563508962056953777e+00, /* 0x401757B0, 0xB9953DD3 */ 1.35111577286449829671e+02, /* 0x4060E392, 0x0A8788E9 */ 1.02724376596164097464e+03, /* 0x40900CF9, 0x9DC8C481 */ 1.98997785864605384631e+03, /* 0x409F17E9, 0x53C6E3A6 */ }; static const double qS5[6] = { 8.27766102236537761883e+01, /* 0x4054B1B3, 0xFB5E1543 */ 2.07781416421392987104e+03, /* 0x40A03BA0, 0xDA21C0CE */ 1.88472887785718085070e+04, /* 0x40D267D2, 0x7B591E6D */ 5.67511122894947329769e+04, /* 0x40EBB5E3, 0x97E02372 */ 3.59767538425114471465e+04, /* 0x40E19118, 0x1F7A54A0 */ -5.35434275601944773371e+03, /* 0xC0B4EA57, 0xBEDBC609 */ }; static const double qR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */ 4.37741014089738620906e-09, /* 0x3E32CD03, 0x6ADECB82 */ 7.32411180042911447163e-02, /* 0x3FB2BFEE, 0x0E8D0842 */ 3.34423137516170720929e+00, /* 0x400AC0FC, 0x61149CF5 */ 4.26218440745412650017e+01, /* 0x40454F98, 0x962DAEDD */ 1.70808091340565596283e+02, /* 0x406559DB, 0xE25EFD1F */ 1.66733948696651168575e+02, /* 0x4064D77C, 0x81FA21E0 */ }; static const double qS3[6] = { 4.87588729724587182091e+01, /* 0x40486122, 0xBFE343A6 */ 7.09689221056606015736e+02, /* 0x40862D83, 0x86544EB3 */ 3.70414822620111362994e+03, /* 0x40ACF04B, 0xE44DFC63 */ 6.46042516752568917582e+03, /* 0x40B93C6C, 0xD7C76A28 */ 2.51633368920368957333e+03, /* 0x40A3A8AA, 0xD94FB1C0 */ -1.49247451836156386662e+02, /* 0xC062A7EB, 0x201CF40F */ }; static const double qR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ 1.50444444886983272379e-07, /* 0x3E84313B, 0x54F76BDB */ 7.32234265963079278272e-02, /* 0x3FB2BEC5, 0x3E883E34 */ 1.99819174093815998816e+00, /* 0x3FFFF897, 0xE727779C */ 1.44956029347885735348e+01, /* 0x402CFDBF, 0xAAF96FE5 */ 3.16662317504781540833e+01, /* 0x403FAA8E, 0x29FBDC4A */ 1.62527075710929267416e+01, /* 0x403040B1, 0x71814BB4 */ }; static const double qS2[6] = { 3.03655848355219184498e+01, /* 0x403E5D96, 0xF7C07AED */ 2.69348118608049844624e+02, /* 0x4070D591, 0xE4D14B40 */ 8.44783757595320139444e+02, /* 0x408A6645, 0x22B3BF22 */ 8.82935845112488550512e+02, /* 0x408B977C, 0x9C5CC214 */ 2.12666388511798828631e+02, /* 0x406A9553, 0x0E001365 */ -5.31095493882666946917e+00, /* 0xC0153E6A, 0xF8B32931 */ }; /* Note: This function is only called for ix>=0x40000000 (see above) */ static double qzero(double x) { const double *p,*q; double s,r,z; int32_t ix; GET_HIGH_WORD(ix,x); ix &= 0x7fffffff; assert(ix>=0x40000000 && ix<=0x48000000); if(ix>=0x40200000) {p = qR8; q= qS8;} else if(ix>=0x40122E8B){p = qR5; q= qS5;} else if(ix>=0x4006DB6D){p = qR3; q= qS3;} else {p = qR2; q= qS2;} z = one/(x*x); r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5]))))); return (-.125 + r/s)/x; } openlibm-0.5.0/src/e_j0f.c000066400000000000000000000244501266752446200152620ustar00rootroot00000000000000/* e_j0f.c -- float version of e_j0.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 #include "cdefs-compat.h" #include #include "math_private.h" static float pzerof(float), qzerof(float); static const float huge = 1e30, one = 1.0, invsqrtpi= 5.6418961287e-01, /* 0x3f106ebb */ tpi = 6.3661974669e-01, /* 0x3f22f983 */ /* R0/S0 on [0, 2.00] */ R02 = 1.5625000000e-02, /* 0x3c800000 */ R03 = -1.8997929874e-04, /* 0xb947352e */ R04 = 1.8295404516e-06, /* 0x35f58e88 */ R05 = -4.6183270541e-09, /* 0xb19eaf3c */ S01 = 1.5619102865e-02, /* 0x3c7fe744 */ S02 = 1.1692678527e-04, /* 0x38f53697 */ S03 = 5.1354652442e-07, /* 0x3509daa6 */ S04 = 1.1661400734e-09; /* 0x30a045e8 */ static const float zero = 0.0; DLLEXPORT float __ieee754_j0f(float x) { float z, s,c,ss,cc,r,u,v; int32_t hx,ix; GET_FLOAT_WORD(hx,x); ix = hx&0x7fffffff; if(ix>=0x7f800000) return one/(x*x); x = fabsf(x); if(ix >= 0x40000000) { /* |x| >= 2.0 */ s = sinf(x); c = cosf(x); ss = s-c; cc = s+c; if(ix<0x7f000000) { /* make sure x+x not overflow */ z = -cosf(x+x); if ((s*c)0x58000000) z = (invsqrtpi*cc)/sqrtf(x); /* |x|>2**49 */ else { u = pzerof(x); v = qzerof(x); z = invsqrtpi*(u*cc-v*ss)/sqrtf(x); } return z; } if(ix<0x3b000000) { /* |x| < 2**-9 */ if(huge+x>one) { /* raise inexact if x != 0 */ if(ix<0x39800000) return one; /* |x|<2**-12 */ else return one - x*x/4; } } z = x*x; r = z*(R02+z*(R03+z*(R04+z*R05))); s = one+z*(S01+z*(S02+z*(S03+z*S04))); if(ix < 0x3F800000) { /* |x| < 1.00 */ return one + z*((float)-0.25+(r/s)); } else { u = (float)0.5*x; return((one+u)*(one-u)+z*(r/s)); } } static const float u00 = -7.3804296553e-02, /* 0xbd9726b5 */ u01 = 1.7666645348e-01, /* 0x3e34e80d */ u02 = -1.3818567619e-02, /* 0xbc626746 */ u03 = 3.4745343146e-04, /* 0x39b62a69 */ u04 = -3.8140706238e-06, /* 0xb67ff53c */ u05 = 1.9559013964e-08, /* 0x32a802ba */ u06 = -3.9820518410e-11, /* 0xae2f21eb */ v01 = 1.2730483897e-02, /* 0x3c509385 */ v02 = 7.6006865129e-05, /* 0x389f65e0 */ v03 = 2.5915085189e-07, /* 0x348b216c */ v04 = 4.4111031494e-10; /* 0x2ff280c2 */ DLLEXPORT float __ieee754_y0f(float x) { float z, s,c,ss,cc,u,v; int32_t hx,ix; GET_FLOAT_WORD(hx,x); ix = 0x7fffffff&hx; /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0 */ if(ix>=0x7f800000) return one/(x+x*x); if(ix==0) return -one/zero; if(hx<0) return zero/zero; if(ix >= 0x40000000) { /* |x| >= 2.0 */ /* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0)) * where x0 = x-pi/4 * Better formula: * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4) * = 1/sqrt(2) * (sin(x) + cos(x)) * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) * = 1/sqrt(2) * (sin(x) - cos(x)) * To avoid cancellation, use * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) * to compute the worse one. */ s = sinf(x); c = cosf(x); ss = s-c; cc = s+c; /* * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x) * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x) */ if(ix<0x7f000000) { /* make sure x+x not overflow */ z = -cosf(x+x); if ((s*c)0x58000000) z = (invsqrtpi*ss)/sqrtf(x); /* |x|>2**49 */ else { u = pzerof(x); v = qzerof(x); z = invsqrtpi*(u*ss+v*cc)/sqrtf(x); } return z; } if(ix<=0x39000000) { /* x < 2**-13 */ return(u00 + tpi*__ieee754_logf(x)); } z = x*x; u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06))))); v = one+z*(v01+z*(v02+z*(v03+z*v04))); return(u/v + tpi*(__ieee754_j0f(x)*__ieee754_logf(x))); } /* The asymptotic expansions of pzero is * 1 - 9/128 s^2 + 11025/98304 s^4 - ..., where s = 1/x. * For x >= 2, We approximate pzero by * pzero(x) = 1 + (R/S) * where R = pR0 + pR1*s^2 + pR2*s^4 + ... + pR5*s^10 * S = 1 + pS0*s^2 + ... + pS4*s^10 * and * | pzero(x)-1-R/S | <= 2 ** ( -60.26) */ static const float pR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ 0.0000000000e+00, /* 0x00000000 */ -7.0312500000e-02, /* 0xbd900000 */ -8.0816707611e+00, /* 0xc1014e86 */ -2.5706311035e+02, /* 0xc3808814 */ -2.4852163086e+03, /* 0xc51b5376 */ -5.2530439453e+03, /* 0xc5a4285a */ }; static const float pS8[5] = { 1.1653436279e+02, /* 0x42e91198 */ 3.8337448730e+03, /* 0x456f9beb */ 4.0597855469e+04, /* 0x471e95db */ 1.1675296875e+05, /* 0x47e4087c */ 4.7627726562e+04, /* 0x473a0bba */ }; static const float pR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ -1.1412546255e-11, /* 0xad48c58a */ -7.0312492549e-02, /* 0xbd8fffff */ -4.1596107483e+00, /* 0xc0851b88 */ -6.7674766541e+01, /* 0xc287597b */ -3.3123129272e+02, /* 0xc3a59d9b */ -3.4643338013e+02, /* 0xc3ad3779 */ }; static const float pS5[5] = { 6.0753936768e+01, /* 0x42730408 */ 1.0512523193e+03, /* 0x44836813 */ 5.9789707031e+03, /* 0x45bad7c4 */ 9.6254453125e+03, /* 0x461665c8 */ 2.4060581055e+03, /* 0x451660ee */ }; static const float pR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */ -2.5470459075e-09, /* 0xb12f081b */ -7.0311963558e-02, /* 0xbd8fffb8 */ -2.4090321064e+00, /* 0xc01a2d95 */ -2.1965976715e+01, /* 0xc1afba52 */ -5.8079170227e+01, /* 0xc2685112 */ -3.1447946548e+01, /* 0xc1fb9565 */ }; static const float pS3[5] = { 3.5856033325e+01, /* 0x420f6c94 */ 3.6151397705e+02, /* 0x43b4c1ca */ 1.1936077881e+03, /* 0x44953373 */ 1.1279968262e+03, /* 0x448cffe6 */ 1.7358093262e+02, /* 0x432d94b8 */ }; static const float pR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ -8.8753431271e-08, /* 0xb3be98b7 */ -7.0303097367e-02, /* 0xbd8ffb12 */ -1.4507384300e+00, /* 0xbfb9b1cc */ -7.6356959343e+00, /* 0xc0f4579f */ -1.1193166733e+01, /* 0xc1331736 */ -3.2336456776e+00, /* 0xc04ef40d */ }; static const float pS2[5] = { 2.2220300674e+01, /* 0x41b1c32d */ 1.3620678711e+02, /* 0x430834f0 */ 2.7047027588e+02, /* 0x43873c32 */ 1.5387539673e+02, /* 0x4319e01a */ 1.4657617569e+01, /* 0x416a859a */ }; static float pzerof(float x) { const float *p,*q; float z,r,s; int32_t ix; GET_FLOAT_WORD(ix,x); ix &= 0x7fffffff; if(ix>=0x41000000) {p = pR8; q= pS8;} else if(ix>=0x409173eb){p = pR5; q= pS5;} else if(ix>=0x4036d917){p = pR3; q= pS3;} else {p = pR2; q= pS2;} /* ix>=0x40000000 */ z = one/(x*x); r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4])))); return one+ r/s; } /* For x >= 8, the asymptotic expansions of qzero is * -1/8 s + 75/1024 s^3 - ..., where s = 1/x. * We approximate pzero by * qzero(x) = s*(-1.25 + (R/S)) * where R = qR0 + qR1*s^2 + qR2*s^4 + ... + qR5*s^10 * S = 1 + qS0*s^2 + ... + qS5*s^12 * and * | qzero(x)/s +1.25-R/S | <= 2 ** ( -61.22) */ static const float qR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ 0.0000000000e+00, /* 0x00000000 */ 7.3242187500e-02, /* 0x3d960000 */ 1.1768206596e+01, /* 0x413c4a93 */ 5.5767340088e+02, /* 0x440b6b19 */ 8.8591972656e+03, /* 0x460a6cca */ 3.7014625000e+04, /* 0x471096a0 */ }; static const float qS8[6] = { 1.6377603149e+02, /* 0x4323c6aa */ 8.0983447266e+03, /* 0x45fd12c2 */ 1.4253829688e+05, /* 0x480b3293 */ 8.0330925000e+05, /* 0x49441ed4 */ 8.4050156250e+05, /* 0x494d3359 */ -3.4389928125e+05, /* 0xc8a7eb69 */ }; static const float qR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ 1.8408595828e-11, /* 0x2da1ec79 */ 7.3242180049e-02, /* 0x3d95ffff */ 5.8356351852e+00, /* 0x40babd86 */ 1.3511157227e+02, /* 0x43071c90 */ 1.0272437744e+03, /* 0x448067cd */ 1.9899779053e+03, /* 0x44f8bf4b */ }; static const float qS5[6] = { 8.2776611328e+01, /* 0x42a58da0 */ 2.0778142090e+03, /* 0x4501dd07 */ 1.8847289062e+04, /* 0x46933e94 */ 5.6751113281e+04, /* 0x475daf1d */ 3.5976753906e+04, /* 0x470c88c1 */ -5.3543427734e+03, /* 0xc5a752be */ }; static const float qR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */ 4.3774099900e-09, /* 0x3196681b */ 7.3241114616e-02, /* 0x3d95ff70 */ 3.3442313671e+00, /* 0x405607e3 */ 4.2621845245e+01, /* 0x422a7cc5 */ 1.7080809021e+02, /* 0x432acedf */ 1.6673394775e+02, /* 0x4326bbe4 */ }; static const float qS3[6] = { 4.8758872986e+01, /* 0x42430916 */ 7.0968920898e+02, /* 0x44316c1c */ 3.7041481934e+03, /* 0x4567825f */ 6.4604252930e+03, /* 0x45c9e367 */ 2.5163337402e+03, /* 0x451d4557 */ -1.4924745178e+02, /* 0xc3153f59 */ }; static const float qR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ 1.5044444979e-07, /* 0x342189db */ 7.3223426938e-02, /* 0x3d95f62a */ 1.9981917143e+00, /* 0x3fffc4bf */ 1.4495602608e+01, /* 0x4167edfd */ 3.1666231155e+01, /* 0x41fd5471 */ 1.6252708435e+01, /* 0x4182058c */ }; static const float qS2[6] = { 3.0365585327e+01, /* 0x41f2ecb8 */ 2.6934811401e+02, /* 0x4386ac8f */ 8.4478375244e+02, /* 0x44533229 */ 8.8293585205e+02, /* 0x445cbbe5 */ 2.1266638184e+02, /* 0x4354aa98 */ -5.3109550476e+00, /* 0xc0a9f358 */ }; static float qzerof(float x) { const float *p,*q; float s,r,z; int32_t ix; GET_FLOAT_WORD(ix,x); ix &= 0x7fffffff; if(ix>=0x41000000) {p = qR8; q= qS8;} else if(ix>=0x409173eb){p = qR5; q= qS5;} else if(ix>=0x4036d917){p = qR3; q= qS3;} else {p = qR2; q= qS2;} /* ix>=0x40000000 */ z = one/(x*x); r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5]))))); return (-(float).125 + r/s)/x; } openlibm-0.5.0/src/e_j1.c000066400000000000000000000344231266752446200151160ustar00rootroot00000000000000 /* @(#)e_j1.c 1.3 95/01/18 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_j1.c,v 1.9 2008/02/22 02:30:35 das Exp $"); /* __ieee754_j1(x), __ieee754_y1(x) * Bessel function of the first and second kinds of order zero. * Method -- j1(x): * 1. For tiny x, we use j1(x) = x/2 - x^3/16 + x^5/384 - ... * 2. Reduce x to |x| since j1(x)=-j1(-x), and * for x in (0,2) * j1(x) = x/2 + x*z*R0/S0, where z = x*x; * (precision: |j1/x - 1/2 - R0/S0 |<2**-61.51 ) * for x in (2,inf) * j1(x) = sqrt(2/(pi*x))*(p1(x)*cos(x1)-q1(x)*sin(x1)) * y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1)) * where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1) * as follow: * cos(x1) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4) * = 1/sqrt(2) * (sin(x) - cos(x)) * sin(x1) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) * = -1/sqrt(2) * (sin(x) + cos(x)) * (To avoid cancellation, use * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) * to compute the worse one.) * * 3 Special cases * j1(nan)= nan * j1(0) = 0 * j1(inf) = 0 * * Method -- y1(x): * 1. screen out x<=0 cases: y1(0)=-inf, y1(x<0)=NaN * 2. For x<2. * Since * y1(x) = 2/pi*(j1(x)*(ln(x/2)+Euler)-1/x-x/2+5/64*x^3-...) * therefore y1(x)-2/pi*j1(x)*ln(x)-1/x is an odd function. * We use the following function to approximate y1, * y1(x) = x*U(z)/V(z) + (2/pi)*(j1(x)*ln(x)-1/x), z= x^2 * where for x in [0,2] (abs err less than 2**-65.89) * U(z) = U0[0] + U0[1]*z + ... + U0[4]*z^4 * V(z) = 1 + v0[0]*z + ... + v0[4]*z^5 * Note: For tiny x, 1/x dominate y1 and hence * y1(tiny) = -2/pi/tiny, (choose tiny<2**-54) * 3. For x>=2. * y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1)) * where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1) * by method mentioned above. */ #include #include "math_private.h" static double pone(double), qone(double); static const double huge = 1e300, one = 1.0, invsqrtpi= 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */ tpi = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ /* R0/S0 on [0,2] */ r00 = -6.25000000000000000000e-02, /* 0xBFB00000, 0x00000000 */ r01 = 1.40705666955189706048e-03, /* 0x3F570D9F, 0x98472C61 */ r02 = -1.59955631084035597520e-05, /* 0xBEF0C5C6, 0xBA169668 */ r03 = 4.96727999609584448412e-08, /* 0x3E6AAAFA, 0x46CA0BD9 */ s01 = 1.91537599538363460805e-02, /* 0x3F939D0B, 0x12637E53 */ s02 = 1.85946785588630915560e-04, /* 0x3F285F56, 0xB9CDF664 */ s03 = 1.17718464042623683263e-06, /* 0x3EB3BFF8, 0x333F8498 */ s04 = 5.04636257076217042715e-09, /* 0x3E35AC88, 0xC97DFF2C */ s05 = 1.23542274426137913908e-11; /* 0x3DAB2ACF, 0xCFB97ED8 */ static const double zero = 0.0; DLLEXPORT double __ieee754_j1(double x) { double z, s,c,ss,cc,r,u,v,y; int32_t hx,ix; GET_HIGH_WORD(hx,x); ix = hx&0x7fffffff; if(ix>=0x7ff00000) return one/x; y = fabs(x); if(ix >= 0x40000000) { /* |x| >= 2.0 */ s = sin(y); c = cos(y); ss = -s-c; cc = s-c; if(ix<0x7fe00000) { /* make sure y+y not overflow */ z = cos(y+y); if ((s*c)>zero) cc = z/ss; else ss = z/cc; } /* * j1(x) = 1/sqrt(pi) * (P(1,x)*cc - Q(1,x)*ss) / sqrt(x) * y1(x) = 1/sqrt(pi) * (P(1,x)*ss + Q(1,x)*cc) / sqrt(x) */ if(ix>0x48000000) z = (invsqrtpi*cc)/sqrt(y); else { u = pone(y); v = qone(y); z = invsqrtpi*(u*cc-v*ss)/sqrt(y); } if(hx<0) return -z; else return z; } if(ix<0x3e400000) { /* |x|<2**-27 */ if(huge+x>one) return 0.5*x;/* inexact if x!=0 necessary */ } z = x*x; r = z*(r00+z*(r01+z*(r02+z*r03))); s = one+z*(s01+z*(s02+z*(s03+z*(s04+z*s05)))); r *= x; return(x*0.5+r/s); } static const double U0[5] = { -1.96057090646238940668e-01, /* 0xBFC91866, 0x143CBC8A */ 5.04438716639811282616e-02, /* 0x3FA9D3C7, 0x76292CD1 */ -1.91256895875763547298e-03, /* 0xBF5F55E5, 0x4844F50F */ 2.35252600561610495928e-05, /* 0x3EF8AB03, 0x8FA6B88E */ -9.19099158039878874504e-08, /* 0xBE78AC00, 0x569105B8 */ }; static const double V0[5] = { 1.99167318236649903973e-02, /* 0x3F94650D, 0x3F4DA9F0 */ 2.02552581025135171496e-04, /* 0x3F2A8C89, 0x6C257764 */ 1.35608801097516229404e-06, /* 0x3EB6C05A, 0x894E8CA6 */ 6.22741452364621501295e-09, /* 0x3E3ABF1D, 0x5BA69A86 */ 1.66559246207992079114e-11, /* 0x3DB25039, 0xDACA772A */ }; DLLEXPORT double __ieee754_y1(double x) { double z, s,c,ss,cc,u,v; int32_t hx,ix,lx; EXTRACT_WORDS(hx,lx,x); ix = 0x7fffffff&hx; /* if Y1(NaN) is NaN, Y1(-inf) is NaN, Y1(inf) is 0 */ if(ix>=0x7ff00000) return one/(x+x*x); if((ix|lx)==0) return -one/zero; if(hx<0) return zero/zero; if(ix >= 0x40000000) { /* |x| >= 2.0 */ s = sin(x); c = cos(x); ss = -s-c; cc = s-c; if(ix<0x7fe00000) { /* make sure x+x not overflow */ z = cos(x+x); if ((s*c)>zero) cc = z/ss; else ss = z/cc; } /* y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x0)+q1(x)*cos(x0)) * where x0 = x-3pi/4 * Better formula: * cos(x0) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4) * = 1/sqrt(2) * (sin(x) - cos(x)) * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) * = -1/sqrt(2) * (cos(x) + sin(x)) * To avoid cancellation, use * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) * to compute the worse one. */ if(ix>0x48000000) z = (invsqrtpi*ss)/sqrt(x); else { u = pone(x); v = qone(x); z = invsqrtpi*(u*ss+v*cc)/sqrt(x); } return z; } if(ix<=0x3c900000) { /* x < 2**-54 */ return(-tpi/x); } z = x*x; u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4]))); v = one+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4])))); return(x*(u/v) + tpi*(__ieee754_j1(x)*__ieee754_log(x)-one/x)); } /* For x >= 8, the asymptotic expansions of pone is * 1 + 15/128 s^2 - 4725/2^15 s^4 - ..., where s = 1/x. * We approximate pone by * pone(x) = 1 + (R/S) * where R = pr0 + pr1*s^2 + pr2*s^4 + ... + pr5*s^10 * S = 1 + ps0*s^2 + ... + ps4*s^10 * and * | pone(x)-1-R/S | <= 2 ** ( -60.06) */ static const double pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ 1.17187499999988647970e-01, /* 0x3FBDFFFF, 0xFFFFFCCE */ 1.32394806593073575129e+01, /* 0x402A7A9D, 0x357F7FCE */ 4.12051854307378562225e+02, /* 0x4079C0D4, 0x652EA590 */ 3.87474538913960532227e+03, /* 0x40AE457D, 0xA3A532CC */ 7.91447954031891731574e+03, /* 0x40BEEA7A, 0xC32782DD */ }; static const double ps8[5] = { 1.14207370375678408436e+02, /* 0x405C8D45, 0x8E656CAC */ 3.65093083420853463394e+03, /* 0x40AC85DC, 0x964D274F */ 3.69562060269033463555e+04, /* 0x40E20B86, 0x97C5BB7F */ 9.76027935934950801311e+04, /* 0x40F7D42C, 0xB28F17BB */ 3.08042720627888811578e+04, /* 0x40DE1511, 0x697A0B2D */ }; static const double pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ 1.31990519556243522749e-11, /* 0x3DAD0667, 0xDAE1CA7D */ 1.17187493190614097638e-01, /* 0x3FBDFFFF, 0xE2C10043 */ 6.80275127868432871736e+00, /* 0x401B3604, 0x6E6315E3 */ 1.08308182990189109773e+02, /* 0x405B13B9, 0x452602ED */ 5.17636139533199752805e+02, /* 0x40802D16, 0xD052D649 */ 5.28715201363337541807e+02, /* 0x408085B8, 0xBB7E0CB7 */ }; static const double ps5[5] = { 5.92805987221131331921e+01, /* 0x404DA3EA, 0xA8AF633D */ 9.91401418733614377743e+02, /* 0x408EFB36, 0x1B066701 */ 5.35326695291487976647e+03, /* 0x40B4E944, 0x5706B6FB */ 7.84469031749551231769e+03, /* 0x40BEA4B0, 0xB8A5BB15 */ 1.50404688810361062679e+03, /* 0x40978030, 0x036F5E51 */ }; static const double pr3[6] = { 3.02503916137373618024e-09, /* 0x3E29FC21, 0xA7AD9EDD */ 1.17186865567253592491e-01, /* 0x3FBDFFF5, 0x5B21D17B */ 3.93297750033315640650e+00, /* 0x400F76BC, 0xE85EAD8A */ 3.51194035591636932736e+01, /* 0x40418F48, 0x9DA6D129 */ 9.10550110750781271918e+01, /* 0x4056C385, 0x4D2C1837 */ 4.85590685197364919645e+01, /* 0x4048478F, 0x8EA83EE5 */ }; static const double ps3[5] = { 3.47913095001251519989e+01, /* 0x40416549, 0xA134069C */ 3.36762458747825746741e+02, /* 0x40750C33, 0x07F1A75F */ 1.04687139975775130551e+03, /* 0x40905B7C, 0x5037D523 */ 8.90811346398256432622e+02, /* 0x408BD67D, 0xA32E31E9 */ 1.03787932439639277504e+02, /* 0x4059F26D, 0x7C2EED53 */ }; static const double pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ 1.07710830106873743082e-07, /* 0x3E7CE9D4, 0xF65544F4 */ 1.17176219462683348094e-01, /* 0x3FBDFF42, 0xBE760D83 */ 2.36851496667608785174e+00, /* 0x4002F2B7, 0xF98FAEC0 */ 1.22426109148261232917e+01, /* 0x40287C37, 0x7F71A964 */ 1.76939711271687727390e+01, /* 0x4031B1A8, 0x177F8EE2 */ 5.07352312588818499250e+00, /* 0x40144B49, 0xA574C1FE */ }; static const double ps2[5] = { 2.14364859363821409488e+01, /* 0x40356FBD, 0x8AD5ECDC */ 1.25290227168402751090e+02, /* 0x405F5293, 0x14F92CD5 */ 2.32276469057162813669e+02, /* 0x406D08D8, 0xD5A2DBD9 */ 1.17679373287147100768e+02, /* 0x405D6B7A, 0xDA1884A9 */ 8.36463893371618283368e+00, /* 0x4020BAB1, 0xF44E5192 */ }; /* Note: This function is only called for ix>=0x40000000 (see above) */ static double pone(double x) { const double *p,*q; double z,r,s; int32_t ix; GET_HIGH_WORD(ix,x); ix &= 0x7fffffff; assert(ix>=0x40000000 && ix<=0x48000000); if(ix>=0x40200000) {p = pr8; q= ps8;} else if(ix>=0x40122E8B){p = pr5; q= ps5;} else if(ix>=0x4006DB6D){p = pr3; q= ps3;} else {p = pr2; q= ps2;} z = one/(x*x); r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4])))); return one+ r/s; } /* For x >= 8, the asymptotic expansions of qone is * 3/8 s - 105/1024 s^3 - ..., where s = 1/x. * We approximate pone by * qone(x) = s*(0.375 + (R/S)) * where R = qr1*s^2 + qr2*s^4 + ... + qr5*s^10 * S = 1 + qs1*s^2 + ... + qs6*s^12 * and * | qone(x)/s -0.375-R/S | <= 2 ** ( -61.13) */ static const double qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ -1.02539062499992714161e-01, /* 0xBFBA3FFF, 0xFFFFFDF3 */ -1.62717534544589987888e+01, /* 0xC0304591, 0xA26779F7 */ -7.59601722513950107896e+02, /* 0xC087BCD0, 0x53E4B576 */ -1.18498066702429587167e+04, /* 0xC0C724E7, 0x40F87415 */ -4.84385124285750353010e+04, /* 0xC0E7A6D0, 0x65D09C6A */ }; static const double qs8[6] = { 1.61395369700722909556e+02, /* 0x40642CA6, 0xDE5BCDE5 */ 7.82538599923348465381e+03, /* 0x40BE9162, 0xD0D88419 */ 1.33875336287249578163e+05, /* 0x4100579A, 0xB0B75E98 */ 7.19657723683240939863e+05, /* 0x4125F653, 0x72869C19 */ 6.66601232617776375264e+05, /* 0x412457D2, 0x7719AD5C */ -2.94490264303834643215e+05, /* 0xC111F969, 0x0EA5AA18 */ }; static const double qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ -2.08979931141764104297e-11, /* 0xBDB6FA43, 0x1AA1A098 */ -1.02539050241375426231e-01, /* 0xBFBA3FFF, 0xCB597FEF */ -8.05644828123936029840e+00, /* 0xC0201CE6, 0xCA03AD4B */ -1.83669607474888380239e+02, /* 0xC066F56D, 0x6CA7B9B0 */ -1.37319376065508163265e+03, /* 0xC09574C6, 0x6931734F */ -2.61244440453215656817e+03, /* 0xC0A468E3, 0x88FDA79D */ }; static const double qs5[6] = { 8.12765501384335777857e+01, /* 0x405451B2, 0xFF5A11B2 */ 1.99179873460485964642e+03, /* 0x409F1F31, 0xE77BF839 */ 1.74684851924908907677e+04, /* 0x40D10F1F, 0x0D64CE29 */ 4.98514270910352279316e+04, /* 0x40E8576D, 0xAABAD197 */ 2.79480751638918118260e+04, /* 0x40DB4B04, 0xCF7C364B */ -4.71918354795128470869e+03, /* 0xC0B26F2E, 0xFCFFA004 */ }; static const double qr3[6] = { -5.07831226461766561369e-09, /* 0xBE35CFA9, 0xD38FC84F */ -1.02537829820837089745e-01, /* 0xBFBA3FEB, 0x51AEED54 */ -4.61011581139473403113e+00, /* 0xC01270C2, 0x3302D9FF */ -5.78472216562783643212e+01, /* 0xC04CEC71, 0xC25D16DA */ -2.28244540737631695038e+02, /* 0xC06C87D3, 0x4718D55F */ -2.19210128478909325622e+02, /* 0xC06B66B9, 0x5F5C1BF6 */ }; static const double qs3[6] = { 4.76651550323729509273e+01, /* 0x4047D523, 0xCCD367E4 */ 6.73865112676699709482e+02, /* 0x40850EEB, 0xC031EE3E */ 3.38015286679526343505e+03, /* 0x40AA684E, 0x448E7C9A */ 5.54772909720722782367e+03, /* 0x40B5ABBA, 0xA61D54A6 */ 1.90311919338810798763e+03, /* 0x409DBC7A, 0x0DD4DF4B */ -1.35201191444307340817e+02, /* 0xC060E670, 0x290A311F */ }; static const double qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ -1.78381727510958865572e-07, /* 0xBE87F126, 0x44C626D2 */ -1.02517042607985553460e-01, /* 0xBFBA3E8E, 0x9148B010 */ -2.75220568278187460720e+00, /* 0xC0060484, 0x69BB4EDA */ -1.96636162643703720221e+01, /* 0xC033A9E2, 0xC168907F */ -4.23253133372830490089e+01, /* 0xC04529A3, 0xDE104AAA */ -2.13719211703704061733e+01, /* 0xC0355F36, 0x39CF6E52 */ }; static const double qs2[6] = { 2.95333629060523854548e+01, /* 0x403D888A, 0x78AE64FF */ 2.52981549982190529136e+02, /* 0x406F9F68, 0xDB821CBA */ 7.57502834868645436472e+02, /* 0x4087AC05, 0xCE49A0F7 */ 7.39393205320467245656e+02, /* 0x40871B25, 0x48D4C029 */ 1.55949003336666123687e+02, /* 0x40637E5E, 0x3C3ED8D4 */ -4.95949898822628210127e+00, /* 0xC013D686, 0xE71BE86B */ }; /* Note: This function is only called for ix>=0x40000000 (see above) */ static double qone(double x) { const double *p,*q; double s,r,z; int32_t ix; GET_HIGH_WORD(ix,x); ix &= 0x7fffffff; assert(ix>=0x40000000 && ix<=0x48000000); if(ix>=0x40200000) {p = qr8; q= qs8;} else if(ix>=0x40122E8B){p = qr5; q= qs5;} else if(ix>=0x4006DB6D){p = qr3; q= qs3;} else {p = qr2; q= qs2;} z = one/(x*x); r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5]))))); return (.375 + r/s)/x; } openlibm-0.5.0/src/e_j1f.c000066400000000000000000000237661266752446200152740ustar00rootroot00000000000000/* e_j1f.c -- float version of e_j1.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 #include "cdefs-compat.h" #include #include "math_private.h" static float ponef(float), qonef(float); static const float huge = 1e30, one = 1.0, invsqrtpi= 5.6418961287e-01, /* 0x3f106ebb */ tpi = 6.3661974669e-01, /* 0x3f22f983 */ /* R0/S0 on [0,2] */ r00 = -6.2500000000e-02, /* 0xbd800000 */ r01 = 1.4070566976e-03, /* 0x3ab86cfd */ r02 = -1.5995563444e-05, /* 0xb7862e36 */ r03 = 4.9672799207e-08, /* 0x335557d2 */ s01 = 1.9153760746e-02, /* 0x3c9ce859 */ s02 = 1.8594678841e-04, /* 0x3942fab6 */ s03 = 1.1771846857e-06, /* 0x359dffc2 */ s04 = 5.0463624390e-09, /* 0x31ad6446 */ s05 = 1.2354227016e-11; /* 0x2d59567e */ static const float zero = 0.0; DLLEXPORT float __ieee754_j1f(float x) { float z, s,c,ss,cc,r,u,v,y; int32_t hx,ix; GET_FLOAT_WORD(hx,x); ix = hx&0x7fffffff; if(ix>=0x7f800000) return one/x; y = fabsf(x); if(ix >= 0x40000000) { /* |x| >= 2.0 */ s = sinf(y); c = cosf(y); ss = -s-c; cc = s-c; if(ix<0x7f000000) { /* make sure y+y not overflow */ z = cosf(y+y); if ((s*c)>zero) cc = z/ss; else ss = z/cc; } /* * j1(x) = 1/sqrt(pi) * (P(1,x)*cc - Q(1,x)*ss) / sqrt(x) * y1(x) = 1/sqrt(pi) * (P(1,x)*ss + Q(1,x)*cc) / sqrt(x) */ if(ix>0x58000000) z = (invsqrtpi*cc)/sqrtf(y); /* |x|>2**49 */ else { u = ponef(y); v = qonef(y); z = invsqrtpi*(u*cc-v*ss)/sqrtf(y); } if(hx<0) return -z; else return z; } if(ix<0x39000000) { /* |x|<2**-13 */ if(huge+x>one) return (float)0.5*x;/* inexact if x!=0 necessary */ } z = x*x; r = z*(r00+z*(r01+z*(r02+z*r03))); s = one+z*(s01+z*(s02+z*(s03+z*(s04+z*s05)))); r *= x; return(x*(float)0.5+r/s); } static const float U0[5] = { -1.9605709612e-01, /* 0xbe48c331 */ 5.0443872809e-02, /* 0x3d4e9e3c */ -1.9125689287e-03, /* 0xbafaaf2a */ 2.3525259166e-05, /* 0x37c5581c */ -9.1909917899e-08, /* 0xb3c56003 */ }; static const float V0[5] = { 1.9916731864e-02, /* 0x3ca3286a */ 2.0255257550e-04, /* 0x3954644b */ 1.3560879779e-06, /* 0x35b602d4 */ 6.2274145840e-09, /* 0x31d5f8eb */ 1.6655924903e-11, /* 0x2d9281cf */ }; DLLEXPORT float __ieee754_y1f(float x) { float z, s,c,ss,cc,u,v; int32_t hx,ix; GET_FLOAT_WORD(hx,x); ix = 0x7fffffff&hx; /* if Y1(NaN) is NaN, Y1(-inf) is NaN, Y1(inf) is 0 */ if(ix>=0x7f800000) return one/(x+x*x); if(ix==0) return -one/zero; if(hx<0) return zero/zero; if(ix >= 0x40000000) { /* |x| >= 2.0 */ s = sinf(x); c = cosf(x); ss = -s-c; cc = s-c; if(ix<0x7f000000) { /* make sure x+x not overflow */ z = cosf(x+x); if ((s*c)>zero) cc = z/ss; else ss = z/cc; } /* y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x0)+q1(x)*cos(x0)) * where x0 = x-3pi/4 * Better formula: * cos(x0) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4) * = 1/sqrt(2) * (sin(x) - cos(x)) * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) * = -1/sqrt(2) * (cos(x) + sin(x)) * To avoid cancellation, use * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) * to compute the worse one. */ if(ix>0x58000000) z = (invsqrtpi*ss)/sqrtf(x); /* |x|>2**49 */ else { u = ponef(x); v = qonef(x); z = invsqrtpi*(u*ss+v*cc)/sqrtf(x); } return z; } if(ix<=0x33000000) { /* x < 2**-25 */ return(-tpi/x); } z = x*x; u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4]))); v = one+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4])))); return(x*(u/v) + tpi*(__ieee754_j1f(x)*__ieee754_logf(x)-one/x)); } /* For x >= 8, the asymptotic expansions of pone is * 1 + 15/128 s^2 - 4725/2^15 s^4 - ..., where s = 1/x. * We approximate pone by * pone(x) = 1 + (R/S) * where R = pr0 + pr1*s^2 + pr2*s^4 + ... + pr5*s^10 * S = 1 + ps0*s^2 + ... + ps4*s^10 * and * | pone(x)-1-R/S | <= 2 ** ( -60.06) */ static const float pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ 0.0000000000e+00, /* 0x00000000 */ 1.1718750000e-01, /* 0x3df00000 */ 1.3239480972e+01, /* 0x4153d4ea */ 4.1205184937e+02, /* 0x43ce06a3 */ 3.8747453613e+03, /* 0x45722bed */ 7.9144794922e+03, /* 0x45f753d6 */ }; static const float ps8[5] = { 1.1420736694e+02, /* 0x42e46a2c */ 3.6509309082e+03, /* 0x45642ee5 */ 3.6956207031e+04, /* 0x47105c35 */ 9.7602796875e+04, /* 0x47bea166 */ 3.0804271484e+04, /* 0x46f0a88b */ }; static const float pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ 1.3199052094e-11, /* 0x2d68333f */ 1.1718749255e-01, /* 0x3defffff */ 6.8027510643e+00, /* 0x40d9b023 */ 1.0830818176e+02, /* 0x42d89dca */ 5.1763616943e+02, /* 0x440168b7 */ 5.2871520996e+02, /* 0x44042dc6 */ }; static const float ps5[5] = { 5.9280597687e+01, /* 0x426d1f55 */ 9.9140142822e+02, /* 0x4477d9b1 */ 5.3532670898e+03, /* 0x45a74a23 */ 7.8446904297e+03, /* 0x45f52586 */ 1.5040468750e+03, /* 0x44bc0180 */ }; static const float pr3[6] = { 3.0250391081e-09, /* 0x314fe10d */ 1.1718686670e-01, /* 0x3defffab */ 3.9329774380e+00, /* 0x407bb5e7 */ 3.5119403839e+01, /* 0x420c7a45 */ 9.1055007935e+01, /* 0x42b61c2a */ 4.8559066772e+01, /* 0x42423c7c */ }; static const float ps3[5] = { 3.4791309357e+01, /* 0x420b2a4d */ 3.3676245117e+02, /* 0x43a86198 */ 1.0468714600e+03, /* 0x4482dbe3 */ 8.9081134033e+02, /* 0x445eb3ed */ 1.0378793335e+02, /* 0x42cf936c */ }; static const float pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ 1.0771083225e-07, /* 0x33e74ea8 */ 1.1717621982e-01, /* 0x3deffa16 */ 2.3685150146e+00, /* 0x401795c0 */ 1.2242610931e+01, /* 0x4143e1bc */ 1.7693971634e+01, /* 0x418d8d41 */ 5.0735230446e+00, /* 0x40a25a4d */ }; static const float ps2[5] = { 2.1436485291e+01, /* 0x41ab7dec */ 1.2529022980e+02, /* 0x42fa9499 */ 2.3227647400e+02, /* 0x436846c7 */ 1.1767937469e+02, /* 0x42eb5bd7 */ 8.3646392822e+00, /* 0x4105d590 */ }; static float ponef(float x) { const float *p,*q; float z,r,s; int32_t ix; GET_FLOAT_WORD(ix,x); ix &= 0x7fffffff; if(ix>=0x41000000) {p = pr8; q= ps8;} else if(ix>=0x409173eb){p = pr5; q= ps5;} else if(ix>=0x4036d917){p = pr3; q= ps3;} else {p = pr2; q= ps2;} /* ix>=0x40000000 */ z = one/(x*x); r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4])))); return one+ r/s; } /* For x >= 8, the asymptotic expansions of qone is * 3/8 s - 105/1024 s^3 - ..., where s = 1/x. * We approximate pone by * qone(x) = s*(0.375 + (R/S)) * where R = qr1*s^2 + qr2*s^4 + ... + qr5*s^10 * S = 1 + qs1*s^2 + ... + qs6*s^12 * and * | qone(x)/s -0.375-R/S | <= 2 ** ( -61.13) */ static const float qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ 0.0000000000e+00, /* 0x00000000 */ -1.0253906250e-01, /* 0xbdd20000 */ -1.6271753311e+01, /* 0xc1822c8d */ -7.5960174561e+02, /* 0xc43de683 */ -1.1849806641e+04, /* 0xc639273a */ -4.8438511719e+04, /* 0xc73d3683 */ }; static const float qs8[6] = { 1.6139537048e+02, /* 0x43216537 */ 7.8253862305e+03, /* 0x45f48b17 */ 1.3387534375e+05, /* 0x4802bcd6 */ 7.1965775000e+05, /* 0x492fb29c */ 6.6660125000e+05, /* 0x4922be94 */ -2.9449025000e+05, /* 0xc88fcb48 */ }; static const float qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ -2.0897993405e-11, /* 0xadb7d219 */ -1.0253904760e-01, /* 0xbdd1fffe */ -8.0564479828e+00, /* 0xc100e736 */ -1.8366960144e+02, /* 0xc337ab6b */ -1.3731937256e+03, /* 0xc4aba633 */ -2.6124443359e+03, /* 0xc523471c */ }; static const float qs5[6] = { 8.1276550293e+01, /* 0x42a28d98 */ 1.9917987061e+03, /* 0x44f8f98f */ 1.7468484375e+04, /* 0x468878f8 */ 4.9851425781e+04, /* 0x4742bb6d */ 2.7948074219e+04, /* 0x46da5826 */ -4.7191835938e+03, /* 0xc5937978 */ }; static const float qr3[6] = { -5.0783124372e-09, /* 0xb1ae7d4f */ -1.0253783315e-01, /* 0xbdd1ff5b */ -4.6101160049e+00, /* 0xc0938612 */ -5.7847221375e+01, /* 0xc267638e */ -2.2824453735e+02, /* 0xc3643e9a */ -2.1921012878e+02, /* 0xc35b35cb */ }; static const float qs3[6] = { 4.7665153503e+01, /* 0x423ea91e */ 6.7386511230e+02, /* 0x4428775e */ 3.3801528320e+03, /* 0x45534272 */ 5.5477290039e+03, /* 0x45ad5dd5 */ 1.9031191406e+03, /* 0x44ede3d0 */ -1.3520118713e+02, /* 0xc3073381 */ }; static const float qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ -1.7838172539e-07, /* 0xb43f8932 */ -1.0251704603e-01, /* 0xbdd1f475 */ -2.7522056103e+00, /* 0xc0302423 */ -1.9663616180e+01, /* 0xc19d4f16 */ -4.2325313568e+01, /* 0xc2294d1f */ -2.1371921539e+01, /* 0xc1aaf9b2 */ }; static const float qs2[6] = { 2.9533363342e+01, /* 0x41ec4454 */ 2.5298155212e+02, /* 0x437cfb47 */ 7.5750280762e+02, /* 0x443d602e */ 7.3939318848e+02, /* 0x4438d92a */ 1.5594900513e+02, /* 0x431bf2f2 */ -4.9594988823e+00, /* 0xc09eb437 */ }; static float qonef(float x) { const float *p,*q; float s,r,z; int32_t ix; GET_FLOAT_WORD(ix,x); ix &= 0x7fffffff; if(ix>=0x41000000) {p = qr8; q= qs8;} else if(ix>=0x409173eb){p = qr5; q= qs5;} else if(ix>=0x4036d917){p = qr3; q= qs3;} else {p = qr2; q= qs2;} /* ix>=0x40000000 */ z = one/(x*x); r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5]))))); return ((float).375 + r/s)/x; } openlibm-0.5.0/src/e_jn.c000066400000000000000000000161341266752446200152120ustar00rootroot00000000000000 /* @(#)e_jn.c 1.4 95/01/18 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_jn.c,v 1.11 2010/11/13 10:54:10 uqs Exp $"); /* * __ieee754_jn(n, x), __ieee754_yn(n, x) * floating point Bessel's function of the 1st and 2nd kind * of order n * * Special cases: * y0(0)=y1(0)=yn(n,0) = -inf with division by zero signal; * y0(-ve)=y1(-ve)=yn(n,-ve) are NaN with invalid signal. * Note 2. About jn(n,x), yn(n,x) * For n=0, j0(x) is called, * for n=1, j1(x) is called, * for nx, a continued fraction approximation to * j(n,x)/j(n-1,x) is evaluated and then backward * recursion is used starting from a supposed value * for j(n,x). The resulting value of j(0,x) is * compared with the actual value to correct the * supposed value of j(n,x). * * yn(n,x) is similar in all respects, except * that forward recursion is used for all * values of n>1. * */ #include #include "math_private.h" static const double invsqrtpi= 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */ two = 2.00000000000000000000e+00, /* 0x40000000, 0x00000000 */ one = 1.00000000000000000000e+00; /* 0x3FF00000, 0x00000000 */ static const double zero = 0.00000000000000000000e+00; DLLEXPORT double __ieee754_jn(int n, double x) { int32_t i,hx,ix,lx, sgn; double a, b, temp, di; double z, w; /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x) * Thus, J(-n,x) = J(n,-x) */ EXTRACT_WORDS(hx,lx,x); ix = 0x7fffffff&hx; /* if J(n,NaN) is NaN */ if((ix|((u_int32_t)(lx|-lx))>>31)>0x7ff00000) return x+x; if(n<0){ n = -n; x = -x; hx ^= 0x80000000; } if(n==0) return(__ieee754_j0(x)); if(n==1) return(__ieee754_j1(x)); sgn = (n&1)&(hx>>31); /* even n -- 0, odd n -- sign(x) */ x = fabs(x); if((ix|lx)==0||ix>=0x7ff00000) /* if x is 0 or inf */ b = zero; else if((double)n<=x) { /* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */ if(ix>=0x52D00000) { /* x > 2**302 */ /* (x >> n**2) * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi) * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi) * Let s=sin(x), c=cos(x), * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then * * n sin(xn)*sqt2 cos(xn)*sqt2 * ---------------------------------- * 0 s-c c+s * 1 -s-c -c+s * 2 -s+c -c-s * 3 s+c c-s */ switch(n&3) { case 0: temp = cos(x)+sin(x); break; case 1: temp = -cos(x)+sin(x); break; case 2: temp = -cos(x)-sin(x); break; case 3: temp = cos(x)-sin(x); break; } b = invsqrtpi*temp/sqrt(x); } else { a = __ieee754_j0(x); b = __ieee754_j1(x); for(i=1;i33) /* underflow */ b = zero; else { temp = x*0.5; b = temp; for (a=one,i=2;i<=n;i++) { a *= (double)i; /* a = n! */ b *= temp; /* b = (x/2)^n */ } b = b/a; } } else { /* use backward recurrence */ /* x x^2 x^2 * J(n,x)/J(n-1,x) = ---- ------ ------ ..... * 2n - 2(n+1) - 2(n+2) * * 1 1 1 * (for large x) = ---- ------ ------ ..... * 2n 2(n+1) 2(n+2) * -- - ------ - ------ - * x x x * * Let w = 2n/x and h=2/x, then the above quotient * is equal to the continued fraction: * 1 * = ----------------------- * 1 * w - ----------------- * 1 * w+h - --------- * w+2h - ... * * To determine how many terms needed, let * Q(0) = w, Q(1) = w(w+h) - 1, * Q(k) = (w+k*h)*Q(k-1) - Q(k-2), * When Q(k) > 1e4 good for single * When Q(k) > 1e9 good for double * When Q(k) > 1e17 good for quadruple */ /* determine k */ double t,v; double q0,q1,h,tmp; int32_t k,m; w = (n+n)/(double)x; h = 2.0/(double)x; q0 = w; z = w+h; q1 = w*z - 1.0; k=1; while(q1<1.0e9) { k += 1; z += h; tmp = z*q1 - q0; q0 = q1; q1 = tmp; } m = n+n; for(t=zero, i = 2*(n+k); i>=m; i -= 2) t = one/(i/x-t); a = t; b = one; /* estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n) * Hence, if n*(log(2n/x)) > ... * single 8.8722839355e+01 * double 7.09782712893383973096e+02 * long double 1.1356523406294143949491931077970765006170e+04 * then recurrent value may overflow and the result is * likely underflow to zero */ tmp = n; v = two/x; tmp = tmp*__ieee754_log(fabs(v*tmp)); if(tmp<7.09782712893383973096e+02) { for(i=n-1,di=(double)(i+i);i>0;i--){ temp = b; b *= di; b = b/x - a; a = temp; di -= two; } } else { for(i=n-1,di=(double)(i+i);i>0;i--){ temp = b; b *= di; b = b/x - a; a = temp; di -= two; /* scale b to avoid spurious overflow */ if(b>1e100) { a /= b; t /= b; b = one; } } } z = __ieee754_j0(x); w = __ieee754_j1(x); if (fabs(z) >= fabs(w)) b = (t*z/b); else b = (t*w/a); } } if(sgn==1) return -b; else return b; } DLLEXPORT double __ieee754_yn(int n, double x) { int32_t i,hx,ix,lx; int32_t sign; double a, b, temp; EXTRACT_WORDS(hx,lx,x); ix = 0x7fffffff&hx; /* if Y(n,NaN) is NaN */ if((ix|((u_int32_t)(lx|-lx))>>31)>0x7ff00000) return x+x; if((ix|lx)==0) return -one/zero; if(hx<0) return zero/zero; sign = 1; if(n<0){ n = -n; sign = 1 - ((n&1)<<1); } if(n==0) return(__ieee754_y0(x)); if(n==1) return(sign*__ieee754_y1(x)); if(ix==0x7ff00000) return zero; if(ix>=0x52D00000) { /* x > 2**302 */ /* (x >> n**2) * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi) * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi) * Let s=sin(x), c=cos(x), * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then * * n sin(xn)*sqt2 cos(xn)*sqt2 * ---------------------------------- * 0 s-c c+s * 1 -s-c -c+s * 2 -s+c -c-s * 3 s+c c-s */ switch(n&3) { case 0: temp = sin(x)-cos(x); break; case 1: temp = -sin(x)-cos(x); break; case 2: temp = -sin(x)+cos(x); break; case 3: temp = sin(x)+cos(x); break; } b = invsqrtpi*temp/sqrt(x); } else { u_int32_t high; a = __ieee754_y0(x); b = __ieee754_y1(x); /* quit if b is -inf */ GET_HIGH_WORD(high,b); for(i=1;i0) return b; else return -b; } openlibm-0.5.0/src/e_jnf.c000066400000000000000000000114361266752446200153600ustar00rootroot00000000000000/* e_jnf.c -- float version of e_jn.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_jnf.c,v 1.11 2010/11/13 10:54:10 uqs Exp $"); #include #include "math_private.h" static const float two = 2.0000000000e+00, /* 0x40000000 */ one = 1.0000000000e+00; /* 0x3F800000 */ static const float zero = 0.0000000000e+00; DLLEXPORT float __ieee754_jnf(int n, float x) { int32_t i,hx,ix, sgn; float a, b, temp, di; float z, w; /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x) * Thus, J(-n,x) = J(n,-x) */ GET_FLOAT_WORD(hx,x); ix = 0x7fffffff&hx; /* if J(n,NaN) is NaN */ if(ix>0x7f800000) return x+x; if(n<0){ n = -n; x = -x; hx ^= 0x80000000; } if(n==0) return(__ieee754_j0f(x)); if(n==1) return(__ieee754_j1f(x)); sgn = (n&1)&(hx>>31); /* even n -- 0, odd n -- sign(x) */ x = fabsf(x); if(ix==0||ix>=0x7f800000) /* if x is 0 or inf */ b = zero; else if((float)n<=x) { /* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */ a = __ieee754_j0f(x); b = __ieee754_j1f(x); for(i=1;i33) /* underflow */ b = zero; else { temp = x*(float)0.5; b = temp; for (a=one,i=2;i<=n;i++) { a *= (float)i; /* a = n! */ b *= temp; /* b = (x/2)^n */ } b = b/a; } } else { /* use backward recurrence */ /* x x^2 x^2 * J(n,x)/J(n-1,x) = ---- ------ ------ ..... * 2n - 2(n+1) - 2(n+2) * * 1 1 1 * (for large x) = ---- ------ ------ ..... * 2n 2(n+1) 2(n+2) * -- - ------ - ------ - * x x x * * Let w = 2n/x and h=2/x, then the above quotient * is equal to the continued fraction: * 1 * = ----------------------- * 1 * w - ----------------- * 1 * w+h - --------- * w+2h - ... * * To determine how many terms needed, let * Q(0) = w, Q(1) = w(w+h) - 1, * Q(k) = (w+k*h)*Q(k-1) - Q(k-2), * When Q(k) > 1e4 good for single * When Q(k) > 1e9 good for double * When Q(k) > 1e17 good for quadruple */ /* determine k */ float t,v; float q0,q1,h,tmp; int32_t k,m; w = (n+n)/(float)x; h = (float)2.0/(float)x; q0 = w; z = w+h; q1 = w*z - (float)1.0; k=1; while(q1<(float)1.0e9) { k += 1; z += h; tmp = z*q1 - q0; q0 = q1; q1 = tmp; } m = n+n; for(t=zero, i = 2*(n+k); i>=m; i -= 2) t = one/(i/x-t); a = t; b = one; /* estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n) * Hence, if n*(log(2n/x)) > ... * single 8.8722839355e+01 * double 7.09782712893383973096e+02 * long double 1.1356523406294143949491931077970765006170e+04 * then recurrent value may overflow and the result is * likely underflow to zero */ tmp = n; v = two/x; tmp = tmp*__ieee754_logf(fabsf(v*tmp)); if(tmp<(float)8.8721679688e+01) { for(i=n-1,di=(float)(i+i);i>0;i--){ temp = b; b *= di; b = b/x - a; a = temp; di -= two; } } else { for(i=n-1,di=(float)(i+i);i>0;i--){ temp = b; b *= di; b = b/x - a; a = temp; di -= two; /* scale b to avoid spurious overflow */ if(b>(float)1e10) { a /= b; t /= b; b = one; } } } z = __ieee754_j0f(x); w = __ieee754_j1f(x); if (fabsf(z) >= fabsf(w)) b = (t*z/b); else b = (t*w/a); } } if(sgn==1) return -b; else return b; } DLLEXPORT float __ieee754_ynf(int n, float x) { int32_t i,hx,ix,ib; int32_t sign; float a, b, temp; GET_FLOAT_WORD(hx,x); ix = 0x7fffffff&hx; /* if Y(n,NaN) is NaN */ if(ix>0x7f800000) return x+x; if(ix==0) return -one/zero; if(hx<0) return zero/zero; sign = 1; if(n<0){ n = -n; sign = 1 - ((n&1)<<1); } if(n==0) return(__ieee754_y0f(x)); if(n==1) return(sign*__ieee754_y1f(x)); if(ix==0x7f800000) return zero; a = __ieee754_y0f(x); b = __ieee754_y1f(x); /* quit if b is -inf */ GET_FLOAT_WORD(ib,b); for(i=1;i0) return b; else return -b; } openlibm-0.5.0/src/e_lgamma.c000066400000000000000000000015251266752446200160370ustar00rootroot00000000000000 /* @(#)e_lgamma.c 1.3 95/01/18 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== * */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_lgamma.c,v 1.9 2008/02/22 02:30:35 das Exp $"); /* __ieee754_lgamma(x) * Return the logarithm of the Gamma function of x. * * Method: call __ieee754_lgamma_r */ #include #include "math_private.h" DLLEXPORT double __ieee754_lgamma(double x) { #ifdef OPENLIBM_ONLY_THREAD_SAFE int signgam; #endif return __ieee754_lgamma_r(x,&signgam); } openlibm-0.5.0/src/e_lgamma_r.c000066400000000000000000000254761266752446200163730ustar00rootroot00000000000000 /* @(#)e_lgamma_r.c 1.3 95/01/18 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== * */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_lgamma_r.c,v 1.11 2011/10/15 07:00:28 das Exp $"); /* __ieee754_lgamma_r(x, signgamp) * Reentrant version of the logarithm of the Gamma function * with user provide pointer for the sign of Gamma(x). * * Method: * 1. Argument Reduction for 0 < x <= 8 * Since gamma(1+s)=s*gamma(s), for x in [0,8], we may * reduce x to a number in [1.5,2.5] by * lgamma(1+s) = log(s) + lgamma(s) * for example, * lgamma(7.3) = log(6.3) + lgamma(6.3) * = log(6.3*5.3) + lgamma(5.3) * = log(6.3*5.3*4.3*3.3*2.3) + lgamma(2.3) * 2. Polynomial approximation of lgamma around its * minimun ymin=1.461632144968362245 to maintain monotonicity. * On [ymin-0.23, ymin+0.27] (i.e., [1.23164,1.73163]), use * Let z = x-ymin; * lgamma(x) = -1.214862905358496078218 + z^2*poly(z) * where * poly(z) is a 14 degree polynomial. * 2. Rational approximation in the primary interval [2,3] * We use the following approximation: * s = x-2.0; * lgamma(x) = 0.5*s + s*P(s)/Q(s) * with accuracy * |P/Q - (lgamma(x)-0.5s)| < 2**-61.71 * Our algorithms are based on the following observation * * zeta(2)-1 2 zeta(3)-1 3 * lgamma(2+s) = s*(1-Euler) + --------- * s - --------- * s + ... * 2 3 * * where Euler = 0.5771... is the Euler constant, which is very * close to 0.5. * * 3. For x>=8, we have * lgamma(x)~(x-0.5)log(x)-x+0.5*log(2pi)+1/(12x)-1/(360x**3)+.... * (better formula: * lgamma(x)~(x-0.5)*(log(x)-1)-.5*(log(2pi)-1) + ...) * Let z = 1/x, then we approximation * f(z) = lgamma(x) - (x-0.5)(log(x)-1) * by * 3 5 11 * w = w0 + w1*z + w2*z + w3*z + ... + w6*z * where * |w - f(z)| < 2**-58.74 * * 4. For negative x, since (G is gamma function) * -x*G(-x)*G(x) = pi/sin(pi*x), * we have * G(x) = pi/(sin(pi*x)*(-x)*G(-x)) * since G(-x) is positive, sign(G(x)) = sign(sin(pi*x)) for x<0 * Hence, for x<0, signgam = sign(sin(pi*x)) and * lgamma(x) = log(|Gamma(x)|) * = log(pi/(|x*sin(pi*x)|)) - lgamma(-x); * Note: one should avoid compute pi*(-x) directly in the * computation of sin(pi*(-x)). * * 5. Special Cases * lgamma(2+s) ~ s*(1-Euler) for tiny s * lgamma(1) = lgamma(2) = 0 * lgamma(x) ~ -log(|x|) for tiny x * lgamma(0) = lgamma(neg.integer) = inf and raise divide-by-zero * lgamma(inf) = inf * lgamma(-inf) = inf (bug for bug compatible with C99!?) * */ #include #include "math_private.h" static const double two52= 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ half= 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */ one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ pi = 3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */ a0 = 7.72156649015328655494e-02, /* 0x3FB3C467, 0xE37DB0C8 */ a1 = 3.22467033424113591611e-01, /* 0x3FD4A34C, 0xC4A60FAD */ a2 = 6.73523010531292681824e-02, /* 0x3FB13E00, 0x1A5562A7 */ a3 = 2.05808084325167332806e-02, /* 0x3F951322, 0xAC92547B */ a4 = 7.38555086081402883957e-03, /* 0x3F7E404F, 0xB68FEFE8 */ a5 = 2.89051383673415629091e-03, /* 0x3F67ADD8, 0xCCB7926B */ a6 = 1.19270763183362067845e-03, /* 0x3F538A94, 0x116F3F5D */ a7 = 5.10069792153511336608e-04, /* 0x3F40B6C6, 0x89B99C00 */ a8 = 2.20862790713908385557e-04, /* 0x3F2CF2EC, 0xED10E54D */ a9 = 1.08011567247583939954e-04, /* 0x3F1C5088, 0x987DFB07 */ a10 = 2.52144565451257326939e-05, /* 0x3EFA7074, 0x428CFA52 */ a11 = 4.48640949618915160150e-05, /* 0x3F07858E, 0x90A45837 */ tc = 1.46163214496836224576e+00, /* 0x3FF762D8, 0x6356BE3F */ tf = -1.21486290535849611461e-01, /* 0xBFBF19B9, 0xBCC38A42 */ /* tt = -(tail of tf) */ tt = -3.63867699703950536541e-18, /* 0xBC50C7CA, 0xA48A971F */ t0 = 4.83836122723810047042e-01, /* 0x3FDEF72B, 0xC8EE38A2 */ t1 = -1.47587722994593911752e-01, /* 0xBFC2E427, 0x8DC6C509 */ t2 = 6.46249402391333854778e-02, /* 0x3FB08B42, 0x94D5419B */ t3 = -3.27885410759859649565e-02, /* 0xBFA0C9A8, 0xDF35B713 */ t4 = 1.79706750811820387126e-02, /* 0x3F9266E7, 0x970AF9EC */ t5 = -1.03142241298341437450e-02, /* 0xBF851F9F, 0xBA91EC6A */ t6 = 6.10053870246291332635e-03, /* 0x3F78FCE0, 0xE370E344 */ t7 = -3.68452016781138256760e-03, /* 0xBF6E2EFF, 0xB3E914D7 */ t8 = 2.25964780900612472250e-03, /* 0x3F6282D3, 0x2E15C915 */ t9 = -1.40346469989232843813e-03, /* 0xBF56FE8E, 0xBF2D1AF1 */ t10 = 8.81081882437654011382e-04, /* 0x3F4CDF0C, 0xEF61A8E9 */ t11 = -5.38595305356740546715e-04, /* 0xBF41A610, 0x9C73E0EC */ t12 = 3.15632070903625950361e-04, /* 0x3F34AF6D, 0x6C0EBBF7 */ t13 = -3.12754168375120860518e-04, /* 0xBF347F24, 0xECC38C38 */ t14 = 3.35529192635519073543e-04, /* 0x3F35FD3E, 0xE8C2D3F4 */ u0 = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */ u1 = 6.32827064025093366517e-01, /* 0x3FE4401E, 0x8B005DFF */ u2 = 1.45492250137234768737e+00, /* 0x3FF7475C, 0xD119BD6F */ u3 = 9.77717527963372745603e-01, /* 0x3FEF4976, 0x44EA8450 */ u4 = 2.28963728064692451092e-01, /* 0x3FCD4EAE, 0xF6010924 */ u5 = 1.33810918536787660377e-02, /* 0x3F8B678B, 0xBF2BAB09 */ v1 = 2.45597793713041134822e+00, /* 0x4003A5D7, 0xC2BD619C */ v2 = 2.12848976379893395361e+00, /* 0x40010725, 0xA42B18F5 */ v3 = 7.69285150456672783825e-01, /* 0x3FE89DFB, 0xE45050AF */ v4 = 1.04222645593369134254e-01, /* 0x3FBAAE55, 0xD6537C88 */ v5 = 3.21709242282423911810e-03, /* 0x3F6A5ABB, 0x57D0CF61 */ s0 = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */ s1 = 2.14982415960608852501e-01, /* 0x3FCB848B, 0x36E20878 */ s2 = 3.25778796408930981787e-01, /* 0x3FD4D98F, 0x4F139F59 */ s3 = 1.46350472652464452805e-01, /* 0x3FC2BB9C, 0xBEE5F2F7 */ s4 = 2.66422703033638609560e-02, /* 0x3F9B481C, 0x7E939961 */ s5 = 1.84028451407337715652e-03, /* 0x3F5E26B6, 0x7368F239 */ s6 = 3.19475326584100867617e-05, /* 0x3F00BFEC, 0xDD17E945 */ r1 = 1.39200533467621045958e+00, /* 0x3FF645A7, 0x62C4AB74 */ r2 = 7.21935547567138069525e-01, /* 0x3FE71A18, 0x93D3DCDC */ r3 = 1.71933865632803078993e-01, /* 0x3FC601ED, 0xCCFBDF27 */ r4 = 1.86459191715652901344e-02, /* 0x3F9317EA, 0x742ED475 */ r5 = 7.77942496381893596434e-04, /* 0x3F497DDA, 0xCA41A95B */ r6 = 7.32668430744625636189e-06, /* 0x3EDEBAF7, 0xA5B38140 */ w0 = 4.18938533204672725052e-01, /* 0x3FDACFE3, 0x90C97D69 */ w1 = 8.33333333333329678849e-02, /* 0x3FB55555, 0x5555553B */ w2 = -2.77777777728775536470e-03, /* 0xBF66C16C, 0x16B02E5C */ w3 = 7.93650558643019558500e-04, /* 0x3F4A019F, 0x98CF38B6 */ w4 = -5.95187557450339963135e-04, /* 0xBF4380CB, 0x8C0FE741 */ w5 = 8.36339918996282139126e-04, /* 0x3F4B67BA, 0x4CDAD5D1 */ w6 = -1.63092934096575273989e-03; /* 0xBF5AB89D, 0x0B9E43E4 */ static const double zero= 0.00000000000000000000e+00; static double sin_pi(double x) { double y,z; int n,ix; GET_HIGH_WORD(ix,x); ix &= 0x7fffffff; if(ix<0x3fd00000) return __kernel_sin(pi*x,zero,0); y = -x; /* x is assume negative */ /* * argument reduction, make sure inexact flag not raised if input * is an integer */ z = floor(y); if(z!=y) { /* inexact anyway */ y *= 0.5; y = 2.0*(y - floor(y)); /* y = |x| mod 2.0 */ n = (int) (y*4.0); } else { if(ix>=0x43400000) { y = zero; n = 0; /* y must be even */ } else { if(ix<0x43300000) z = y+two52; /* exact */ GET_LOW_WORD(n,z); n &= 1; y = n; n<<= 2; } } switch (n) { case 0: y = __kernel_sin(pi*y,zero,0); break; case 1: case 2: y = __kernel_cos(pi*(0.5-y),zero); break; case 3: case 4: y = __kernel_sin(pi*(one-y),zero,0); break; case 5: case 6: y = -__kernel_cos(pi*(y-1.5),zero); break; default: y = __kernel_sin(pi*(y-2.0),zero,0); break; } return -y; } DLLEXPORT double __ieee754_lgamma_r(double x, int *signgamp) { double t,y,z,nadj,p,p1,p2,p3,q,r,w; int32_t hx; int i,lx,ix; EXTRACT_WORDS(hx,lx,x); /* purge off +-inf, NaN, +-0, tiny and negative arguments */ *signgamp = 1; ix = hx&0x7fffffff; if(ix>=0x7ff00000) return x*x; if((ix|lx)==0) return one/zero; if(ix<0x3b900000) { /* |x|<2**-70, return -log(|x|) */ if(hx<0) { *signgamp = -1; return -__ieee754_log(-x); } else return -__ieee754_log(x); } if(hx<0) { if(ix>=0x43300000) /* |x|>=2**52, must be -integer */ return one/zero; t = sin_pi(x); if(t==zero) return one/zero; /* -integer */ nadj = __ieee754_log(pi/fabs(t*x)); if(t=0x3FE76944) {y = one-x; i= 0;} else if(ix>=0x3FCDA661) {y= x-(tc-one); i=1;} else {y = x; i=2;} } else { r = zero; if(ix>=0x3FFBB4C3) {y=2.0-x;i=0;} /* [1.7316,2] */ else if(ix>=0x3FF3B4C4) {y=x-tc;i=1;} /* [1.23,1.73] */ else {y=x-one;i=2;} } switch(i) { case 0: z = y*y; p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10)))); p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11))))); p = y*p1+p2; r += (p-0.5*y); break; case 1: z = y*y; w = z*y; p1 = t0+w*(t3+w*(t6+w*(t9 +w*t12))); /* parallel comp */ p2 = t1+w*(t4+w*(t7+w*(t10+w*t13))); p3 = t2+w*(t5+w*(t8+w*(t11+w*t14))); p = z*p1-(tt-w*(p2+y*p3)); r += (tf + p); break; case 2: p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5))))); p2 = one+y*(v1+y*(v2+y*(v3+y*(v4+y*v5)))); r += (-0.5*y + p1/p2); } } else if(ix<0x40200000) { /* x < 8.0 */ i = (int)x; y = x-(double)i; p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6)))))); q = one+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6))))); r = half*y+p/q; z = one; /* lgamma(1+s) = log(s) + lgamma(s) */ switch(i) { case 7: z *= (y+6.0); /* FALLTHRU */ case 6: z *= (y+5.0); /* FALLTHRU */ case 5: z *= (y+4.0); /* FALLTHRU */ case 4: z *= (y+3.0); /* FALLTHRU */ case 3: z *= (y+2.0); /* FALLTHRU */ r += __ieee754_log(z); break; } /* 8.0 <= x < 2**58 */ } else if (ix < 0x43900000) { t = __ieee754_log(x); z = one/x; y = z*z; w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6))))); r = (x-half)*(t-one)+w; } else /* 2**58 <= x <= inf */ r = x*(__ieee754_log(x)-one); if(hx<0) r = nadj - r; return r; } openlibm-0.5.0/src/e_lgammaf.c000066400000000000000000000016601266752446200162050ustar00rootroot00000000000000/* e_lgammaf.c -- float version of e_lgamma.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_lgammaf.c,v 1.8 2008/02/22 02:30:35 das Exp $"); /* __ieee754_lgammaf(x) * Return the logarithm of the Gamma function of x. * * Method: call __ieee754_lgammaf_r */ #include #include "math_private.h" DLLEXPORT float __ieee754_lgammaf(float x) { #ifdef OPENLIBM_ONLY_THREAD_SAFE int signgam; #endif return __ieee754_lgammaf_r(x,&signgam); } openlibm-0.5.0/src/e_lgammaf_r.c000066400000000000000000000162361266752446200165330ustar00rootroot00000000000000/* e_lgammaf_r.c -- float version of e_lgamma_r.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_lgammaf_r.c,v 1.12 2011/10/15 07:00:28 das Exp $"); #include #include "math_private.h" static const float two23= 8.3886080000e+06, /* 0x4b000000 */ half= 5.0000000000e-01, /* 0x3f000000 */ one = 1.0000000000e+00, /* 0x3f800000 */ pi = 3.1415927410e+00, /* 0x40490fdb */ a0 = 7.7215664089e-02, /* 0x3d9e233f */ a1 = 3.2246702909e-01, /* 0x3ea51a66 */ a2 = 6.7352302372e-02, /* 0x3d89f001 */ a3 = 2.0580807701e-02, /* 0x3ca89915 */ a4 = 7.3855509982e-03, /* 0x3bf2027e */ a5 = 2.8905137442e-03, /* 0x3b3d6ec6 */ a6 = 1.1927076848e-03, /* 0x3a9c54a1 */ a7 = 5.1006977446e-04, /* 0x3a05b634 */ a8 = 2.2086278477e-04, /* 0x39679767 */ a9 = 1.0801156895e-04, /* 0x38e28445 */ a10 = 2.5214456400e-05, /* 0x37d383a2 */ a11 = 4.4864096708e-05, /* 0x383c2c75 */ tc = 1.4616321325e+00, /* 0x3fbb16c3 */ tf = -1.2148628384e-01, /* 0xbdf8cdcd */ /* tt = -(tail of tf) */ tt = 6.6971006518e-09, /* 0x31e61c52 */ t0 = 4.8383611441e-01, /* 0x3ef7b95e */ t1 = -1.4758771658e-01, /* 0xbe17213c */ t2 = 6.4624942839e-02, /* 0x3d845a15 */ t3 = -3.2788541168e-02, /* 0xbd064d47 */ t4 = 1.7970675603e-02, /* 0x3c93373d */ t5 = -1.0314224288e-02, /* 0xbc28fcfe */ t6 = 6.1005386524e-03, /* 0x3bc7e707 */ t7 = -3.6845202558e-03, /* 0xbb7177fe */ t8 = 2.2596477065e-03, /* 0x3b141699 */ t9 = -1.4034647029e-03, /* 0xbab7f476 */ t10 = 8.8108185446e-04, /* 0x3a66f867 */ t11 = -5.3859531181e-04, /* 0xba0d3085 */ t12 = 3.1563205994e-04, /* 0x39a57b6b */ t13 = -3.1275415677e-04, /* 0xb9a3f927 */ t14 = 3.3552918467e-04, /* 0x39afe9f7 */ u0 = -7.7215664089e-02, /* 0xbd9e233f */ u1 = 6.3282704353e-01, /* 0x3f2200f4 */ u2 = 1.4549225569e+00, /* 0x3fba3ae7 */ u3 = 9.7771751881e-01, /* 0x3f7a4bb2 */ u4 = 2.2896373272e-01, /* 0x3e6a7578 */ u5 = 1.3381091878e-02, /* 0x3c5b3c5e */ v1 = 2.4559779167e+00, /* 0x401d2ebe */ v2 = 2.1284897327e+00, /* 0x4008392d */ v3 = 7.6928514242e-01, /* 0x3f44efdf */ v4 = 1.0422264785e-01, /* 0x3dd572af */ v5 = 3.2170924824e-03, /* 0x3b52d5db */ s0 = -7.7215664089e-02, /* 0xbd9e233f */ s1 = 2.1498242021e-01, /* 0x3e5c245a */ s2 = 3.2577878237e-01, /* 0x3ea6cc7a */ s3 = 1.4635047317e-01, /* 0x3e15dce6 */ s4 = 2.6642270386e-02, /* 0x3cda40e4 */ s5 = 1.8402845599e-03, /* 0x3af135b4 */ s6 = 3.1947532989e-05, /* 0x3805ff67 */ r1 = 1.3920053244e+00, /* 0x3fb22d3b */ r2 = 7.2193557024e-01, /* 0x3f38d0c5 */ r3 = 1.7193385959e-01, /* 0x3e300f6e */ r4 = 1.8645919859e-02, /* 0x3c98bf54 */ r5 = 7.7794247773e-04, /* 0x3a4beed6 */ r6 = 7.3266842264e-06, /* 0x36f5d7bd */ w0 = 4.1893854737e-01, /* 0x3ed67f1d */ w1 = 8.3333335817e-02, /* 0x3daaaaab */ w2 = -2.7777778450e-03, /* 0xbb360b61 */ w3 = 7.9365057172e-04, /* 0x3a500cfd */ w4 = -5.9518753551e-04, /* 0xba1c065c */ w5 = 8.3633989561e-04, /* 0x3a5b3dd2 */ w6 = -1.6309292987e-03; /* 0xbad5c4e8 */ static const float zero= 0.0000000000e+00; static float sin_pif(float x) { float y,z; int n,ix; GET_FLOAT_WORD(ix,x); ix &= 0x7fffffff; if(ix<0x3e800000) return __kernel_sindf(pi*x); y = -x; /* x is assume negative */ /* * argument reduction, make sure inexact flag not raised if input * is an integer */ z = floorf(y); if(z!=y) { /* inexact anyway */ y *= (float)0.5; y = (float)2.0*(y - floorf(y)); /* y = |x| mod 2.0 */ n = (int) (y*(float)4.0); } else { if(ix>=0x4b800000) { y = zero; n = 0; /* y must be even */ } else { if(ix<0x4b000000) z = y+two23; /* exact */ GET_FLOAT_WORD(n,z); n &= 1; y = n; n<<= 2; } } switch (n) { case 0: y = __kernel_sindf(pi*y); break; case 1: case 2: y = __kernel_cosdf(pi*((float)0.5-y)); break; case 3: case 4: y = __kernel_sindf(pi*(one-y)); break; case 5: case 6: y = -__kernel_cosdf(pi*(y-(float)1.5)); break; default: y = __kernel_sindf(pi*(y-(float)2.0)); break; } return -y; } DLLEXPORT float __ieee754_lgammaf_r(float x, int *signgamp) { float t,y,z,nadj,p,p1,p2,p3,q,r,w; int32_t hx; int i,ix; GET_FLOAT_WORD(hx,x); /* purge off +-inf, NaN, +-0, tiny and negative arguments */ *signgamp = 1; ix = hx&0x7fffffff; if(ix>=0x7f800000) return x*x; if(ix==0) return one/zero; if(ix<0x35000000) { /* |x|<2**-21, return -log(|x|) */ if(hx<0) { *signgamp = -1; return -__ieee754_logf(-x); } else return -__ieee754_logf(x); } if(hx<0) { if(ix>=0x4b000000) /* |x|>=2**23, must be -integer */ return one/zero; t = sin_pif(x); if(t==zero) return one/zero; /* -integer */ nadj = __ieee754_logf(pi/fabsf(t*x)); if(t=0x3f3b4a20) {y = one-x; i= 0;} else if(ix>=0x3e6d3308) {y= x-(tc-one); i=1;} else {y = x; i=2;} } else { r = zero; if(ix>=0x3fdda618) {y=(float)2.0-x;i=0;} /* [1.7316,2] */ else if(ix>=0x3F9da620) {y=x-tc;i=1;} /* [1.23,1.73] */ else {y=x-one;i=2;} } switch(i) { case 0: z = y*y; p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10)))); p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11))))); p = y*p1+p2; r += (p-(float)0.5*y); break; case 1: z = y*y; w = z*y; p1 = t0+w*(t3+w*(t6+w*(t9 +w*t12))); /* parallel comp */ p2 = t1+w*(t4+w*(t7+w*(t10+w*t13))); p3 = t2+w*(t5+w*(t8+w*(t11+w*t14))); p = z*p1-(tt-w*(p2+y*p3)); r += (tf + p); break; case 2: p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5))))); p2 = one+y*(v1+y*(v2+y*(v3+y*(v4+y*v5)))); r += (-(float)0.5*y + p1/p2); } } else if(ix<0x41000000) { /* x < 8.0 */ i = (int)x; y = x-(float)i; p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6)))))); q = one+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6))))); r = half*y+p/q; z = one; /* lgamma(1+s) = log(s) + lgamma(s) */ switch(i) { case 7: z *= (y+(float)6.0); /* FALLTHRU */ case 6: z *= (y+(float)5.0); /* FALLTHRU */ case 5: z *= (y+(float)4.0); /* FALLTHRU */ case 4: z *= (y+(float)3.0); /* FALLTHRU */ case 3: z *= (y+(float)2.0); /* FALLTHRU */ r += __ieee754_logf(z); break; } /* 8.0 <= x < 2**58 */ } else if (ix < 0x5c800000) { t = __ieee754_logf(x); z = one/x; y = z*z; w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6))))); r = (x-half)*(t-one)+w; } else /* 2**58 <= x <= inf */ r = x*(__ieee754_logf(x)-one); if(hx<0) r = nadj - r; return r; } openlibm-0.5.0/src/e_lgammal.c000066400000000000000000000003341266752446200162100ustar00rootroot00000000000000#include "cdefs-compat.h" #include #include "math_private.h" DLLEXPORT long double lgammal(long double x) { #ifdef OPENLIBM_ONLY_THREAD_SAFE int signgam; #endif return (lgammal_r(x, &signgam)); } openlibm-0.5.0/src/e_log.c000066400000000000000000000106201266752446200153560ustar00rootroot00000000000000 /* @(#)e_log.c 1.3 95/01/18 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_log.c,v 1.15 2008/03/29 16:37:59 das Exp $"); /* __ieee754_log(x) * Return the logrithm of x * * Method : * 1. Argument Reduction: find k and f such that * x = 2^k * (1+f), * where sqrt(2)/2 < 1+f < sqrt(2) . * * 2. Approximation of log(1+f). * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s) * = 2s + 2/3 s**3 + 2/5 s**5 + ....., * = 2s + s*R * We use a special Reme algorithm on [0,0.1716] to generate * a polynomial of degree 14 to approximate R The maximum error * of this polynomial approximation is bounded by 2**-58.45. In * other words, * 2 4 6 8 10 12 14 * R(z) ~ Lg1*s +Lg2*s +Lg3*s +Lg4*s +Lg5*s +Lg6*s +Lg7*s * (the values of Lg1 to Lg7 are listed in the program) * and * | 2 14 | -58.45 * | Lg1*s +...+Lg7*s - R(z) | <= 2 * | | * Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2. * In order to guarantee error in log below 1ulp, we compute log * by * log(1+f) = f - s*(f - R) (if f is not too large) * log(1+f) = f - (hfsq - s*(hfsq+R)). (better accuracy) * * 3. Finally, log(x) = k*ln2 + log(1+f). * = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo))) * Here ln2 is split into two floating point number: * ln2_hi + ln2_lo, * where n*ln2_hi is always exact for |n| < 2000. * * Special cases: * log(x) is NaN with signal if x < 0 (including -INF) ; * log(+INF) is +INF; log(0) is -INF with signal; * log(NaN) is that NaN with no signal. * * Accuracy: * according to an error analysis, the error is always less than * 1 ulp (unit in the last place). * * Constants: * The hexadecimal values are the intended ones for the following * constants. The decimal values may be used, provided that the * compiler will convert from decimal to binary accurately enough * to produce the hexadecimal values shown. */ #include #include "math_private.h" static const double ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */ ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */ two54 = 1.80143985094819840000e+16, /* 43500000 00000000 */ Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ static const double zero = 0.0; DLLEXPORT double __ieee754_log(double x) { double hfsq,f,s,z,R,w,t1,t2,dk; int32_t k,hx,i,j; u_int32_t lx; EXTRACT_WORDS(hx,lx,x); k=0; if (hx < 0x00100000) { /* x < 2**-1022 */ if (((hx&0x7fffffff)|lx)==0) return -two54/zero; /* log(+-0)=-inf */ if (hx<0) return (x-x)/zero; /* log(-#) = NaN */ k -= 54; x *= two54; /* subnormal number, scale up x */ GET_HIGH_WORD(hx,x); } if (hx >= 0x7ff00000) return x+x; k += (hx>>20)-1023; hx &= 0x000fffff; i = (hx+0x95f64)&0x100000; SET_HIGH_WORD(x,hx|(i^0x3ff00000)); /* normalize x or x/2 */ k += (i>>20); f = x-1.0; if((0x000fffff&(2+hx))<3) { /* -2**-20 <= f < 2**-20 */ if(f==zero) { if(k==0) { return zero; } else { dk=(double)k; return dk*ln2_hi+dk*ln2_lo; } } R = f*f*(0.5-0.33333333333333333*f); if(k==0) return f-R; else {dk=(double)k; return dk*ln2_hi-((R-dk*ln2_lo)-f);} } s = f/(2.0+f); dk = (double)k; z = s*s; i = hx-0x6147a; w = z*z; j = 0x6b851-hx; t1= w*(Lg2+w*(Lg4+w*Lg6)); t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); i |= j; R = t2+t1; if(i>0) { hfsq=0.5*f*f; if(k==0) return f-(hfsq-s*(hfsq+R)); else return dk*ln2_hi-((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f); } else { if(k==0) return f-s*(f-R); else return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f); } } openlibm-0.5.0/src/e_log10.c000066400000000000000000000047421266752446200155270ustar00rootroot00000000000000 /* @(#)e_log10.c 1.3 95/01/18 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_log10.c,v 1.15 2011/10/15 05:23:28 das Exp $"); /* * Return the base 10 logarithm of x. See e_log.c and k_log.h for most * comments. * * log10(x) = (f - 0.5*f*f + k_log1p(f)) / ln10 + k * log10(2) * in not-quite-routine extra precision. */ #include #include "math_private.h" #include "k_log.h" static const double two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ ivln10hi = 4.34294481878168880939e-01, /* 0x3fdbcb7b, 0x15200000 */ ivln10lo = 2.50829467116452752298e-11, /* 0x3dbb9438, 0xca9aadd5 */ log10_2hi = 3.01029995663611771306e-01, /* 0x3FD34413, 0x509F6000 */ log10_2lo = 3.69423907715893078616e-13; /* 0x3D59FEF3, 0x11F12B36 */ static const double zero = 0.0; DLLEXPORT double __ieee754_log10(double x) { double f,hfsq,hi,lo,r,val_hi,val_lo,w,y,y2; int32_t i,k,hx; u_int32_t lx; EXTRACT_WORDS(hx,lx,x); k=0; if (hx < 0x00100000) { /* x < 2**-1022 */ if (((hx&0x7fffffff)|lx)==0) return -two54/zero; /* log(+-0)=-inf */ if (hx<0) return (x-x)/zero; /* log(-#) = NaN */ k -= 54; x *= two54; /* subnormal number, scale up x */ GET_HIGH_WORD(hx,x); } if (hx >= 0x7ff00000) return x+x; if (hx == 0x3ff00000 && lx == 0) return zero; /* log(1) = +0 */ k += (hx>>20)-1023; hx &= 0x000fffff; i = (hx+0x95f64)&0x100000; SET_HIGH_WORD(x,hx|(i^0x3ff00000)); /* normalize x or x/2 */ k += (i>>20); y = (double)k; f = x - 1.0; hfsq = 0.5*f*f; r = k_log1p(f); /* See e_log2.c for most details. */ hi = f - hfsq; SET_LOW_WORD(hi,0); lo = (f - hi) - hfsq + r; val_hi = hi*ivln10hi; y2 = y*log10_2hi; val_lo = y*log10_2lo + (lo+hi)*ivln10lo + lo*ivln10hi; /* * Extra precision in for adding y*log10_2hi is not strictly needed * since there is no very large cancellation near x = sqrt(2) or * x = 1/sqrt(2), but we do it anyway since it costs little on CPUs * with some parallelism and it reduces the error for many args. */ w = y2 + val_hi; val_lo += (y2 - w) + val_hi; val_hi = w; return val_lo + val_hi; } openlibm-0.5.0/src/e_log10f.c000066400000000000000000000040121266752446200156630ustar00rootroot00000000000000/* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_log10f.c,v 1.13 2011/10/16 05:36:23 das Exp $"); /* * Float version of e_log10.c. See the latter for most comments. */ #include #include "math_private.h" #include "k_logf.h" // VBS #define float_t float static const float two25 = 3.3554432000e+07, /* 0x4c000000 */ ivln10hi = 4.3432617188e-01, /* 0x3ede6000 */ ivln10lo = -3.1689971365e-05, /* 0xb804ead9 */ log10_2hi = 3.0102920532e-01, /* 0x3e9a2080 */ log10_2lo = 7.9034151668e-07; /* 0x355427db */ static const float zero = 0.0; DLLEXPORT float __ieee754_log10f(float x) { float f,hfsq,hi,lo,r,y; int32_t i,k,hx; GET_FLOAT_WORD(hx,x); k=0; if (hx < 0x00800000) { /* x < 2**-126 */ if ((hx&0x7fffffff)==0) return -two25/zero; /* log(+-0)=-inf */ if (hx<0) return (x-x)/zero; /* log(-#) = NaN */ k -= 25; x *= two25; /* subnormal number, scale up x */ GET_FLOAT_WORD(hx,x); } if (hx >= 0x7f800000) return x+x; if (hx == 0x3f800000) return zero; /* log(1) = +0 */ k += (hx>>23)-127; hx &= 0x007fffff; i = (hx+(0x4afb0d))&0x800000; SET_FLOAT_WORD(x,hx|(i^0x3f800000)); /* normalize x or x/2 */ k += (i>>23); y = (float)k; f = x - (float)1.0; hfsq = (float)0.5*f*f; r = k_log1pf(f); /* See e_log2f.c and e_log2.c for details. */ if (sizeof(float_t) > sizeof(float)) return (r - hfsq + f) * ((float_t)ivln10lo + ivln10hi) + y * ((float_t)log10_2lo + log10_2hi); hi = f - hfsq; GET_FLOAT_WORD(hx,hi); SET_FLOAT_WORD(hi,hx&0xfffff000); lo = (f - hi) - hfsq + r; return y*log10_2lo + (lo+hi)*ivln10lo + lo*ivln10hi + hi*ivln10hi + y*log10_2hi; } openlibm-0.5.0/src/e_log2.c000066400000000000000000000071521266752446200154460ustar00rootroot00000000000000 /* @(#)e_log10.c 1.3 95/01/18 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_log2.c,v 1.4 2011/10/15 05:23:28 das Exp $"); /* * Return the base 2 logarithm of x. See e_log.c and k_log.h for most * comments. * * This reduces x to {k, 1+f} exactly as in e_log.c, then calls the kernel, * then does the combining and scaling steps * log2(x) = (f - 0.5*f*f + k_log1p(f)) / ln2 + k * in not-quite-routine extra precision. */ #include #include "math_private.h" #include "k_log.h" static const double two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ ivln2hi = 1.44269504072144627571e+00, /* 0x3ff71547, 0x65200000 */ ivln2lo = 1.67517131648865118353e-10; /* 0x3de705fc, 0x2eefa200 */ static const double zero = 0.0; DLLEXPORT double __ieee754_log2(double x) { double f,hfsq,hi,lo,r,val_hi,val_lo,w,y; int32_t i,k,hx; u_int32_t lx; EXTRACT_WORDS(hx,lx,x); k=0; if (hx < 0x00100000) { /* x < 2**-1022 */ if (((hx&0x7fffffff)|lx)==0) return -two54/zero; /* log(+-0)=-inf */ if (hx<0) return (x-x)/zero; /* log(-#) = NaN */ k -= 54; x *= two54; /* subnormal number, scale up x */ GET_HIGH_WORD(hx,x); } if (hx >= 0x7ff00000) return x+x; if (hx == 0x3ff00000 && lx == 0) return zero; /* log(1) = +0 */ k += (hx>>20)-1023; hx &= 0x000fffff; i = (hx+0x95f64)&0x100000; SET_HIGH_WORD(x,hx|(i^0x3ff00000)); /* normalize x or x/2 */ k += (i>>20); y = (double)k; f = x - 1.0; hfsq = 0.5*f*f; r = k_log1p(f); /* * f-hfsq must (for args near 1) be evaluated in extra precision * to avoid a large cancellation when x is near sqrt(2) or 1/sqrt(2). * This is fairly efficient since f-hfsq only depends on f, so can * be evaluated in parallel with R. Not combining hfsq with R also * keeps R small (though not as small as a true `lo' term would be), * so that extra precision is not needed for terms involving R. * * Compiler bugs involving extra precision used to break Dekker's * theorem for spitting f-hfsq as hi+lo, unless double_t was used * or the multi-precision calculations were avoided when double_t * has extra precision. These problems are now automatically * avoided as a side effect of the optimization of combining the * Dekker splitting step with the clear-low-bits step. * * y must (for args near sqrt(2) and 1/sqrt(2)) be added in extra * precision to avoid a very large cancellation when x is very near * these values. Unlike the above cancellations, this problem is * specific to base 2. It is strange that adding +-1 is so much * harder than adding +-ln2 or +-log10_2. * * This uses Dekker's theorem to normalize y+val_hi, so the * compiler bugs are back in some configurations, sigh. And I * don't want to used double_t to avoid them, since that gives a * pessimization and the support for avoiding the pessimization * is not yet available. * * The multi-precision calculations for the multiplications are * routine. */ hi = f - hfsq; SET_LOW_WORD(hi,0); lo = (f - hi) - hfsq + r; val_hi = hi*ivln2hi; val_lo = (lo+hi)*ivln2lo + lo*ivln2hi; /* spadd(val_hi, val_lo, y), except for not using double_t: */ w = y + val_hi; val_lo += (y - w) + val_hi; val_hi = w; return val_lo + val_hi; } openlibm-0.5.0/src/e_log2f.c000066400000000000000000000047101266752446200156110ustar00rootroot00000000000000/* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_log2f.c,v 1.5 2011/10/15 05:23:28 das Exp $"); /* * Float version of e_log2.c. See the latter for most comments. */ #include #include "math_private.h" #include "k_logf.h" // VBS #define float_t float static const float two25 = 3.3554432000e+07, /* 0x4c000000 */ ivln2hi = 1.4428710938e+00, /* 0x3fb8b000 */ ivln2lo = -1.7605285393e-04; /* 0xb9389ad4 */ static const float zero = 0.0; DLLEXPORT float __ieee754_log2f(float x) { float f,hfsq,hi,lo,r,y; int32_t i,k,hx; GET_FLOAT_WORD(hx,x); k=0; if (hx < 0x00800000) { /* x < 2**-126 */ if ((hx&0x7fffffff)==0) return -two25/zero; /* log(+-0)=-inf */ if (hx<0) return (x-x)/zero; /* log(-#) = NaN */ k -= 25; x *= two25; /* subnormal number, scale up x */ GET_FLOAT_WORD(hx,x); } if (hx >= 0x7f800000) return x+x; if (hx == 0x3f800000) return zero; /* log(1) = +0 */ k += (hx>>23)-127; hx &= 0x007fffff; i = (hx+(0x4afb0d))&0x800000; SET_FLOAT_WORD(x,hx|(i^0x3f800000)); /* normalize x or x/2 */ k += (i>>23); y = (float)k; f = x - (float)1.0; hfsq = (float)0.5*f*f; r = k_log1pf(f); /* * We no longer need to avoid falling into the multi-precision * calculations due to compiler bugs breaking Dekker's theorem. * Keep avoiding this as an optimization. See e_log2.c for more * details (some details are here only because the optimization * is not yet available in double precision). * * Another compiler bug turned up. With gcc on i386, * (ivln2lo + ivln2hi) would be evaluated in float precision * despite runtime evaluations using double precision. So we * must cast one of its terms to float_t. This makes the whole * expression have type float_t, so return is forced to waste * time clobbering its extra precision. */ if (sizeof(float_t) > sizeof(float)) return (r - hfsq + f) * ((float_t)ivln2lo + ivln2hi) + y; hi = f - hfsq; GET_FLOAT_WORD(hx,hi); SET_FLOAT_WORD(hi,hx&0xfffff000); lo = (f - hi) - hfsq + r; return (lo+hi)*ivln2lo + lo*ivln2hi + hi*ivln2hi + y; } openlibm-0.5.0/src/e_logf.c000066400000000000000000000046471266752446200155400ustar00rootroot00000000000000/* e_logf.c -- float version of e_log.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_logf.c,v 1.11 2008/03/29 16:37:59 das Exp $"); #include #include "math_private.h" static const float ln2_hi = 6.9313812256e-01, /* 0x3f317180 */ ln2_lo = 9.0580006145e-06, /* 0x3717f7d1 */ two25 = 3.355443200e+07, /* 0x4c000000 */ /* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */ Lg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */ Lg2 = 0xccce13.0p-25, /* 0.40000972152 */ Lg3 = 0x91e9ee.0p-25, /* 0.28498786688 */ Lg4 = 0xf89e26.0p-26; /* 0.24279078841 */ static const float zero = 0.0; DLLEXPORT float __ieee754_logf(float x) { float hfsq,f,s,z,R,w,t1,t2,dk; int32_t k,ix,i,j; GET_FLOAT_WORD(ix,x); k=0; if (ix < 0x00800000) { /* x < 2**-126 */ if ((ix&0x7fffffff)==0) return -two25/zero; /* log(+-0)=-inf */ if (ix<0) return (x-x)/zero; /* log(-#) = NaN */ k -= 25; x *= two25; /* subnormal number, scale up x */ GET_FLOAT_WORD(ix,x); } if (ix >= 0x7f800000) return x+x; k += (ix>>23)-127; ix &= 0x007fffff; i = (ix+(0x95f64<<3))&0x800000; SET_FLOAT_WORD(x,ix|(i^0x3f800000)); /* normalize x or x/2 */ k += (i>>23); f = x-(float)1.0; if((0x007fffff&(0x8000+ix))<0xc000) { /* -2**-9 <= f < 2**-9 */ if(f==zero) { if(k==0) { return zero; } else { dk=(float)k; return dk*ln2_hi+dk*ln2_lo; } } R = f*f*((float)0.5-(float)0.33333333333333333*f); if(k==0) return f-R; else {dk=(float)k; return dk*ln2_hi-((R-dk*ln2_lo)-f);} } s = f/((float)2.0+f); dk = (float)k; z = s*s; i = ix-(0x6147a<<3); w = z*z; j = (0x6b851<<3)-ix; t1= w*(Lg2+w*Lg4); t2= z*(Lg1+w*Lg3); i |= j; R = t2+t1; if(i>0) { hfsq=(float)0.5*f*f; if(k==0) return f-(hfsq-s*(hfsq+R)); else return dk*ln2_hi-((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f); } else { if(k==0) return f-s*(f-R); else return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f); } } openlibm-0.5.0/src/e_pow.c000066400000000000000000000237751266752446200154210ustar00rootroot00000000000000/* @(#)e_pow.c 1.5 04/04/22 SMI */ /* * ==================================================== * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved. * * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_pow.c,v 1.14 2011/10/21 06:26:07 das Exp $"); /* __ieee754_pow(x,y) return x**y * * n * Method: Let x = 2 * (1+f) * 1. Compute and return log2(x) in two pieces: * log2(x) = w1 + w2, * where w1 has 53-24 = 29 bit trailing zeros. * 2. Perform y*log2(x) = n+y' by simulating muti-precision * arithmetic, where |y'|<=0.5. * 3. Return x**y = 2**n*exp(y'*log2) * * Special cases: * 1. (anything) ** 0 is 1 * 2. (anything) ** 1 is itself * 3. (anything) ** NAN is NAN * 4. NAN ** (anything except 0) is NAN * 5. +-(|x| > 1) ** +INF is +INF * 6. +-(|x| > 1) ** -INF is +0 * 7. +-(|x| < 1) ** +INF is +0 * 8. +-(|x| < 1) ** -INF is +INF * 9. +-1 ** +-INF is NAN * 10. +0 ** (+anything except 0, NAN) is +0 * 11. -0 ** (+anything except 0, NAN, odd integer) is +0 * 12. +0 ** (-anything except 0, NAN) is +INF * 13. -0 ** (-anything except 0, NAN, odd integer) is +INF * 14. -0 ** (odd integer) = -( +0 ** (odd integer) ) * 15. +INF ** (+anything except 0,NAN) is +INF * 16. +INF ** (-anything except 0,NAN) is +0 * 17. -INF ** (anything) = -0 ** (-anything) * 18. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer) * 19. (-anything except 0 and inf) ** (non-integer) is NAN * * Accuracy: * pow(x,y) returns x**y nearly rounded. In particular * pow(integer,integer) * always returns the correct integer provided it is * representable. * * Constants : * The hexadecimal values are the intended ones for the following * constants. The decimal values may be used, provided that the * compiler will convert from decimal to binary accurately enough * to produce the hexadecimal values shown. */ #include #include "math_private.h" static const double bp[] = {1.0, 1.5,}, dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */ dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */ zero = 0.0, one = 1.0, two = 2.0, two53 = 9007199254740992.0, /* 0x43400000, 0x00000000 */ huge = 1.0e300, tiny = 1.0e-300, /* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */ L1 = 5.99999999999994648725e-01, /* 0x3FE33333, 0x33333303 */ L2 = 4.28571428578550184252e-01, /* 0x3FDB6DB6, 0xDB6FABFF */ L3 = 3.33333329818377432918e-01, /* 0x3FD55555, 0x518F264D */ L4 = 2.72728123808534006489e-01, /* 0x3FD17460, 0xA91D4101 */ L5 = 2.30660745775561754067e-01, /* 0x3FCD864A, 0x93C9DB65 */ L6 = 2.06975017800338417784e-01, /* 0x3FCA7E28, 0x4A454EEF */ P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */ P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */ P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */ P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */ P5 = 4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */ lg2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */ lg2_h = 6.93147182464599609375e-01, /* 0x3FE62E43, 0x00000000 */ lg2_l = -1.90465429995776804525e-09, /* 0xBE205C61, 0x0CA86C39 */ ovt = 8.0085662595372944372e-0017, /* -(1024-log2(ovfl+.5ulp)) */ cp = 9.61796693925975554329e-01, /* 0x3FEEC709, 0xDC3A03FD =2/(3ln2) */ cp_h = 9.61796700954437255859e-01, /* 0x3FEEC709, 0xE0000000 =(float)cp */ cp_l = -7.02846165095275826516e-09, /* 0xBE3E2FE0, 0x145B01F5 =tail of cp_h*/ ivln2 = 1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */ ivln2_h = 1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/ ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/ DLLEXPORT double __ieee754_pow(double x, double y) { double z,ax,z_h,z_l,p_h,p_l; double y1,t1,t2,r,s,t,u,v,w; int32_t i,j,k,yisint,n; int32_t hx,hy,ix,iy; u_int32_t lx,ly; EXTRACT_WORDS(hx,lx,x); EXTRACT_WORDS(hy,ly,y); ix = hx&0x7fffffff; iy = hy&0x7fffffff; /* y==zero: x**0 = 1 */ if((iy|ly)==0) return one; /* x==1: 1**y = 1, even if y is NaN */ if (hx==0x3ff00000 && lx == 0) return one; /* y!=zero: result is NaN if either arg is NaN */ if(ix > 0x7ff00000 || ((ix==0x7ff00000)&&(lx!=0)) || iy > 0x7ff00000 || ((iy==0x7ff00000)&&(ly!=0))) return (x+0.0)+(y+0.0); /* determine if y is an odd int when x < 0 * yisint = 0 ... y is not an integer * yisint = 1 ... y is an odd int * yisint = 2 ... y is an even int */ yisint = 0; if(hx<0) { if(iy>=0x43400000) yisint = 2; /* even integer y */ else if(iy>=0x3ff00000) { k = (iy>>20)-0x3ff; /* exponent */ if(k>20) { j = ly>>(52-k); if((j<<(52-k))==ly) yisint = 2-(j&1); } else if(ly==0) { j = iy>>(20-k); if((j<<(20-k))==iy) yisint = 2-(j&1); } } } /* special value of y */ if(ly==0) { if (iy==0x7ff00000) { /* y is +-inf */ if(((ix-0x3ff00000)|lx)==0) return one; /* (-1)**+-inf is NaN */ else if (ix >= 0x3ff00000)/* (|x|>1)**+-inf = inf,0 */ return (hy>=0)? y: zero; else /* (|x|<1)**-,+inf = inf,0 */ return (hy<0)?-y: zero; } if(iy==0x3ff00000) { /* y is +-1 */ if(hy<0) return one/x; else return x; } if(hy==0x40000000) return x*x; /* y is 2 */ if(hy==0x40080000) return x*x*x; /* y is 3 */ if(hy==0x40100000) { /* y is 4 */ u = x*x; return u*u; } if(hy==0x3fe00000) { /* y is 0.5 */ if(hx>=0) /* x >= +0 */ return sqrt(x); } } ax = fabs(x); /* special value of x */ if(lx==0) { if(ix==0x7ff00000||ix==0||ix==0x3ff00000){ z = ax; /*x is +-0,+-inf,+-1*/ if(hy<0) z = one/z; /* z = (1/|x|) */ if(hx<0) { if(((ix-0x3ff00000)|yisint)==0) { z = (z-z)/(z-z); /* (-1)**non-int is NaN */ } else if(yisint==1) z = -z; /* (x<0)**odd = -(|x|**odd) */ } return z; } } /* CYGNUS LOCAL + fdlibm-5.3 fix: This used to be n = (hx>>31)+1; but ANSI C says a right shift of a signed negative quantity is implementation defined. */ n = ((u_int32_t)hx>>31)-1; /* (x<0)**(non-int) is NaN */ if((n|yisint)==0) return (x-x)/(x-x); s = one; /* s (sign of result -ve**odd) = -1 else = 1 */ if((n|(yisint-1))==0) s = -one;/* (-ve)**(odd int) */ /* |y| is huge */ if(iy>0x41e00000) { /* if |y| > 2**31 */ if(iy>0x43f00000){ /* if |y| > 2**64, must o/uflow */ if(ix<=0x3fefffff) return (hy<0)? huge*huge:tiny*tiny; if(ix>=0x3ff00000) return (hy>0)? huge*huge:tiny*tiny; } /* over/underflow if x is not close to one */ if(ix<0x3fefffff) return (hy<0)? s*huge*huge:s*tiny*tiny; if(ix>0x3ff00000) return (hy>0)? s*huge*huge:s*tiny*tiny; /* now |1-x| is tiny <= 2**-20, suffice to compute log(x) by x-x^2/2+x^3/3-x^4/4 */ t = ax-one; /* t has 20 trailing zeros */ w = (t*t)*(0.5-t*(0.3333333333333333333333-t*0.25)); u = ivln2_h*t; /* ivln2_h has 21 sig. bits */ v = t*ivln2_l-w*ivln2; t1 = u+v; SET_LOW_WORD(t1,0); t2 = v-(t1-u); } else { double ss,s2,s_h,s_l,t_h,t_l; n = 0; /* take care subnormal number */ if(ix<0x00100000) {ax *= two53; n -= 53; GET_HIGH_WORD(ix,ax); } n += ((ix)>>20)-0x3ff; j = ix&0x000fffff; /* determine interval */ ix = j|0x3ff00000; /* normalize ix */ if(j<=0x3988E) k=0; /* |x|>1)|0x20000000)+0x00080000+(k<<18)); t_l = ax - (t_h-bp[k]); s_l = v*((u-s_h*t_h)-s_h*t_l); /* compute log(ax) */ s2 = ss*ss; r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6))))); r += s_l*(s_h+ss); s2 = s_h*s_h; t_h = 3.0+s2+r; SET_LOW_WORD(t_h,0); t_l = r-((t_h-3.0)-s2); /* u+v = ss*(1+...) */ u = s_h*t_h; v = s_l*t_h+t_l*ss; /* 2/(3log2)*(ss+...) */ p_h = u+v; SET_LOW_WORD(p_h,0); p_l = v-(p_h-u); z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */ z_l = cp_l*p_h+p_l*cp+dp_l[k]; /* log2(ax) = (ss+..)*2/(3*log2) = n + dp_h + z_h + z_l */ t = (double)n; t1 = (((z_h+z_l)+dp_h[k])+t); SET_LOW_WORD(t1,0); t2 = z_l-(((t1-t)-dp_h[k])-z_h); } /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */ y1 = y; SET_LOW_WORD(y1,0); p_l = (y-y1)*t1+y*t2; p_h = y1*t1; z = p_l+p_h; EXTRACT_WORDS(j,i,z); if (j>=0x40900000) { /* z >= 1024 */ if(((j-0x40900000)|i)!=0) /* if z > 1024 */ return s*huge*huge; /* overflow */ else { if(p_l+ovt>z-p_h) return s*huge*huge; /* overflow */ } } else if((j&0x7fffffff)>=0x4090cc00 ) { /* z <= -1075 */ if(((j-0xc090cc00)|i)!=0) /* z < -1075 */ return s*tiny*tiny; /* underflow */ else { if(p_l<=z-p_h) return s*tiny*tiny; /* underflow */ } } /* * compute 2**(p_h+p_l) */ i = j&0x7fffffff; k = (i>>20)-0x3ff; n = 0; if(i>0x3fe00000) { /* if |z| > 0.5, set n = [z+0.5] */ n = j+(0x00100000>>(k+1)); k = ((n&0x7fffffff)>>20)-0x3ff; /* new k for n */ t = zero; SET_HIGH_WORD(t,n&~(0x000fffff>>k)); n = ((n&0x000fffff)|0x00100000)>>(20-k); if(j<0) n = -n; p_h -= t; } t = p_l+p_h; SET_LOW_WORD(t,0); u = t*lg2_h; v = (p_l-(t-p_h))*lg2+t*lg2_l; z = u+v; w = v-(z-u); t = z*z; t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5)))); r = (z*t1)/(t1-two)-(w+z*w); z = one-(r-z); GET_HIGH_WORD(j,z); j += (n<<20); if((j>>20)<=0) z = scalbn(z,n); /* subnormal output */ else SET_HIGH_WORD(z,j); return s*z; } openlibm-0.5.0/src/e_powf.c000066400000000000000000000171571266752446200155640ustar00rootroot00000000000000/* e_powf.c -- float version of e_pow.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_powf.c,v 1.16 2011/10/21 06:26:07 das Exp $"); #include #include "math_private.h" static const float bp[] = {1.0, 1.5,}, dp_h[] = { 0.0, 5.84960938e-01,}, /* 0x3f15c000 */ dp_l[] = { 0.0, 1.56322085e-06,}, /* 0x35d1cfdc */ zero = 0.0, one = 1.0, two = 2.0, two24 = 16777216.0, /* 0x4b800000 */ huge = 1.0e30, tiny = 1.0e-30, /* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */ L1 = 6.0000002384e-01, /* 0x3f19999a */ L2 = 4.2857143283e-01, /* 0x3edb6db7 */ L3 = 3.3333334327e-01, /* 0x3eaaaaab */ L4 = 2.7272811532e-01, /* 0x3e8ba305 */ L5 = 2.3066075146e-01, /* 0x3e6c3255 */ L6 = 2.0697501302e-01, /* 0x3e53f142 */ P1 = 1.6666667163e-01, /* 0x3e2aaaab */ P2 = -2.7777778450e-03, /* 0xbb360b61 */ P3 = 6.6137559770e-05, /* 0x388ab355 */ P4 = -1.6533901999e-06, /* 0xb5ddea0e */ P5 = 4.1381369442e-08, /* 0x3331bb4c */ lg2 = 6.9314718246e-01, /* 0x3f317218 */ lg2_h = 6.93145752e-01, /* 0x3f317200 */ lg2_l = 1.42860654e-06, /* 0x35bfbe8c */ ovt = 4.2995665694e-08, /* -(128-log2(ovfl+.5ulp)) */ cp = 9.6179670095e-01, /* 0x3f76384f =2/(3ln2) */ cp_h = 9.6191406250e-01, /* 0x3f764000 =12b cp */ cp_l = -1.1736857402e-04, /* 0xb8f623c6 =tail of cp_h */ ivln2 = 1.4426950216e+00, /* 0x3fb8aa3b =1/ln2 */ ivln2_h = 1.4426879883e+00, /* 0x3fb8aa00 =16b 1/ln2*/ ivln2_l = 7.0526075433e-06; /* 0x36eca570 =1/ln2 tail*/ DLLEXPORT float __ieee754_powf(float x, float y) { float z,ax,z_h,z_l,p_h,p_l; float y1,t1,t2,r,s,sn,t,u,v,w; int32_t i,j,k,yisint,n; int32_t hx,hy,ix,iy,is; GET_FLOAT_WORD(hx,x); GET_FLOAT_WORD(hy,y); ix = hx&0x7fffffff; iy = hy&0x7fffffff; /* y==zero: x**0 = 1 */ if(iy==0) return one; /* x==1: 1**y = 1, even if y is NaN */ if (hx==0x3f800000) return one; /* y!=zero: result is NaN if either arg is NaN */ if(ix > 0x7f800000 || iy > 0x7f800000) return (x+0.0F)+(y+0.0F); /* determine if y is an odd int when x < 0 * yisint = 0 ... y is not an integer * yisint = 1 ... y is an odd int * yisint = 2 ... y is an even int */ yisint = 0; if(hx<0) { if(iy>=0x4b800000) yisint = 2; /* even integer y */ else if(iy>=0x3f800000) { k = (iy>>23)-0x7f; /* exponent */ j = iy>>(23-k); if((j<<(23-k))==iy) yisint = 2-(j&1); } } /* special value of y */ if (iy==0x7f800000) { /* y is +-inf */ if (ix==0x3f800000) return one; /* (-1)**+-inf is NaN */ else if (ix > 0x3f800000)/* (|x|>1)**+-inf = inf,0 */ return (hy>=0)? y: zero; else /* (|x|<1)**-,+inf = inf,0 */ return (hy<0)?-y: zero; } if(iy==0x3f800000) { /* y is +-1 */ if(hy<0) return one/x; else return x; } if(hy==0x40000000) return x*x; /* y is 2 */ if(hy==0x40400000) return x*x*x; /* y is 3 */ if(hy==0x40800000) { /* y is 4 */ u = x*x; return u*u; } if(hy==0x3f000000) { /* y is 0.5 */ if(hx>=0) /* x >= +0 */ return __ieee754_sqrtf(x); } ax = fabsf(x); /* special value of x */ if(ix==0x7f800000||ix==0||ix==0x3f800000){ z = ax; /*x is +-0,+-inf,+-1*/ if(hy<0) z = one/z; /* z = (1/|x|) */ if(hx<0) { if(((ix-0x3f800000)|yisint)==0) { z = (z-z)/(z-z); /* (-1)**non-int is NaN */ } else if(yisint==1) z = -z; /* (x<0)**odd = -(|x|**odd) */ } return z; } n = ((u_int32_t)hx>>31)-1; /* (x<0)**(non-int) is NaN */ if((n|yisint)==0) return (x-x)/(x-x); sn = one; /* s (sign of result -ve**odd) = -1 else = 1 */ if((n|(yisint-1))==0) sn = -one;/* (-ve)**(odd int) */ /* |y| is huge */ if(iy>0x4d000000) { /* if |y| > 2**27 */ /* over/underflow if x is not close to one */ if(ix<0x3f7ffff8) return (hy<0)? sn*huge*huge:sn*tiny*tiny; if(ix>0x3f800007) return (hy>0)? sn*huge*huge:sn*tiny*tiny; /* now |1-x| is tiny <= 2**-20, suffice to compute log(x) by x-x^2/2+x^3/3-x^4/4 */ t = ax-1; /* t has 20 trailing zeros */ w = (t*t)*((float)0.5-t*((float)0.333333333333-t*(float)0.25)); u = ivln2_h*t; /* ivln2_h has 16 sig. bits */ v = t*ivln2_l-w*ivln2; t1 = u+v; GET_FLOAT_WORD(is,t1); SET_FLOAT_WORD(t1,is&0xfffff000); t2 = v-(t1-u); } else { float s2,s_h,s_l,t_h,t_l; n = 0; /* take care subnormal number */ if(ix<0x00800000) {ax *= two24; n -= 24; GET_FLOAT_WORD(ix,ax); } n += ((ix)>>23)-0x7f; j = ix&0x007fffff; /* determine interval */ ix = j|0x3f800000; /* normalize ix */ if(j<=0x1cc471) k=0; /* |x|>1)&0xfffff000)|0x20000000; SET_FLOAT_WORD(t_h,is+0x00400000+(k<<21)); t_l = ax - (t_h-bp[k]); s_l = v*((u-s_h*t_h)-s_h*t_l); /* compute log(ax) */ s2 = s*s; r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6))))); r += s_l*(s_h+s); s2 = s_h*s_h; t_h = (float)3.0+s2+r; GET_FLOAT_WORD(is,t_h); SET_FLOAT_WORD(t_h,is&0xfffff000); t_l = r-((t_h-(float)3.0)-s2); /* u+v = s*(1+...) */ u = s_h*t_h; v = s_l*t_h+t_l*s; /* 2/(3log2)*(s+...) */ p_h = u+v; GET_FLOAT_WORD(is,p_h); SET_FLOAT_WORD(p_h,is&0xfffff000); p_l = v-(p_h-u); z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */ z_l = cp_l*p_h+p_l*cp+dp_l[k]; /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */ t = (float)n; t1 = (((z_h+z_l)+dp_h[k])+t); GET_FLOAT_WORD(is,t1); SET_FLOAT_WORD(t1,is&0xfffff000); t2 = z_l-(((t1-t)-dp_h[k])-z_h); } /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */ GET_FLOAT_WORD(is,y); SET_FLOAT_WORD(y1,is&0xfffff000); p_l = (y-y1)*t1+y*t2; p_h = y1*t1; z = p_l+p_h; GET_FLOAT_WORD(j,z); if (j>0x43000000) /* if z > 128 */ return sn*huge*huge; /* overflow */ else if (j==0x43000000) { /* if z == 128 */ if(p_l+ovt>z-p_h) return sn*huge*huge; /* overflow */ } else if ((j&0x7fffffff)>0x43160000) /* z <= -150 */ return sn*tiny*tiny; /* underflow */ else if (j==0xc3160000){ /* z == -150 */ if(p_l<=z-p_h) return sn*tiny*tiny; /* underflow */ } /* * compute 2**(p_h+p_l) */ i = j&0x7fffffff; k = (i>>23)-0x7f; n = 0; if(i>0x3f000000) { /* if |z| > 0.5, set n = [z+0.5] */ n = j+(0x00800000>>(k+1)); k = ((n&0x7fffffff)>>23)-0x7f; /* new k for n */ SET_FLOAT_WORD(t,n&~(0x007fffff>>k)); n = ((n&0x007fffff)|0x00800000)>>(23-k); if(j<0) n = -n; p_h -= t; } t = p_l+p_h; GET_FLOAT_WORD(is,t); SET_FLOAT_WORD(t,is&0xffff8000); u = t*lg2_h; v = (p_l-(t-p_h))*lg2+t*lg2_l; z = u+v; w = v-(z-u); t = z*z; t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5)))); r = (z*t1)/(t1-two)-(w+z*w); z = one-(r-z); GET_FLOAT_WORD(j,z); j += (n<<23); if((j>>23)<=0) z = scalbnf(z,n); /* subnormal output */ else SET_FLOAT_WORD(z,j); return sn*z; } openlibm-0.5.0/src/e_rem_pio2.c000066400000000000000000000116301266752446200163130ustar00rootroot00000000000000 /* @(#)e_rem_pio2.c 1.4 95/01/18 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== * * Optimized by Bruce D. Evans. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_rem_pio2.c,v 1.22 2011/06/19 17:07:58 kargl Exp $"); /* __ieee754_rem_pio2(x,y) * * return the remainder of x rem pi/2 in y[0]+y[1] * use __kernel_rem_pio2() */ #include #include #include "math_private.h" /* * invpio2: 53 bits of 2/pi * pio2_1: first 33 bit of pi/2 * pio2_1t: pi/2 - pio2_1 * pio2_2: second 33 bit of pi/2 * pio2_2t: pi/2 - (pio2_1+pio2_2) * pio2_3: third 33 bit of pi/2 * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) */ static const double zero = 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */ invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */ pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */ pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */ pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */ pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */ pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */ __inline int __ieee754_rem_pio2(double x, double *y) { double z,w,t,r,fn; double tx[3],ty[2]; int32_t e0,i,j,nx,n,ix,hx; u_int32_t low; GET_HIGH_WORD(hx,x); /* high word of x */ ix = hx&0x7fffffff; #if 0 /* Must be handled in caller. */ if(ix<=0x3fe921fb) /* |x| ~<= pi/4 , no need for reduction */ {y[0] = x; y[1] = 0; return 0;} #endif if (ix <= 0x400f6a7a) { /* |x| ~<= 5pi/4 */ if ((ix & 0xfffff) == 0x921fb) /* |x| ~= pi/2 or 2pi/2 */ goto medium; /* cancellation -- use medium case */ if (ix <= 0x4002d97c) { /* |x| ~<= 3pi/4 */ if (hx > 0) { z = x - pio2_1; /* one round good to 85 bits */ y[0] = z - pio2_1t; y[1] = (z-y[0])-pio2_1t; return 1; } else { z = x + pio2_1; y[0] = z + pio2_1t; y[1] = (z-y[0])+pio2_1t; return -1; } } else { if (hx > 0) { z = x - 2*pio2_1; y[0] = z - 2*pio2_1t; y[1] = (z-y[0])-2*pio2_1t; return 2; } else { z = x + 2*pio2_1; y[0] = z + 2*pio2_1t; y[1] = (z-y[0])+2*pio2_1t; return -2; } } } if (ix <= 0x401c463b) { /* |x| ~<= 9pi/4 */ if (ix <= 0x4015fdbc) { /* |x| ~<= 7pi/4 */ if (ix == 0x4012d97c) /* |x| ~= 3pi/2 */ goto medium; if (hx > 0) { z = x - 3*pio2_1; y[0] = z - 3*pio2_1t; y[1] = (z-y[0])-3*pio2_1t; return 3; } else { z = x + 3*pio2_1; y[0] = z + 3*pio2_1t; y[1] = (z-y[0])+3*pio2_1t; return -3; } } else { if (ix == 0x401921fb) /* |x| ~= 4pi/2 */ goto medium; if (hx > 0) { z = x - 4*pio2_1; y[0] = z - 4*pio2_1t; y[1] = (z-y[0])-4*pio2_1t; return 4; } else { z = x + 4*pio2_1; y[0] = z + 4*pio2_1t; y[1] = (z-y[0])+4*pio2_1t; return -4; } } } if(ix<0x413921fb) { /* |x| ~< 2^20*(pi/2), medium size */ medium: /* Use a specialized rint() to get fn. Assume round-to-nearest. */ STRICT_ASSIGN(double,fn,x*invpio2+0x1.8p52); fn = fn-0x1.8p52; #ifdef HAVE_EFFICIENT_IRINT n = irint(fn); #else n = (int32_t)fn; #endif r = x-fn*pio2_1; w = fn*pio2_1t; /* 1st round good to 85 bit */ { u_int32_t high; j = ix>>20; y[0] = r-w; GET_HIGH_WORD(high,y[0]); i = j-((high>>20)&0x7ff); if(i>16) { /* 2nd iteration needed, good to 118 */ t = r; w = fn*pio2_2; r = t-w; w = fn*pio2_2t-((t-r)-w); y[0] = r-w; GET_HIGH_WORD(high,y[0]); i = j-((high>>20)&0x7ff); if(i>49) { /* 3rd iteration need, 151 bits acc */ t = r; /* will cover all possible cases */ w = fn*pio2_3; r = t-w; w = fn*pio2_3t-((t-r)-w); y[0] = r-w; } } } y[1] = (r-y[0])-w; return n; } /* * all other (large) arguments */ if(ix>=0x7ff00000) { /* x is inf or NaN */ y[0]=y[1]=x-x; return 0; } /* set z = scalbn(|x|,ilogb(x)-23) */ GET_LOW_WORD(low,x); e0 = (ix>>20)-1046; /* e0 = ilogb(z)-23; */ INSERT_WORDS(z, ix - ((int32_t)(e0<<20)), low); for(i=0;i<2;i++) { tx[i] = (double)((int32_t)(z)); z = (z-tx[i])*two24; } tx[2] = z; nx = 3; while(tx[nx-1]==zero) nx--; /* skip zero term */ n = __kernel_rem_pio2(tx,ty,e0,nx,1); if(hx<0) {y[0] = -ty[0]; y[1] = -ty[1]; return -n;} y[0] = ty[0]; y[1] = ty[1]; return n; } openlibm-0.5.0/src/e_rem_pio2f.c000066400000000000000000000042431266752446200164630ustar00rootroot00000000000000/* e_rem_pio2f.c -- float version of e_rem_pio2.c * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. * Debugged and optimized by Bruce D. Evans. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_rem_pio2f.c,v 1.32 2009/06/03 08:16:34 ed Exp $"); /* __ieee754_rem_pio2f(x,y) * * return the remainder of x rem pi/2 in *y * use double precision for everything except passing x * use __kernel_rem_pio2() for large x */ #include #include #include "math_private.h" /* * invpio2: 53 bits of 2/pi * pio2_1: first 33 bit of pi/2 * pio2_1t: pi/2 - pio2_1 */ static const double invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ pio2_1 = 1.57079631090164184570e+00, /* 0x3FF921FB, 0x50000000 */ pio2_1t = 1.58932547735281966916e-08; /* 0x3E5110b4, 0x611A6263 */ __inline int __ieee754_rem_pio2f(float x, double *y) { double w,r,fn; double tx[1],ty[1]; float z; int32_t e0,n,ix,hx; GET_FLOAT_WORD(hx,x); ix = hx&0x7fffffff; /* 33+53 bit pi is good enough for medium size */ if(ix<0x4dc90fdb) { /* |x| ~< 2^28*(pi/2), medium size */ /* Use a specialized rint() to get fn. Assume round-to-nearest. */ STRICT_ASSIGN(double,fn,x*invpio2+0x1.8p52); fn = fn-0x1.8p52; #ifdef HAVE_EFFICIENT_IRINT n = irint(fn); #else n = (int32_t)fn; #endif r = x-fn*pio2_1; w = fn*pio2_1t; *y = r-w; return n; } /* * all other (large) arguments */ if(ix>=0x7f800000) { /* x is inf or NaN */ *y=x-x; return 0; } /* set z = scalbn(|x|,ilogb(|x|)-23) */ e0 = (ix>>23)-150; /* e0 = ilogb(|x|)-23; */ SET_FLOAT_WORD(z, ix - ((int32_t)(e0<<23))); tx[0] = z; n = __kernel_rem_pio2(tx,ty,e0,1,0); if(hx<0) {*y = -ty[0]; return -n;} *y = ty[0]; return n; } openlibm-0.5.0/src/e_remainder.c000066400000000000000000000035571266752446200165560ustar00rootroot00000000000000 /* @(#)e_remainder.c 1.3 95/01/18 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_remainder.c,v 1.12 2008/03/30 20:47:42 das Exp $"); /* __ieee754_remainder(x,p) * Return : * returns x REM p = x - [x/p]*p as if in infinite * precise arithmetic, where [x/p] is the (infinite bit) * integer nearest x/p (in half way case choose the even one). * Method : * Based on fmod() return x-[x/p]chopped*p exactlp. */ #include #include #include "math_private.h" static const double zero = 0.0; DLLEXPORT double __ieee754_remainder(double x, double p) { int32_t hx,hp; u_int32_t sx,lx,lp; double p_half; EXTRACT_WORDS(hx,lx,x); EXTRACT_WORDS(hp,lp,p); sx = hx&0x80000000; hp &= 0x7fffffff; hx &= 0x7fffffff; /* purge off exception values */ if((hp|lp)==0) return (x*p)/(x*p); /* p = 0 */ if((hx>=0x7ff00000)|| /* x not finite */ ((hp>=0x7ff00000)&& /* p is NaN */ (((hp-0x7ff00000)|lp)!=0))) return ((long double)x*p)/((long double)x*p); if (hp<=0x7fdfffff) x = __ieee754_fmod(x,p+p); /* now x < 2p */ if (((hx-hp)|(lx-lp))==0) return zero*x; x = fabs(x); p = fabs(p); if (hp<0x00200000) { if(x+x>p) { x-=p; if(x+x>=p) x -= p; } } else { p_half = 0.5*p; if(x>p_half) { x-=p; if(x>=p_half) x -= p; } } GET_HIGH_WORD(hx,x); if ((hx&0x7fffffff)==0) hx = 0; SET_HIGH_WORD(x,hx^sx); return x; } #if LDBL_MANT_DIG == 53 __weak_reference(remainder, remainderl); #endif openlibm-0.5.0/src/e_remainderf.c000066400000000000000000000030171266752446200167130ustar00rootroot00000000000000/* e_remainderf.c -- float version of e_remainder.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_remainderf.c,v 1.8 2008/02/12 17:11:36 bde Exp $"); #include #include "math_private.h" static const float zero = 0.0; DLLEXPORT float __ieee754_remainderf(float x, float p) { int32_t hx,hp; u_int32_t sx; float p_half; GET_FLOAT_WORD(hx,x); GET_FLOAT_WORD(hp,p); sx = hx&0x80000000; hp &= 0x7fffffff; hx &= 0x7fffffff; /* purge off exception values */ if(hp==0) return (x*p)/(x*p); /* p = 0 */ if((hx>=0x7f800000)|| /* x not finite */ ((hp>0x7f800000))) /* p is NaN */ return ((long double)x*p)/((long double)x*p); if (hp<=0x7effffff) x = __ieee754_fmodf(x,p+p); /* now x < 2p */ if ((hx-hp)==0) return zero*x; x = fabsf(x); p = fabsf(p); if (hp<0x01000000) { if(x+x>p) { x-=p; if(x+x>=p) x -= p; } } else { p_half = (float)0.5*p; if(x>p_half) { x-=p; if(x>=p_half) x -= p; } } GET_FLOAT_WORD(hx,x); if ((hx&0x7fffffff)==0) hx = 0; SET_FLOAT_WORD(x,hx^sx); return x; } openlibm-0.5.0/src/e_remainderl.c000066400000000000000000000031711266752446200167220ustar00rootroot00000000000000/*- * Copyright (c) 2008 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_remainderl.c,v 1.1 2008/03/30 20:47:42 das Exp $"); #include #include "math_private.h" DLLEXPORT long double remainderl(long double x, long double y) { int quo; return (remquol(x, y, &quo)); } openlibm-0.5.0/src/e_sinh.c000066400000000000000000000040411266752446200155360ustar00rootroot00000000000000 /* @(#)e_sinh.c 1.3 95/01/18 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_sinh.c,v 1.11 2011/10/21 06:28:47 das Exp $"); /* __ieee754_sinh(x) * Method : * mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2 * 1. Replace x by |x| (sinh(-x) = -sinh(x)). * 2. * E + E/(E+1) * 0 <= x <= 22 : sinh(x) := --------------, E=expm1(x) * 2 * * 22 <= x <= lnovft : sinh(x) := exp(x)/2 * lnovft <= x <= ln2ovft: sinh(x) := exp(x/2)/2 * exp(x/2) * ln2ovft < x : sinh(x) := x*shuge (overflow) * * Special cases: * sinh(x) is |x| if x is +INF, -INF, or NaN. * only sinh(0)=0 is exact for finite x. */ #include #include "math_private.h" static const double one = 1.0, shuge = 1.0e307; DLLEXPORT double __ieee754_sinh(double x) { double t,h; int32_t ix,jx; /* High word of |x|. */ GET_HIGH_WORD(jx,x); ix = jx&0x7fffffff; /* x is INF or NaN */ if(ix>=0x7ff00000) return x+x; h = 0.5; if (jx<0) h = -h; /* |x| in [0,22], return sign(x)*0.5*(E+E/(E+1))) */ if (ix < 0x40360000) { /* |x|<22 */ if (ix<0x3e300000) /* |x|<2**-28 */ if(shuge+x>one) return x;/* sinh(tiny) = tiny with inexact */ t = expm1(fabs(x)); if(ix<0x3ff00000) return h*(2.0*t-t*t/(t+one)); return h*(t+t/(t+one)); } /* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */ if (ix < 0x40862E42) return h*__ieee754_exp(fabs(x)); /* |x| in [log(maxdouble), overflowthresold] */ if (ix<=0x408633CE) return h*2.0*__ldexp_exp(fabs(x), -1); /* |x| > overflowthresold, sinh(x) overflow */ return x*shuge; } openlibm-0.5.0/src/e_sinhf.c000066400000000000000000000030231266752446200157030ustar00rootroot00000000000000/* e_sinhf.c -- float version of e_sinh.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_sinhf.c,v 1.10 2011/10/21 06:28:47 das Exp $"); #include #include "math_private.h" static const float one = 1.0, shuge = 1.0e37; DLLEXPORT float __ieee754_sinhf(float x) { float t,h; int32_t ix,jx; GET_FLOAT_WORD(jx,x); ix = jx&0x7fffffff; /* x is INF or NaN */ if(ix>=0x7f800000) return x+x; h = 0.5; if (jx<0) h = -h; /* |x| in [0,9], return sign(x)*0.5*(E+E/(E+1))) */ if (ix < 0x41100000) { /* |x|<9 */ if (ix<0x39800000) /* |x|<2**-12 */ if(shuge+x>one) return x;/* sinh(tiny) = tiny with inexact */ t = expm1f(fabsf(x)); if(ix<0x3f800000) return h*((float)2.0*t-t*t/(t+one)); return h*(t+t/(t+one)); } /* |x| in [9, logf(maxfloat)] return 0.5*exp(|x|) */ if (ix < 0x42b17217) return h*__ieee754_expf(fabsf(x)); /* |x| in [logf(maxfloat), overflowthresold] */ if (ix<=0x42b2d4fc) return h*2.0F*__ldexp_expf(fabsf(x), -1); /* |x| > overflowthresold, sinh(x) overflow */ return x*shuge; } openlibm-0.5.0/src/e_sqrt.c000066400000000000000000000343171266752446200155770ustar00rootroot00000000000000 /* @(#)e_sqrt.c 1.3 95/01/18 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_sqrt.c,v 1.11 2008/03/02 01:47:58 das Exp $"); /* __ieee754_sqrt(x) * Return correctly rounded sqrt. * ------------------------------------------ * | Use the hardware sqrt if you have one | * ------------------------------------------ * Method: * Bit by bit method using integer arithmetic. (Slow, but portable) * 1. Normalization * Scale x to y in [1,4) with even powers of 2: * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then * sqrt(x) = 2^k * sqrt(y) * 2. Bit by bit computation * Let q = sqrt(y) truncated to i bit after binary point (q = 1), * i 0 * i+1 2 * s = 2*q , and y = 2 * ( y - q ). (1) * i i i i * * To compute q from q , one checks whether * i+1 i * * -(i+1) 2 * (q + 2 ) <= y. (2) * i * -(i+1) * If (2) is false, then q = q ; otherwise q = q + 2 . * i+1 i i+1 i * * With some algebric manipulation, it is not difficult to see * that (2) is equivalent to * -(i+1) * s + 2 <= y (3) * i i * * The advantage of (3) is that s and y can be computed by * i i * the following recurrence formula: * if (3) is false * * s = s , y = y ; (4) * i+1 i i+1 i * * otherwise, * -i -(i+1) * s = s + 2 , y = y - s - 2 (5) * i+1 i i+1 i i * * One may easily use induction to prove (4) and (5). * Note. Since the left hand side of (3) contain only i+2 bits, * it does not necessary to do a full (53-bit) comparison * in (3). * 3. Final rounding * After generating the 53 bits result, we compute one more bit. * Together with the remainder, we can decide whether the * result is exact, bigger than 1/2ulp, or less than 1/2ulp * (it will never equal to 1/2ulp). * The rounding mode can be detected by checking whether * huge + tiny is equal to huge, and whether huge - tiny is * equal to huge for some floating point number "huge" and "tiny". * * Special cases: * sqrt(+-0) = +-0 ... exact * sqrt(inf) = inf * sqrt(-ve) = NaN ... with invalid signal * sqrt(NaN) = NaN ... with invalid signal for signaling NaN * * Other methods : see the appended file at the end of the program below. *--------------- */ #include #include #include "math_private.h" static const double one = 1.0, tiny=1.0e-300; DLLEXPORT double __ieee754_sqrt(double x) { double z; int32_t sign = (int)0x80000000; int32_t ix0,s0,q,m,t,i; u_int32_t r,t1,s1,ix1,q1; EXTRACT_WORDS(ix0,ix1,x); /* take care of Inf and NaN */ if((ix0&0x7ff00000)==0x7ff00000) { return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf sqrt(-inf)=sNaN */ } /* take care of zero */ if(ix0<=0) { if(((ix0&(~sign))|ix1)==0) return x;/* sqrt(+-0) = +-0 */ else if(ix0<0) return (x-x)/(x-x); /* sqrt(-ve) = sNaN */ } /* normalize x */ m = (ix0>>20); if(m==0) { /* subnormal x */ while(ix0==0) { m -= 21; ix0 |= (ix1>>11); ix1 <<= 21; } for(i=0;(ix0&0x00100000)==0;i++) ix0<<=1; m -= i-1; ix0 |= (ix1>>(32-i)); ix1 <<= i; } m -= 1023; /* unbias exponent */ ix0 = (ix0&0x000fffff)|0x00100000; if(m&1){ /* odd m, double x to make it even */ ix0 += ix0 + ((ix1&sign)>>31); ix1 += ix1; } m >>= 1; /* m = [m/2] */ /* generate sqrt(x) bit by bit */ ix0 += ix0 + ((ix1&sign)>>31); ix1 += ix1; q = q1 = s0 = s1 = 0; /* [q,q1] = sqrt(x) */ r = 0x00200000; /* r = moving bit from right to left */ while(r!=0) { t = s0+r; if(t<=ix0) { s0 = t+r; ix0 -= t; q += r; } ix0 += ix0 + ((ix1&sign)>>31); ix1 += ix1; r>>=1; } r = sign; while(r!=0) { t1 = s1+r; t = s0; if((t>31); ix1 += ix1; r>>=1; } /* use floating add to find out rounding direction */ if((ix0|ix1)!=0) { z = one-tiny; /* trigger inexact flag */ if (z>=one) { z = one+tiny; if (q1==(u_int32_t)0xffffffff) { q1=0; q += 1;} else if (z>one) { if (q1==(u_int32_t)0xfffffffe) q+=1; q1+=2; } else q1 += (q1&1); } } ix0 = (q>>1)+0x3fe00000; ix1 = q1>>1; if ((q&1)==1) ix1 |= sign; ix0 += (m <<20); INSERT_WORDS(z,ix0,ix1); return z; } #if (LDBL_MANT_DIG == 53) __weak_reference(sqrt, sqrtl); #endif /* Other methods (use floating-point arithmetic) ------------- (This is a copy of a drafted paper by Prof W. Kahan and K.C. Ng, written in May, 1986) Two algorithms are given here to implement sqrt(x) (IEEE double precision arithmetic) in software. Both supply sqrt(x) correctly rounded. The first algorithm (in Section A) uses newton iterations and involves four divisions. The second one uses reciproot iterations to avoid division, but requires more multiplications. Both algorithms need the ability to chop results of arithmetic operations instead of round them, and the INEXACT flag to indicate when an arithmetic operation is executed exactly with no roundoff error, all part of the standard (IEEE 754-1985). The ability to perform shift, add, subtract and logical AND operations upon 32-bit words is needed too, though not part of the standard. A. sqrt(x) by Newton Iteration (1) Initial approximation Let x0 and x1 be the leading and the trailing 32-bit words of a floating point number x (in IEEE double format) respectively 1 11 52 ...widths ------------------------------------------------------ x: |s| e | f | ------------------------------------------------------ msb lsb msb lsb ...order ------------------------ ------------------------ x0: |s| e | f1 | x1: | f2 | ------------------------ ------------------------ By performing shifts and subtracts on x0 and x1 (both regarded as integers), we obtain an 8-bit approximation of sqrt(x) as follows. k := (x0>>1) + 0x1ff80000; y0 := k - T1[31&(k>>15)]. ... y ~ sqrt(x) to 8 bits Here k is a 32-bit integer and T1[] is an integer array containing correction terms. Now magically the floating value of y (y's leading 32-bit word is y0, the value of its trailing word is 0) approximates sqrt(x) to almost 8-bit. Value of T1: static int T1[32]= { 0, 1024, 3062, 5746, 9193, 13348, 18162, 23592, 29598, 36145, 43202, 50740, 58733, 67158, 75992, 85215, 83599, 71378, 60428, 50647, 41945, 34246, 27478, 21581, 16499, 12183, 8588, 5674, 3403, 1742, 661, 130,}; (2) Iterative refinement Apply Heron's rule three times to y, we have y approximates sqrt(x) to within 1 ulp (Unit in the Last Place): y := (y+x/y)/2 ... almost 17 sig. bits y := (y+x/y)/2 ... almost 35 sig. bits y := y-(y-x/y)/2 ... within 1 ulp Remark 1. Another way to improve y to within 1 ulp is: y := (y+x/y) ... almost 17 sig. bits to 2*sqrt(x) y := y - 0x00100006 ... almost 18 sig. bits to sqrt(x) 2 (x-y )*y y := y + 2* ---------- ...within 1 ulp 2 3y + x This formula has one division fewer than the one above; however, it requires more multiplications and additions. Also x must be scaled in advance to avoid spurious overflow in evaluating the expression 3y*y+x. Hence it is not recommended uless division is slow. If division is very slow, then one should use the reciproot algorithm given in section B. (3) Final adjustment By twiddling y's last bit it is possible to force y to be correctly rounded according to the prevailing rounding mode as follows. Let r and i be copies of the rounding mode and inexact flag before entering the square root program. Also we use the expression y+-ulp for the next representable floating numbers (up and down) of y. Note that y+-ulp = either fixed point y+-1, or multiply y by nextafter(1,+-inf) in chopped mode. I := FALSE; ... reset INEXACT flag I R := RZ; ... set rounding mode to round-toward-zero z := x/y; ... chopped quotient, possibly inexact If(not I) then { ... if the quotient is exact if(z=y) { I := i; ... restore inexact flag R := r; ... restore rounded mode return sqrt(x):=y. } else { z := z - ulp; ... special rounding } } i := TRUE; ... sqrt(x) is inexact If (r=RN) then z=z+ulp ... rounded-to-nearest If (r=RP) then { ... round-toward-+inf y = y+ulp; z=z+ulp; } y := y+z; ... chopped sum y0:=y0-0x00100000; ... y := y/2 is correctly rounded. I := i; ... restore inexact flag R := r; ... restore rounded mode return sqrt(x):=y. (4) Special cases Square root of +inf, +-0, or NaN is itself; Square root of a negative number is NaN with invalid signal. B. sqrt(x) by Reciproot Iteration (1) Initial approximation Let x0 and x1 be the leading and the trailing 32-bit words of a floating point number x (in IEEE double format) respectively (see section A). By performing shifs and subtracts on x0 and y0, we obtain a 7.8-bit approximation of 1/sqrt(x) as follows. k := 0x5fe80000 - (x0>>1); y0:= k - T2[63&(k>>14)]. ... y ~ 1/sqrt(x) to 7.8 bits Here k is a 32-bit integer and T2[] is an integer array containing correction terms. Now magically the floating value of y (y's leading 32-bit word is y0, the value of its trailing word y1 is set to zero) approximates 1/sqrt(x) to almost 7.8-bit. Value of T2: static int T2[64]= { 0x1500, 0x2ef8, 0x4d67, 0x6b02, 0x87be, 0xa395, 0xbe7a, 0xd866, 0xf14a, 0x1091b,0x11fcd,0x13552,0x14999,0x15c98,0x16e34,0x17e5f, 0x18d03,0x19a01,0x1a545,0x1ae8a,0x1b5c4,0x1bb01,0x1bfde,0x1c28d, 0x1c2de,0x1c0db,0x1ba73,0x1b11c,0x1a4b5,0x1953d,0x18266,0x16be0, 0x1683e,0x179d8,0x18a4d,0x19992,0x1a789,0x1b445,0x1bf61,0x1c989, 0x1d16d,0x1d77b,0x1dddf,0x1e2ad,0x1e5bf,0x1e6e8,0x1e654,0x1e3cd, 0x1df2a,0x1d635,0x1cb16,0x1be2c,0x1ae4e,0x19bde,0x1868e,0x16e2e, 0x1527f,0x1334a,0x11051,0xe951, 0xbe01, 0x8e0d, 0x5924, 0x1edd,}; (2) Iterative refinement Apply Reciproot iteration three times to y and multiply the result by x to get an approximation z that matches sqrt(x) to about 1 ulp. To be exact, we will have -1ulp < sqrt(x)-z<1.0625ulp. ... set rounding mode to Round-to-nearest y := y*(1.5-0.5*x*y*y) ... almost 15 sig. bits to 1/sqrt(x) y := y*((1.5-2^-30)+0.5*x*y*y)... about 29 sig. bits to 1/sqrt(x) ... special arrangement for better accuracy z := x*y ... 29 bits to sqrt(x), with z*y<1 z := z + 0.5*z*(1-z*y) ... about 1 ulp to sqrt(x) Remark 2. The constant 1.5-2^-30 is chosen to bias the error so that (a) the term z*y in the final iteration is always less than 1; (b) the error in the final result is biased upward so that -1 ulp < sqrt(x) - z < 1.0625 ulp instead of |sqrt(x)-z|<1.03125ulp. (3) Final adjustment By twiddling y's last bit it is possible to force y to be correctly rounded according to the prevailing rounding mode as follows. Let r and i be copies of the rounding mode and inexact flag before entering the square root program. Also we use the expression y+-ulp for the next representable floating numbers (up and down) of y. Note that y+-ulp = either fixed point y+-1, or multiply y by nextafter(1,+-inf) in chopped mode. R := RZ; ... set rounding mode to round-toward-zero switch(r) { case RN: ... round-to-nearest if(x<= z*(z-ulp)...chopped) z = z - ulp; else if(x<= z*(z+ulp)...chopped) z = z; else z = z+ulp; break; case RZ:case RM: ... round-to-zero or round-to--inf R:=RP; ... reset rounding mod to round-to-+inf if(x=(z+ulp)*(z+ulp) ...rounded up) z = z+ulp; break; case RP: ... round-to-+inf if(x>(z+ulp)*(z+ulp)...chopped) z = z+2*ulp; else if(x>z*z ...chopped) z = z+ulp; break; } Remark 3. The above comparisons can be done in fixed point. For example, to compare x and w=z*z chopped, it suffices to compare x1 and w1 (the trailing parts of x and w), regarding them as two's complement integers. ...Is z an exact square root? To determine whether z is an exact square root of x, let z1 be the trailing part of z, and also let x0 and x1 be the leading and trailing parts of x. If ((z1&0x03ffffff)!=0) ... not exact if trailing 26 bits of z!=0 I := 1; ... Raise Inexact flag: z is not exact else { j := 1 - [(x0>>20)&1] ... j = logb(x) mod 2 k := z1 >> 26; ... get z's 25-th and 26-th fraction bits I := i or (k&j) or ((k&(j+j+1))!=(x1&3)); } R:= r ... restore rounded mode return sqrt(x):=z. If multiplication is cheaper then the foregoing red tape, the Inexact flag can be evaluated by I := i; I := (z*z!=x) or I. Note that z*z can overwrite I; this value must be sensed if it is True. Remark 4. If z*z = x exactly, then bit 25 to bit 0 of z1 must be zero. -------------------- z1: | f2 | -------------------- bit 31 bit 0 Further more, bit 27 and 26 of z1, bit 0 and 1 of x1, and the odd or even of logb(x) have the following relations: ------------------------------------------------- bit 27,26 of z1 bit 1,0 of x1 logb(x) ------------------------------------------------- 00 00 odd and even 01 01 even 10 10 odd 10 00 even 11 01 even ------------------------------------------------- (4) Special cases (see (4) of Section A). */ openlibm-0.5.0/src/e_sqrtf.c000066400000000000000000000036011266752446200157350ustar00rootroot00000000000000/* e_sqrtf.c -- float version of e_sqrt.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 #include "math_private.h" static const float one = 1.0, tiny=1.0e-30; DLLEXPORT float __ieee754_sqrtf(float x) { float z; int32_t sign = (int)0x80000000; int32_t ix,s,q,m,t,i; u_int32_t r; GET_FLOAT_WORD(ix,x); /* take care of Inf and NaN */ if((ix&0x7f800000)==0x7f800000) { return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf sqrt(-inf)=sNaN */ } /* take care of zero */ if(ix<=0) { if((ix&(~sign))==0) return x;/* sqrt(+-0) = +-0 */ else if(ix<0) return (x-x)/(x-x); /* sqrt(-ve) = sNaN */ } /* normalize x */ m = (ix>>23); if(m==0) { /* subnormal x */ for(i=0;(ix&0x00800000)==0;i++) ix<<=1; m -= i-1; } m -= 127; /* unbias exponent */ ix = (ix&0x007fffff)|0x00800000; if(m&1) /* odd m, double x to make it even */ ix += ix; m >>= 1; /* m = [m/2] */ /* generate sqrt(x) bit by bit */ ix += ix; q = s = 0; /* q = sqrt(x) */ r = 0x01000000; /* r = moving bit from right to left */ while(r!=0) { t = s+r; if(t<=ix) { s = t+r; ix -= t; q += r; } ix += ix; r>>=1; } /* use floating add to find out rounding direction */ if(ix!=0) { z = one-tiny; /* trigger inexact flag */ if (z>=one) { z = one+tiny; if (z>one) q += 2; else q += (q&1); } } ix = (q>>1)+0x3f000000; ix += (m <<23); SET_FLOAT_WORD(z,ix); return z; } openlibm-0.5.0/src/e_sqrtl.c000066400000000000000000000105741266752446200157520ustar00rootroot00000000000000/*- * Copyright (c) 2007 Steven G. Kargl * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice unmodified, this list of conditions, and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/e_sqrtl.c,v 1.1 2008/03/02 01:47:58 das Exp $"); #include #include #include #include "fpmath.h" #include "math_private.h" /* Return (x + ulp) for normal positive x. Assumes no overflow. */ static inline long double inc(long double x) { union IEEEl2bits u; u.e = x; if (++u.bits.manl == 0) { if (++u.bits.manh == 0) { u.bits.exp++; u.bits.manh |= LDBL_NBIT; } } return (u.e); } /* Return (x - ulp) for normal positive x. Assumes no underflow. */ static inline long double dec(long double x) { union IEEEl2bits u; u.e = x; if (u.bits.manl-- == 0) { if (u.bits.manh-- == LDBL_NBIT) { u.bits.exp--; u.bits.manh |= LDBL_NBIT; } } return (u.e); } #ifndef __GNUC__ #pragma STDC FENV_ACCESS ON #endif /* * This is slow, but simple and portable. You should use hardware sqrt * if possible. */ DLLEXPORT long double sqrtl(long double x) { union IEEEl2bits u; int k, r; long double lo, xn; fenv_t env; u.e = x; /* If x = NaN, then sqrt(x) = NaN. */ /* If x = Inf, then sqrt(x) = Inf. */ /* If x = -Inf, then sqrt(x) = NaN. */ if (u.bits.exp == LDBL_MAX_EXP * 2 - 1) return (x * x + x); /* If x = +-0, then sqrt(x) = +-0. */ if ((u.bits.manh | u.bits.manl | u.bits.exp) == 0) return (x); /* If x < 0, then raise invalid and return NaN */ if (u.bits.sign) return ((x - x) / (x - x)); feholdexcept(&env); if (u.bits.exp == 0) { /* Adjust subnormal numbers. */ u.e *= 0x1.0p514; k = -514; } else { k = 0; } /* * u.e is a normal number, so break it into u.e = e*2^n where * u.e = (2*e)*2^2k for odd n and u.e = (4*e)*2^2k for even n. */ if ((u.bits.exp - 0x3ffe) & 1) { /* n is odd. */ k += u.bits.exp - 0x3fff; /* 2k = n - 1. */ u.bits.exp = 0x3fff; /* u.e in [1,2). */ } else { k += u.bits.exp - 0x4000; /* 2k = n - 2. */ u.bits.exp = 0x4000; /* u.e in [2,4). */ } /* * Newton's iteration. * Split u.e into a high and low part to achieve additional precision. */ xn = sqrt(u.e); /* 53-bit estimate of sqrtl(x). */ #if LDBL_MANT_DIG > 100 xn = (xn + (u.e / xn)) * 0.5; /* 106-bit estimate. */ #endif lo = u.e; u.bits.manl = 0; /* Zero out lower bits. */ lo = (lo - u.e) / xn; /* Low bits divided by xn. */ xn = xn + (u.e / xn); /* High portion of estimate. */ u.e = xn + lo; /* Combine everything. */ u.bits.exp += (k >> 1) - 1; feclearexcept(FE_INEXACT); r = fegetround(); fesetround(FE_TOWARDZERO); /* Set to round-toward-zero. */ xn = x / u.e; /* Chopped quotient (inexact?). */ if (!fetestexcept(FE_INEXACT)) { /* Quotient is exact. */ if (xn == u.e) { fesetenv(&env); return (u.e); } /* Round correctly for inputs like x = y**2 - ulp. */ xn = dec(xn); /* xn = xn - ulp. */ } if (r == FE_TONEAREST) { xn = inc(xn); /* xn = xn + ulp. */ } else if (r == FE_UPWARD) { u.e = inc(u.e); /* u.e = u.e + ulp. */ xn = inc(xn); /* xn = xn + ulp. */ } u.e = u.e + xn; /* Chopped sum. */ feupdateenv(&env); /* Restore env and raise inexact */ u.bits.exp--; return (u.e); } openlibm-0.5.0/src/fpmath.h000066400000000000000000000066211266752446200155630ustar00rootroot00000000000000/*- * Copyright (c) 2003 Mike Barcroft * Copyright (c) 2002 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/lib/libc/include/fpmath.h,v 1.4 2008/12/23 22:20:59 marcel Exp $ */ #ifndef _FPMATH_H_ #define _FPMATH_H_ #if defined(__aarch64__) #include "aarch64_fpmath.h" #elif defined(__i386__) || defined(__x86_64__) #ifdef __LP64__ #include "amd64_fpmath.h" #else #include "i386_fpmath.h" #endif #elif defined(__powerpc__) #include "powerpc_fpmath.h" #endif /* Definitions provided directly by GCC and Clang. */ #if !(defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_BIG_ENDIAN__)) #if defined(__GLIBC__) #include #include #define __ORDER_LITTLE_ENDIAN__ __LITTLE_ENDIAN #define __ORDER_BIG_ENDIAN__ __BIG_ENDIAN #define __BYTE_ORDER__ __BYTE_ORDER #elif defined(__APPLE__) #include #define __ORDER_LITTLE_ENDIAN__ LITTLE_ENDIAN #define __ORDER_BIG_ENDIAN__ BIG_ENDIAN #define __BYTE_ORDER__ BYTE_ORDER #elif defined(_WIN32) #define __ORDER_LITTLE_ENDIAN__ 1234 #define __ORDER_BIG_ENDIAN__ 4321 #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ #endif #endif /* __BYTE_ORDER__, __ORDER_LITTLE_ENDIAN__ and __ORDER_BIG_ENDIAN__ */ #ifndef __FLOAT_WORD_ORDER__ #define __FLOAT_WORD_ORDER__ __BYTE_ORDER__ #endif union IEEEf2bits { float f; struct { #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ unsigned int man :23; unsigned int exp :8; unsigned int sign :1; #else /* _BIG_ENDIAN */ unsigned int sign :1; unsigned int exp :8; unsigned int man :23; #endif } bits; }; #define DBL_MANH_SIZE 20 #define DBL_MANL_SIZE 32 union IEEEd2bits { double d; struct { #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #if __FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__ unsigned int manl :32; #endif unsigned int manh :20; unsigned int exp :11; unsigned int sign :1; #if __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__ unsigned int manl :32; #endif #else /* _BIG_ENDIAN */ unsigned int sign :1; unsigned int exp :11; unsigned int manh :20; unsigned int manl :32; #endif } bits; }; #endif openlibm-0.5.0/src/i386_fpmath.h000066400000000000000000000037301266752446200163320ustar00rootroot00000000000000/*- * Copyright (c) 2002, 2003 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/lib/libc/i386/_fpmath.h,v 1.6 2008/01/17 16:39:06 bde Exp $ */ union IEEEl2bits { long double e; struct { unsigned int manl :32; unsigned int manh :32; unsigned int exp :15; unsigned int sign :1; unsigned int junk :16; } bits; struct { unsigned long long man :64; unsigned int expsign :16; unsigned int junk :16; } xbits; }; #define LDBL_NBIT 0x80000000 #define mask_nbit_l(u) ((u).bits.manh &= ~LDBL_NBIT) #define LDBL_MANH_SIZE 32 #define LDBL_MANL_SIZE 32 #define LDBL_TO_ARRAY32(u, a) do { \ (a)[0] = (uint32_t)(u).bits.manl; \ (a)[1] = (uint32_t)(u).bits.manh; \ } while (0) openlibm-0.5.0/src/k_cos.c000066400000000000000000000055221266752446200153740ustar00rootroot00000000000000 /* @(#)k_cos.c 1.3 95/01/18 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/k_cos.c,v 1.12 2008/02/19 12:54:14 bde Exp $"); /* * __kernel_cos( x, y ) * kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164 * Input x is assumed to be bounded by ~pi/4 in magnitude. * Input y is the tail of x. * * Algorithm * 1. Since cos(-x) = cos(x), we need only to consider positive x. * 2. if x < 2^-27 (hx<0x3e400000 0), return 1 with inexact if x!=0. * 3. cos(x) is approximated by a polynomial of degree 14 on * [0,pi/4] * 4 14 * cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x * where the remez error is * * | 2 4 6 8 10 12 14 | -58 * |cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x +C6*x )| <= 2 * | | * * 4 6 8 10 12 14 * 4. let r = C1*x +C2*x +C3*x +C4*x +C5*x +C6*x , then * cos(x) ~ 1 - x*x/2 + r * since cos(x+y) ~ cos(x) - sin(x)*y * ~ cos(x) - x*y, * a correction term is necessary in cos(x) and hence * cos(x+y) = 1 - (x*x/2 - (r - x*y)) * For better accuracy, rearrange to * cos(x+y) ~ w + (tmp + (r-x*y)) * where w = 1 - x*x/2 and tmp is a tiny correction term * (1 - x*x/2 == w + tmp exactly in infinite precision). * The exactness of w + tmp in infinite precision depends on w * and tmp having the same precision as x. If they have extra * precision due to compiler bugs, then the extra precision is * only good provided it is retained in all terms of the final * expression for cos(). Retention happens in all cases tested * under FreeBSD, so don't pessimize things by forcibly clipping * any extra precision in w. */ #include #include "math_private.h" static const double one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ C1 = 4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */ C2 = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */ C3 = 2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */ C4 = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */ C5 = 2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */ C6 = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */ DLLEXPORT double __kernel_cos(double x, double y) { double hz,z,r,w; z = x*x; w = z*z; r = z*(C1+z*(C2+z*C3)) + w*w*(C4+z*(C5+z*C6)); hz = 0.5*z; w = one-hz; return w + (((one-w)-hz) + (z*r-x*y)); } openlibm-0.5.0/src/k_cosf.c000066400000000000000000000025151266752446200155410ustar00rootroot00000000000000/* k_cosf.c -- float version of k_cos.c * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. * Debugged and optimized by Bruce D. Evans. */ /* * ==================================================== * 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. * ==================================================== */ #ifndef INLINE_KERNEL_COSDF #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/k_cosf.c,v 1.18 2009/06/03 08:16:34 ed Exp $"); #endif #include #include "math_private.h" /* |cos(x) - c(x)| < 2**-34.1 (~[-5.37e-11, 5.295e-11]). */ static const double one = 1.0, C0 = -0x1ffffffd0c5e81.0p-54, /* -0.499999997251031003120 */ C1 = 0x155553e1053a42.0p-57, /* 0.0416666233237390631894 */ C2 = -0x16c087e80f1e27.0p-62, /* -0.00138867637746099294692 */ C3 = 0x199342e0ee5069.0p-68; /* 0.0000243904487962774090654 */ #ifndef INLINE_KERNEL_COSDF extern #endif //__inline float DLLEXPORT float __kernel_cosdf(double x) { double r, w, z; /* Try to optimize for parallel evaluation as in k_tanf.c. */ z = x*x; w = z*z; r = C2+z*C3; return ((one+z*C0) + w*C1) + (w*z)*r; } openlibm-0.5.0/src/k_exp.c000066400000000000000000000071321266752446200154030ustar00rootroot00000000000000/*- * Copyright (c) 2011 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/k_exp.c,v 1.1 2011/10/21 06:27:56 das Exp $"); #include #include #include "math_private.h" static const u_int32_t k = 1799; /* constant for reduction */ static const double kln2 = 1246.97177782734161156; /* k * ln2 */ /* * Compute exp(x), scaled to avoid spurious overflow. An exponent is * returned separately in 'expt'. * * Input: ln(DBL_MAX) <= x < ln(2 * DBL_MAX / DBL_MIN_DENORM) ~= 1454.91 * Output: 2**1023 <= y < 2**1024 */ static double __frexp_exp(double x, int *expt) { double exp_x; u_int32_t hx; /* * We use exp(x) = exp(x - kln2) * 2**k, carefully chosen to * minimize |exp(kln2) - 2**k|. We also scale the exponent of * exp_x to MAX_EXP so that the result can be multiplied by * a tiny number without losing accuracy due to denormalization. */ exp_x = exp(x - kln2); GET_HIGH_WORD(hx, exp_x); *expt = (hx >> 20) - (0x3ff + 1023) + k; SET_HIGH_WORD(exp_x, (hx & 0xfffff) | ((0x3ff + 1023) << 20)); return (exp_x); } /* * __ldexp_exp(x, expt) and __ldexp_cexp(x, expt) compute exp(x) * 2**expt. * They are intended for large arguments (real part >= ln(DBL_MAX)) * where care is needed to avoid overflow. * * The present implementation is narrowly tailored for our hyperbolic and * exponential functions. We assume expt is small (0 or -1), and the caller * has filtered out very large x, for which overflow would be inevitable. */ DLLEXPORT double __ldexp_exp(double x, int expt) { double exp_x, scale; int ex_expt; exp_x = __frexp_exp(x, &ex_expt); expt += ex_expt; INSERT_WORDS(scale, (0x3ff + expt) << 20, 0); return (exp_x * scale); } DLLEXPORT double complex __ldexp_cexp(double complex z, int expt) { double x, y, exp_x, scale1, scale2; int ex_expt, half_expt; x = creal(z); y = cimag(z); exp_x = __frexp_exp(x, &ex_expt); expt += ex_expt; /* * Arrange so that scale1 * scale2 == 2**expt. We use this to * compensate for scalbn being horrendously slow. */ half_expt = expt / 2; INSERT_WORDS(scale1, (0x3ff + half_expt) << 20, 0); half_expt = expt - half_expt; INSERT_WORDS(scale2, (0x3ff + half_expt) << 20, 0); return (CMPLX(cos(y) * exp_x * scale1 * scale2, sin(y) * exp_x * scale1 * scale2)); } openlibm-0.5.0/src/k_expf.c000066400000000000000000000053241266752446200155520ustar00rootroot00000000000000/*- * Copyright (c) 2011 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/k_expf.c,v 1.1 2011/10/21 06:27:56 das Exp $"); #include #include #include "math_private.h" static const u_int32_t k = 235; /* constant for reduction */ static const float kln2 = 162.88958740F; /* k * ln2 */ /* * See k_exp.c for details. * * Input: ln(FLT_MAX) <= x < ln(2 * FLT_MAX / FLT_MIN_DENORM) ~= 192.7 * Output: 2**127 <= y < 2**128 */ static float __frexp_expf(float x, int *expt) { double exp_x; u_int32_t hx; exp_x = expf(x - kln2); GET_FLOAT_WORD(hx, exp_x); *expt = (hx >> 23) - (0x7f + 127) + k; SET_FLOAT_WORD(exp_x, (hx & 0x7fffff) | ((0x7f + 127) << 23)); return (exp_x); } DLLEXPORT float __ldexp_expf(float x, int expt) { float exp_x, scale; int ex_expt; exp_x = __frexp_expf(x, &ex_expt); expt += ex_expt; SET_FLOAT_WORD(scale, (0x7f + expt) << 23); return (exp_x * scale); } DLLEXPORT float complex __ldexp_cexpf(float complex z, int expt) { float x, y, exp_x, scale1, scale2; int ex_expt, half_expt; x = crealf(z); y = cimagf(z); exp_x = __frexp_expf(x, &ex_expt); expt += ex_expt; half_expt = expt / 2; SET_FLOAT_WORD(scale1, (0x7f + half_expt) << 23); half_expt = expt - half_expt; SET_FLOAT_WORD(scale2, (0x7f + half_expt) << 23); return (CMPLXF(cosf(y) * exp_x * scale1 * scale2, sinf(y) * exp_x * scale1 * scale2)); } openlibm-0.5.0/src/k_log.h000066400000000000000000000066321266752446200154010ustar00rootroot00000000000000 /* @(#)e_log.c 1.3 95/01/18 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/k_log.h,v 1.2 2011/10/15 05:23:28 das Exp $"); /* * k_log1p(f): * Return log(1+f) - f for 1+f in ~[sqrt(2)/2, sqrt(2)]. * * The following describes the overall strategy for computing * logarithms in base e. The argument reduction and adding the final * term of the polynomial are done by the caller for increased accuracy * when different bases are used. * * Method : * 1. Argument Reduction: find k and f such that * x = 2^k * (1+f), * where sqrt(2)/2 < 1+f < sqrt(2) . * * 2. Approximation of log(1+f). * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s) * = 2s + 2/3 s**3 + 2/5 s**5 + ....., * = 2s + s*R * We use a special Reme algorithm on [0,0.1716] to generate * a polynomial of degree 14 to approximate R The maximum error * of this polynomial approximation is bounded by 2**-58.45. In * other words, * 2 4 6 8 10 12 14 * R(z) ~ Lg1*s +Lg2*s +Lg3*s +Lg4*s +Lg5*s +Lg6*s +Lg7*s * (the values of Lg1 to Lg7 are listed in the program) * and * | 2 14 | -58.45 * | Lg1*s +...+Lg7*s - R(z) | <= 2 * | | * Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2. * In order to guarantee error in log below 1ulp, we compute log * by * log(1+f) = f - s*(f - R) (if f is not too large) * log(1+f) = f - (hfsq - s*(hfsq+R)). (better accuracy) * * 3. Finally, log(x) = k*ln2 + log(1+f). * = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo))) * Here ln2 is split into two floating point number: * ln2_hi + ln2_lo, * where n*ln2_hi is always exact for |n| < 2000. * * Special cases: * log(x) is NaN with signal if x < 0 (including -INF) ; * log(+INF) is +INF; log(0) is -INF with signal; * log(NaN) is that NaN with no signal. * * Accuracy: * according to an error analysis, the error is always less than * 1 ulp (unit in the last place). * * Constants: * The hexadecimal values are the intended ones for the following * constants. The decimal values may be used, provided that the * compiler will convert from decimal to binary accurately enough * to produce the hexadecimal values shown. */ static const double Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ /* * We always inline k_log1p(), since doing so produces a * substantial performance improvement (~40% on amd64). */ static inline double k_log1p(double f) { double hfsq,s,z,R,w,t1,t2; s = f/(2.0+f); z = s*s; w = z*z; t1= w*(Lg2+w*(Lg4+w*Lg6)); t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); R = t2+t1; hfsq=0.5*f*f; return s*(hfsq+R); } openlibm-0.5.0/src/k_logf.h000066400000000000000000000020431266752446200155370ustar00rootroot00000000000000/* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/k_logf.h,v 1.3 2011/10/15 05:23:28 das Exp $"); /* * Float version of k_log.h. See the latter for most comments. */ static const float /* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */ Lg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */ Lg2 = 0xccce13.0p-25, /* 0.40000972152 */ Lg3 = 0x91e9ee.0p-25, /* 0.28498786688 */ Lg4 = 0xf89e26.0p-26; /* 0.24279078841 */ static inline float k_log1pf(float f) { float hfsq,s,z,R,w,t1,t2; s = f/((float)2.0+f); z = s*s; w = z*z; t1= w*(Lg2+w*Lg4); t2= z*(Lg1+w*Lg3); R = t2+t1; hfsq=(float)0.5*f*f; return s*(hfsq+R); } openlibm-0.5.0/src/k_rem_pio2.c000066400000000000000000000371471266752446200163340ustar00rootroot00000000000000 /* @(#)k_rem_pio2.c 1.3 95/01/18 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/k_rem_pio2.c,v 1.11 2008/02/25 11:43:20 bde Exp $"); /* * __kernel_rem_pio2(x,y,e0,nx,prec) * double x[],y[]; int e0,nx,prec; * * __kernel_rem_pio2 return the last three digits of N with * y = x - N*pi/2 * so that |y| < pi/2. * * The method is to compute the integer (mod 8) and fraction parts of * (2/pi)*x without doing the full multiplication. In general we * skip the part of the product that are known to be a huge integer ( * more accurately, = 0 mod 8 ). Thus the number of operations are * independent of the exponent of the input. * * (2/pi) is represented by an array of 24-bit integers in ipio2[]. * * Input parameters: * x[] The input value (must be positive) is broken into nx * pieces of 24-bit integers in double precision format. * x[i] will be the i-th 24 bit of x. The scaled exponent * of x[0] is given in input parameter e0 (i.e., x[0]*2^e0 * match x's up to 24 bits. * * Example of breaking a double positive z into x[0]+x[1]+x[2]: * e0 = ilogb(z)-23 * z = scalbn(z,-e0) * for i = 0,1,2 * x[i] = floor(z) * z = (z-x[i])*2**24 * * * y[] ouput result in an array of double precision numbers. * The dimension of y[] is: * 24-bit precision 1 * 53-bit precision 2 * 64-bit precision 2 * 113-bit precision 3 * The actual value is the sum of them. Thus for 113-bit * precison, one may have to do something like: * * long double t,w,r_head, r_tail; * t = (long double)y[2] + (long double)y[1]; * w = (long double)y[0]; * r_head = t+w; * r_tail = w - (r_head - t); * * e0 The exponent of x[0]. Must be <= 16360 or you need to * expand the ipio2 table. * * nx dimension of x[] * * prec an integer indicating the precision: * 0 24 bits (single) * 1 53 bits (double) * 2 64 bits (extended) * 3 113 bits (quad) * * External function: * double scalbn(), floor(); * * * Here is the description of some local variables: * * jk jk+1 is the initial number of terms of ipio2[] needed * in the computation. The minimum and recommended value * for jk is 3,4,4,6 for single, double, extended, and quad. * jk+1 must be 2 larger than you might expect so that our * recomputation test works. (Up to 24 bits in the integer * part (the 24 bits of it that we compute) and 23 bits in * the fraction part may be lost to cancelation before we * recompute.) * * jz local integer variable indicating the number of * terms of ipio2[] used. * * jx nx - 1 * * jv index for pointing to the suitable ipio2[] for the * computation. In general, we want * ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8 * is an integer. Thus * e0-3-24*jv >= 0 or (e0-3)/24 >= jv * Hence jv = max(0,(e0-3)/24). * * jp jp+1 is the number of terms in PIo2[] needed, jp = jk. * * q[] double array with integral value, representing the * 24-bits chunk of the product of x and 2/pi. * * q0 the corresponding exponent of q[0]. Note that the * exponent for q[i] would be q0-24*i. * * PIo2[] double precision array, obtained by cutting pi/2 * into 24 bits chunks. * * f[] ipio2[] in floating point * * iq[] integer array by breaking up q[] in 24-bits chunk. * * fq[] final product of x*(2/pi) in fq[0],..,fq[jk] * * ih integer. If >0 it indicates q[] is >= 0.5, hence * it also indicates the *sign* of the result. * */ /* * Constants: * The hexadecimal values are the intended ones for the following * constants. The decimal values may be used, provided that the * compiler will convert from decimal to binary accurately enough * to produce the hexadecimal values shown. */ #include #include #include "math_private.h" static const int init_jk[] = {3,4,4,6}; /* initial value for jk */ /* * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi * * integer array, contains the (24*i)-th to (24*i+23)-th * bit of 2/pi after binary point. The corresponding * floating value is * * ipio2[i] * 2^(-24(i+1)). * * NB: This table must have at least (e0-3)/24 + jk terms. * For quad precision (e0 <= 16360, jk = 6), this is 686. */ static const int32_t ipio2[] = { 0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62, 0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A, 0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129, 0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41, 0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8, 0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF, 0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5, 0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08, 0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3, 0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880, 0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B, #if LDBL_MAX_EXP > 1024 #if LDBL_MAX_EXP > 16384 #error "ipio2 table needs to be expanded" #endif 0x47C419, 0xC367CD, 0xDCE809, 0x2A8359, 0xC4768B, 0x961CA6, 0xDDAF44, 0xD15719, 0x053EA5, 0xFF0705, 0x3F7E33, 0xE832C2, 0xDE4F98, 0x327DBB, 0xC33D26, 0xEF6B1E, 0x5EF89F, 0x3A1F35, 0xCAF27F, 0x1D87F1, 0x21907C, 0x7C246A, 0xFA6ED5, 0x772D30, 0x433B15, 0xC614B5, 0x9D19C3, 0xC2C4AD, 0x414D2C, 0x5D000C, 0x467D86, 0x2D71E3, 0x9AC69B, 0x006233, 0x7CD2B4, 0x97A7B4, 0xD55537, 0xF63ED7, 0x1810A3, 0xFC764D, 0x2A9D64, 0xABD770, 0xF87C63, 0x57B07A, 0xE71517, 0x5649C0, 0xD9D63B, 0x3884A7, 0xCB2324, 0x778AD6, 0x23545A, 0xB91F00, 0x1B0AF1, 0xDFCE19, 0xFF319F, 0x6A1E66, 0x615799, 0x47FBAC, 0xD87F7E, 0xB76522, 0x89E832, 0x60BFE6, 0xCDC4EF, 0x09366C, 0xD43F5D, 0xD7DE16, 0xDE3B58, 0x929BDE, 0x2822D2, 0xE88628, 0x4D58E2, 0x32CAC6, 0x16E308, 0xCB7DE0, 0x50C017, 0xA71DF3, 0x5BE018, 0x34132E, 0x621283, 0x014883, 0x5B8EF5, 0x7FB0AD, 0xF2E91E, 0x434A48, 0xD36710, 0xD8DDAA, 0x425FAE, 0xCE616A, 0xA4280A, 0xB499D3, 0xF2A606, 0x7F775C, 0x83C2A3, 0x883C61, 0x78738A, 0x5A8CAF, 0xBDD76F, 0x63A62D, 0xCBBFF4, 0xEF818D, 0x67C126, 0x45CA55, 0x36D9CA, 0xD2A828, 0x8D61C2, 0x77C912, 0x142604, 0x9B4612, 0xC459C4, 0x44C5C8, 0x91B24D, 0xF31700, 0xAD43D4, 0xE54929, 0x10D5FD, 0xFCBE00, 0xCC941E, 0xEECE70, 0xF53E13, 0x80F1EC, 0xC3E7B3, 0x28F8C7, 0x940593, 0x3E71C1, 0xB3092E, 0xF3450B, 0x9C1288, 0x7B20AB, 0x9FB52E, 0xC29247, 0x2F327B, 0x6D550C, 0x90A772, 0x1FE76B, 0x96CB31, 0x4A1679, 0xE27941, 0x89DFF4, 0x9794E8, 0x84E6E2, 0x973199, 0x6BED88, 0x365F5F, 0x0EFDBB, 0xB49A48, 0x6CA467, 0x427271, 0x325D8D, 0xB8159F, 0x09E5BC, 0x25318D, 0x3974F7, 0x1C0530, 0x010C0D, 0x68084B, 0x58EE2C, 0x90AA47, 0x02E774, 0x24D6BD, 0xA67DF7, 0x72486E, 0xEF169F, 0xA6948E, 0xF691B4, 0x5153D1, 0xF20ACF, 0x339820, 0x7E4BF5, 0x6863B2, 0x5F3EDD, 0x035D40, 0x7F8985, 0x295255, 0xC06437, 0x10D86D, 0x324832, 0x754C5B, 0xD4714E, 0x6E5445, 0xC1090B, 0x69F52A, 0xD56614, 0x9D0727, 0x50045D, 0xDB3BB4, 0xC576EA, 0x17F987, 0x7D6B49, 0xBA271D, 0x296996, 0xACCCC6, 0x5414AD, 0x6AE290, 0x89D988, 0x50722C, 0xBEA404, 0x940777, 0x7030F3, 0x27FC00, 0xA871EA, 0x49C266, 0x3DE064, 0x83DD97, 0x973FA3, 0xFD9443, 0x8C860D, 0xDE4131, 0x9D3992, 0x8C70DD, 0xE7B717, 0x3BDF08, 0x2B3715, 0xA0805C, 0x93805A, 0x921110, 0xD8E80F, 0xAF806C, 0x4BFFDB, 0x0F9038, 0x761859, 0x15A562, 0xBBCB61, 0xB989C7, 0xBD4010, 0x04F2D2, 0x277549, 0xF6B6EB, 0xBB22DB, 0xAA140A, 0x2F2689, 0x768364, 0x333B09, 0x1A940E, 0xAA3A51, 0xC2A31D, 0xAEEDAF, 0x12265C, 0x4DC26D, 0x9C7A2D, 0x9756C0, 0x833F03, 0xF6F009, 0x8C402B, 0x99316D, 0x07B439, 0x15200C, 0x5BC3D8, 0xC492F5, 0x4BADC6, 0xA5CA4E, 0xCD37A7, 0x36A9E6, 0x9492AB, 0x6842DD, 0xDE6319, 0xEF8C76, 0x528B68, 0x37DBFC, 0xABA1AE, 0x3115DF, 0xA1AE00, 0xDAFB0C, 0x664D64, 0xB705ED, 0x306529, 0xBF5657, 0x3AFF47, 0xB9F96A, 0xF3BE75, 0xDF9328, 0x3080AB, 0xF68C66, 0x15CB04, 0x0622FA, 0x1DE4D9, 0xA4B33D, 0x8F1B57, 0x09CD36, 0xE9424E, 0xA4BE13, 0xB52333, 0x1AAAF0, 0xA8654F, 0xA5C1D2, 0x0F3F0B, 0xCD785B, 0x76F923, 0x048B7B, 0x721789, 0x53A6C6, 0xE26E6F, 0x00EBEF, 0x584A9B, 0xB7DAC4, 0xBA66AA, 0xCFCF76, 0x1D02D1, 0x2DF1B1, 0xC1998C, 0x77ADC3, 0xDA4886, 0xA05DF7, 0xF480C6, 0x2FF0AC, 0x9AECDD, 0xBC5C3F, 0x6DDED0, 0x1FC790, 0xB6DB2A, 0x3A25A3, 0x9AAF00, 0x9353AD, 0x0457B6, 0xB42D29, 0x7E804B, 0xA707DA, 0x0EAA76, 0xA1597B, 0x2A1216, 0x2DB7DC, 0xFDE5FA, 0xFEDB89, 0xFDBE89, 0x6C76E4, 0xFCA906, 0x70803E, 0x156E85, 0xFF87FD, 0x073E28, 0x336761, 0x86182A, 0xEABD4D, 0xAFE7B3, 0x6E6D8F, 0x396795, 0x5BBF31, 0x48D784, 0x16DF30, 0x432DC7, 0x356125, 0xCE70C9, 0xB8CB30, 0xFD6CBF, 0xA200A4, 0xE46C05, 0xA0DD5A, 0x476F21, 0xD21262, 0x845CB9, 0x496170, 0xE0566B, 0x015299, 0x375550, 0xB7D51E, 0xC4F133, 0x5F6E13, 0xE4305D, 0xA92E85, 0xC3B21D, 0x3632A1, 0xA4B708, 0xD4B1EA, 0x21F716, 0xE4698F, 0x77FF27, 0x80030C, 0x2D408D, 0xA0CD4F, 0x99A520, 0xD3A2B3, 0x0A5D2F, 0x42F9B4, 0xCBDA11, 0xD0BE7D, 0xC1DB9B, 0xBD17AB, 0x81A2CA, 0x5C6A08, 0x17552E, 0x550027, 0xF0147F, 0x8607E1, 0x640B14, 0x8D4196, 0xDEBE87, 0x2AFDDA, 0xB6256B, 0x34897B, 0xFEF305, 0x9EBFB9, 0x4F6A68, 0xA82A4A, 0x5AC44F, 0xBCF82D, 0x985AD7, 0x95C7F4, 0x8D4D0D, 0xA63A20, 0x5F57A4, 0xB13F14, 0x953880, 0x0120CC, 0x86DD71, 0xB6DEC9, 0xF560BF, 0x11654D, 0x6B0701, 0xACB08C, 0xD0C0B2, 0x485551, 0x0EFB1E, 0xC37295, 0x3B06A3, 0x3540C0, 0x7BDC06, 0xCC45E0, 0xFA294E, 0xC8CAD6, 0x41F3E8, 0xDE647C, 0xD8649B, 0x31BED9, 0xC397A4, 0xD45877, 0xC5E369, 0x13DAF0, 0x3C3ABA, 0x461846, 0x5F7555, 0xF5BDD2, 0xC6926E, 0x5D2EAC, 0xED440E, 0x423E1C, 0x87C461, 0xE9FD29, 0xF3D6E7, 0xCA7C22, 0x35916F, 0xC5E008, 0x8DD7FF, 0xE26A6E, 0xC6FDB0, 0xC10893, 0x745D7C, 0xB2AD6B, 0x9D6ECD, 0x7B723E, 0x6A11C6, 0xA9CFF7, 0xDF7329, 0xBAC9B5, 0x5100B7, 0x0DB2E2, 0x24BA74, 0x607DE5, 0x8AD874, 0x2C150D, 0x0C1881, 0x94667E, 0x162901, 0x767A9F, 0xBEFDFD, 0xEF4556, 0x367ED9, 0x13D9EC, 0xB9BA8B, 0xFC97C4, 0x27A831, 0xC36EF1, 0x36C594, 0x56A8D8, 0xB5A8B4, 0x0ECCCF, 0x2D8912, 0x34576F, 0x89562C, 0xE3CE99, 0xB920D6, 0xAA5E6B, 0x9C2A3E, 0xCC5F11, 0x4A0BFD, 0xFBF4E1, 0x6D3B8E, 0x2C86E2, 0x84D4E9, 0xA9B4FC, 0xD1EEEF, 0xC9352E, 0x61392F, 0x442138, 0xC8D91B, 0x0AFC81, 0x6A4AFB, 0xD81C2F, 0x84B453, 0x8C994E, 0xCC2254, 0xDC552A, 0xD6C6C0, 0x96190B, 0xB8701A, 0x649569, 0x605A26, 0xEE523F, 0x0F117F, 0x11B5F4, 0xF5CBFC, 0x2DBC34, 0xEEBC34, 0xCC5DE8, 0x605EDD, 0x9B8E67, 0xEF3392, 0xB817C9, 0x9B5861, 0xBC57E1, 0xC68351, 0x103ED8, 0x4871DD, 0xDD1C2D, 0xA118AF, 0x462C21, 0xD7F359, 0x987AD9, 0xC0549E, 0xFA864F, 0xFC0656, 0xAE79E5, 0x362289, 0x22AD38, 0xDC9367, 0xAAE855, 0x382682, 0x9BE7CA, 0xA40D51, 0xB13399, 0x0ED7A9, 0x480569, 0xF0B265, 0xA7887F, 0x974C88, 0x36D1F9, 0xB39221, 0x4A827B, 0x21CF98, 0xDC9F40, 0x5547DC, 0x3A74E1, 0x42EB67, 0xDF9DFE, 0x5FD45E, 0xA4677B, 0x7AACBA, 0xA2F655, 0x23882B, 0x55BA41, 0x086E59, 0x862A21, 0x834739, 0xE6E389, 0xD49EE5, 0x40FB49, 0xE956FF, 0xCA0F1C, 0x8A59C5, 0x2BFA94, 0xC5C1D3, 0xCFC50F, 0xAE5ADB, 0x86C547, 0x624385, 0x3B8621, 0x94792C, 0x876110, 0x7B4C2A, 0x1A2C80, 0x12BF43, 0x902688, 0x893C78, 0xE4C4A8, 0x7BDBE5, 0xC23AC4, 0xEAF426, 0x8A67F7, 0xBF920D, 0x2BA365, 0xB1933D, 0x0B7CBD, 0xDC51A4, 0x63DD27, 0xDDE169, 0x19949A, 0x9529A8, 0x28CE68, 0xB4ED09, 0x209F44, 0xCA984E, 0x638270, 0x237C7E, 0x32B90F, 0x8EF5A7, 0xE75614, 0x08F121, 0x2A9DB5, 0x4D7E6F, 0x5119A5, 0xABF9B5, 0xD6DF82, 0x61DD96, 0x023616, 0x9F3AC4, 0xA1A283, 0x6DED72, 0x7A8D39, 0xA9B882, 0x5C326B, 0x5B2746, 0xED3400, 0x7700D2, 0x55F4FC, 0x4D5901, 0x8071E0, #endif }; static const double PIo2[] = { 1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */ 7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */ 5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */ 3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */ 1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */ 1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */ 2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */ 2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */ }; static const double zero = 0.0, one = 1.0, two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */ twon24 = 5.96046447753906250000e-08; /* 0x3E700000, 0x00000000 */ DLLEXPORT int __kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec) { int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih; double z,fw,f[20],fq[20],q[20]; /* initialize jk*/ jk = init_jk[prec]; jp = jk; /* determine jx,jv,q0, note that 3>q0 */ jx = nx-1; jv = (e0-3)/24; if(jv<0) jv=0; q0 = e0-24*(jv+1); /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */ j = jv-jx; m = jx+jk; for(i=0;i<=m;i++,j++) f[i] = (j<0)? zero : (double) ipio2[j]; /* compute q[0],q[1],...q[jk] */ for (i=0;i<=jk;i++) { for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; q[i] = fw; } jz = jk; recompute: /* distill q[] into iq[] reversingly */ for(i=0,j=jz,z=q[jz];j>0;i++,j--) { fw = (double)((int32_t)(twon24* z)); iq[i] = (int32_t)(z-two24*fw); z = q[j-1]+fw; } /* compute n */ z = scalbn(z,q0); /* actual value of z */ z -= 8.0*floor(z*0.125); /* trim off integer >= 8 */ n = (int32_t) z; z -= (double)n; ih = 0; if(q0>0) { /* need iq[jz-1] to determine n */ i = (iq[jz-1]>>(24-q0)); n += i; iq[jz-1] -= i<<(24-q0); ih = iq[jz-1]>>(23-q0); } else if(q0==0) ih = iq[jz-1]>>23; else if(z>=0.5) ih=2; if(ih>0) { /* q > 0.5 */ n += 1; carry = 0; for(i=0;i0) { /* rare case: chance is 1 in 12 */ switch(q0) { case 1: iq[jz-1] &= 0x7fffff; break; case 2: iq[jz-1] &= 0x3fffff; break; } } if(ih==2) { z = one - z; if(carry!=0) z -= scalbn(one,q0); } } /* check if recomputation is needed */ if(z==zero) { j = 0; for (i=jz-1;i>=jk;i--) j |= iq[i]; if(j==0) { /* need recomputation */ for(k=1;iq[jk-k]==0;k++); /* k = no. of terms needed */ for(i=jz+1;i<=jz+k;i++) { /* add q[jz+1] to q[jz+k] */ f[jx+i] = (double) ipio2[jv+i]; for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; q[i] = fw; } jz += k; goto recompute; } } /* chop off zero terms */ if(z==0.0) { jz -= 1; q0 -= 24; while(iq[jz]==0) { jz--; q0-=24;} } else { /* break z into 24-bit if necessary */ z = scalbn(z,-q0); if(z>=two24) { fw = (double)((int32_t)(twon24*z)); iq[jz] = (int32_t)(z-two24*fw); jz += 1; q0 += 24; iq[jz] = (int32_t) fw; } else iq[jz] = (int32_t) z ; } /* convert integer "bit" chunk to floating-point value */ fw = scalbn(one,q0); for(i=jz;i>=0;i--) { q[i] = fw*(double)iq[i]; fw*=twon24; } /* compute PIo2[0,...,jp]*q[jz,...,0] */ for(i=jz;i>=0;i--) { for(fw=0.0,k=0;k<=jp&&k<=jz-i;k++) fw += PIo2[k]*q[i+k]; fq[jz-i] = fw; } /* compress fq[] into y[] */ switch(prec) { case 0: fw = 0.0; for (i=jz;i>=0;i--) fw += fq[i]; y[0] = (ih==0)? fw: -fw; break; case 1: case 2: fw = 0.0; for (i=jz;i>=0;i--) fw += fq[i]; STRICT_ASSIGN(double,fw,fw); y[0] = (ih==0)? fw: -fw; fw = fq[0]-fw; for (i=1;i<=jz;i++) fw += fq[i]; y[1] = (ih==0)? fw: -fw; break; case 3: /* painful */ for (i=jz;i>0;i--) { fw = fq[i-1]+fq[i]; fq[i] += fq[i-1]-fw; fq[i-1] = fw; } for (i=jz;i>1;i--) { fw = fq[i-1]+fq[i]; fq[i] += fq[i-1]-fw; fq[i-1] = fw; } for (fw=0.0,i=jz;i>=2;i--) fw += fq[i]; if(ih==0) { y[0] = fq[0]; y[1] = fq[1]; y[2] = fw; } else { y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw; } } return n&7; } openlibm-0.5.0/src/k_sin.c000066400000000000000000000045501266752446200154010ustar00rootroot00000000000000 /* @(#)k_sin.c 1.3 95/01/18 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/k_sin.c,v 1.11 2008/02/19 12:54:14 bde Exp $"); /* __kernel_sin( x, y, iy) * kernel sin function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854 * Input x is assumed to be bounded by ~pi/4 in magnitude. * Input y is the tail of x. * Input iy indicates whether y is 0. (if iy=0, y assume to be 0). * * Algorithm * 1. Since sin(-x) = -sin(x), we need only to consider positive x. * 2. Callers must return sin(-0) = -0 without calling here since our * odd polynomial is not evaluated in a way that preserves -0. * Callers may do the optimization sin(x) ~ x for tiny x. * 3. sin(x) is approximated by a polynomial of degree 13 on * [0,pi/4] * 3 13 * sin(x) ~ x + S1*x + ... + S6*x * where * * |sin(x) 2 4 6 8 10 12 | -58 * |----- - (1+S1*x +S2*x +S3*x +S4*x +S5*x +S6*x )| <= 2 * | x | * * 4. sin(x+y) = sin(x) + sin'(x')*y * ~ sin(x) + (1-x*x/2)*y * For better accuracy, let * 3 2 2 2 2 * r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6)))) * then 3 2 * sin(x) = x + (S1*x + (x *(r-y/2)+y)) */ #include #include "math_private.h" static const double half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */ S1 = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */ S2 = 8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */ S3 = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */ S4 = 2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */ S5 = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */ S6 = 1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */ DLLEXPORT double __kernel_sin(double x, double y, int iy) { double z,r,v,w; z = x*x; w = z*z; r = S2+z*(S3+z*S4) + z*w*(S5+z*S6); v = z*x; if(iy==0) return x+v*(S1+z*r); else return x-((z*(half*y-v*r)-y)-v*S1); } openlibm-0.5.0/src/k_sinf.c000066400000000000000000000024751266752446200155530ustar00rootroot00000000000000/* k_sinf.c -- float version of k_sin.c * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. * Optimized by Bruce D. Evans. */ /* * ==================================================== * 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. * ==================================================== */ #ifndef INLINE_KERNEL_SINDF #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/k_sinf.c,v 1.16 2009/06/03 08:16:34 ed Exp $"); #endif #include #include "math_private.h" /* |sin(x)/x - s(x)| < 2**-37.5 (~[-4.89e-12, 4.824e-12]). */ static const double S1 = -0x15555554cbac77.0p-55, /* -0.166666666416265235595 */ S2 = 0x111110896efbb2.0p-59, /* 0.0083333293858894631756 */ S3 = -0x1a00f9e2cae774.0p-65, /* -0.000198393348360966317347 */ S4 = 0x16cd878c3b46a7.0p-71; /* 0.0000027183114939898219064 */ #ifndef INLINE_KERNEL_SINDF extern #endif //__inline float DLLEXPORT float __kernel_sindf(double x) { double r, s, w, z; /* Try to optimize for parallel evaluation as in k_tanf.c. */ z = x*x; w = z*z; r = S3+z*S4; s = z*x; return (x + s*(S1+z*S2)) + s*w*r; } openlibm-0.5.0/src/k_tan.c000066400000000000000000000100221266752446200153610ustar00rootroot00000000000000/* @(#)k_tan.c 1.5 04/04/22 SMI */ /* * ==================================================== * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved. * * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ /* INDENT OFF */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/k_tan.c,v 1.13 2008/02/22 02:30:35 das Exp $"); /* __kernel_tan( x, y, k ) * kernel tan function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854 * Input x is assumed to be bounded by ~pi/4 in magnitude. * Input y is the tail of x. * Input k indicates whether tan (if k = 1) or -1/tan (if k = -1) is returned. * * Algorithm * 1. Since tan(-x) = -tan(x), we need only to consider positive x. * 2. Callers must return tan(-0) = -0 without calling here since our * odd polynomial is not evaluated in a way that preserves -0. * Callers may do the optimization tan(x) ~ x for tiny x. * 3. tan(x) is approximated by a odd polynomial of degree 27 on * [0,0.67434] * 3 27 * tan(x) ~ x + T1*x + ... + T13*x * where * * |tan(x) 2 4 26 | -59.2 * |----- - (1+T1*x +T2*x +.... +T13*x )| <= 2 * | x | * * Note: tan(x+y) = tan(x) + tan'(x)*y * ~ tan(x) + (1+x*x)*y * Therefore, for better accuracy in computing tan(x+y), let * 3 2 2 2 2 * r = x *(T2+x *(T3+x *(...+x *(T12+x *T13)))) * then * 3 2 * tan(x+y) = x + (T1*x + (x *(r+y)+y)) * * 4. For x in [0.67434,pi/4], let y = pi/4 - x, then * tan(x) = tan(pi/4-y) = (1-tan(y))/(1+tan(y)) * = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y))) */ #include #include "math_private.h" static const double xxx[] = { 3.33333333333334091986e-01, /* 3FD55555, 55555563 */ 1.33333333333201242699e-01, /* 3FC11111, 1110FE7A */ 5.39682539762260521377e-02, /* 3FABA1BA, 1BB341FE */ 2.18694882948595424599e-02, /* 3F9664F4, 8406D637 */ 8.86323982359930005737e-03, /* 3F8226E3, E96E8493 */ 3.59207910759131235356e-03, /* 3F6D6D22, C9560328 */ 1.45620945432529025516e-03, /* 3F57DBC8, FEE08315 */ 5.88041240820264096874e-04, /* 3F4344D8, F2F26501 */ 2.46463134818469906812e-04, /* 3F3026F7, 1A8D1068 */ 7.81794442939557092300e-05, /* 3F147E88, A03792A6 */ 7.14072491382608190305e-05, /* 3F12B80F, 32F0A7E9 */ -1.85586374855275456654e-05, /* BEF375CB, DB605373 */ 2.59073051863633712884e-05, /* 3EFB2A70, 74BF7AD4 */ /* one */ 1.00000000000000000000e+00, /* 3FF00000, 00000000 */ /* pio4 */ 7.85398163397448278999e-01, /* 3FE921FB, 54442D18 */ /* pio4lo */ 3.06161699786838301793e-17 /* 3C81A626, 33145C07 */ }; #define one xxx[13] #define pio4 xxx[14] #define pio4lo xxx[15] #define T xxx /* INDENT ON */ DLLEXPORT double __kernel_tan(double x, double y, int iy) { double z, r, v, w, s; int32_t ix, hx; GET_HIGH_WORD(hx,x); ix = hx & 0x7fffffff; /* high word of |x| */ if (ix >= 0x3FE59428) { /* |x| >= 0.6744 */ if (hx < 0) { x = -x; y = -y; } z = pio4 - x; w = pio4lo - y; x = z + w; y = 0.0; } z = x * x; w = z * z; /* * Break x^5*(T[1]+x^2*T[2]+...) into * x^5(T[1]+x^4*T[3]+...+x^20*T[11]) + * x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12])) */ r = T[1] + w * (T[3] + w * (T[5] + w * (T[7] + w * (T[9] + w * T[11])))); v = z * (T[2] + w * (T[4] + w * (T[6] + w * (T[8] + w * (T[10] + w * T[12]))))); s = z * x; r = y + z * (s * (r + v) + y); r += T[0] * s; w = x + r; if (ix >= 0x3FE59428) { v = (double) iy; return (double) (1 - ((hx >> 30) & 2)) * (v - 2.0 * (x - (w * w / (w + v) - r))); } if (iy == 1) return w; else { /* * if allow error up to 2 ulp, simply return * -1.0 / (x+r) here */ /* compute -1.0 / (x+r) accurately */ double a, t; z = w; SET_LOW_WORD(z,0); v = r - (z - x); /* z+v = r+x */ t = a = -1.0 / w; /* a = -1.0/w */ SET_LOW_WORD(t,0); s = 1.0 + t * z; return t + a * (s + t * v); } } openlibm-0.5.0/src/k_tanf.c000066400000000000000000000041061266752446200155350ustar00rootroot00000000000000/* k_tanf.c -- float version of k_tan.c * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. * Optimized by Bruce D. Evans. */ /* * ==================================================== * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved. * * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #ifndef INLINE_KERNEL_TANDF #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/k_tanf.c,v 1.23 2009/06/03 08:16:34 ed Exp $"); #endif #include #include "math_private.h" /* |tan(x)/x - t(x)| < 2**-25.5 (~[-2e-08, 2e-08]). */ static const double T[] = { 0x15554d3418c99f.0p-54, /* 0.333331395030791399758 */ 0x1112fd38999f72.0p-55, /* 0.133392002712976742718 */ 0x1b54c91d865afe.0p-57, /* 0.0533812378445670393523 */ 0x191df3908c33ce.0p-58, /* 0.0245283181166547278873 */ 0x185dadfcecf44e.0p-61, /* 0.00297435743359967304927 */ 0x1362b9bf971bcd.0p-59, /* 0.00946564784943673166728 */ }; #ifndef INLINE_KERNEL_TANDF extern #endif //__inline float DLLEXPORT float __kernel_tandf(double x, int iy) { double z,r,w,s,t,u; z = x*x; /* * Split up the polynomial into small independent terms to give * opportunities for parallel evaluation. The chosen splitting is * micro-optimized for Athlons (XP, X64). It costs 2 multiplications * relative to Horner's method on sequential machines. * * We add the small terms from lowest degree up for efficiency on * non-sequential machines (the lowest degree terms tend to be ready * earlier). Apart from this, we don't care about order of * operations, and don't need to to care since we have precision to * spare. However, the chosen splitting is good for accuracy too, * and would give results as accurate as Horner's method if the * small terms were added from highest degree down. */ r = T[4]+z*T[5]; t = T[2]+z*T[3]; w = z*z; s = z*x; u = T[0]+z*T[1]; r = (x+s*u)+(s*w)*(t+w*r); if(iy==1) return r; else return -1.0/r; } openlibm-0.5.0/src/math_private.h000066400000000000000000000204601266752446200167640ustar00rootroot00000000000000/* * ==================================================== * 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. * ==================================================== */ /* * from: @(#)fdlibm.h 5.1 93/09/24 * $FreeBSD: src/lib/msun/src/math_private.h,v 1.34 2011/10/21 06:27:56 das Exp $ */ #ifndef _MATH_PRIVATE_H_ #define _MATH_PRIVATE_H_ #include #include "cdefs-compat.h" #include "types-compat.h" #include "fpmath.h" #include #include "math_private_openbsd.h" /* * The original fdlibm code used statements like: * n0 = ((*(int*)&one)>>29)^1; * index of high word * * ix0 = *(n0+(int*)&x); * high word of x * * ix1 = *((1-n0)+(int*)&x); * low word of x * * to dig two 32 bit words out of the 64 bit IEEE floating point * value. That is non-ANSI, and, moreover, the gcc instruction * scheduler gets it wrong. We instead use the following macros. * Unlike the original code, we determine the endianness at compile * time, not at run time; I don't see much benefit to selecting * endianness at run time. */ /* * A union which permits us to convert between a double and two 32 bit * ints. */ #if __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__ typedef union { double value; struct { u_int32_t msw; u_int32_t lsw; } parts; struct { u_int64_t w; } xparts; } ieee_double_shape_type; #endif #if __FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__ typedef union { double value; struct { u_int32_t lsw; u_int32_t msw; } parts; struct { u_int64_t w; } xparts; } ieee_double_shape_type; #endif /* Get two 32 bit ints from a double. */ #define EXTRACT_WORDS(ix0,ix1,d) \ do { \ ieee_double_shape_type ew_u; \ ew_u.value = (d); \ (ix0) = ew_u.parts.msw; \ (ix1) = ew_u.parts.lsw; \ } while (0) /* Get a 64-bit int from a double. */ #define EXTRACT_WORD64(ix,d) \ do { \ ieee_double_shape_type ew_u; \ ew_u.value = (d); \ (ix) = ew_u.xparts.w; \ } while (0) /* Get the more significant 32 bit int from a double. */ #define GET_HIGH_WORD(i,d) \ do { \ ieee_double_shape_type gh_u; \ gh_u.value = (d); \ (i) = gh_u.parts.msw; \ } while (0) /* Get the less significant 32 bit int from a double. */ #define GET_LOW_WORD(i,d) \ do { \ ieee_double_shape_type gl_u; \ gl_u.value = (d); \ (i) = gl_u.parts.lsw; \ } while (0) /* Set a double from two 32 bit ints. */ #define INSERT_WORDS(d,ix0,ix1) \ do { \ ieee_double_shape_type iw_u; \ iw_u.parts.msw = (ix0); \ iw_u.parts.lsw = (ix1); \ (d) = iw_u.value; \ } while (0) /* Set a double from a 64-bit int. */ #define INSERT_WORD64(d,ix) \ do { \ ieee_double_shape_type iw_u; \ iw_u.xparts.w = (ix); \ (d) = iw_u.value; \ } while (0) /* Set the more significant 32 bits of a double from an int. */ #define SET_HIGH_WORD(d,v) \ do { \ ieee_double_shape_type sh_u; \ sh_u.value = (d); \ sh_u.parts.msw = (v); \ (d) = sh_u.value; \ } while (0) /* Set the less significant 32 bits of a double from an int. */ #define SET_LOW_WORD(d,v) \ do { \ ieee_double_shape_type sl_u; \ sl_u.value = (d); \ sl_u.parts.lsw = (v); \ (d) = sl_u.value; \ } while (0) /* * A union which permits us to convert between a float and a 32 bit * int. */ typedef union { float value; /* FIXME: Assumes 32 bit int. */ unsigned int word; } ieee_float_shape_type; /* Get a 32 bit int from a float. */ #define GET_FLOAT_WORD(i,d) \ do { \ ieee_float_shape_type gf_u; \ gf_u.value = (d); \ (i) = gf_u.word; \ } while (0) /* Set a float from a 32 bit int. */ #define SET_FLOAT_WORD(d,i) \ do { \ ieee_float_shape_type sf_u; \ sf_u.word = (i); \ (d) = sf_u.value; \ } while (0) /* Get expsign as a 16 bit int from a long double. */ #define GET_LDBL_EXPSIGN(i,d) \ do { \ union IEEEl2bits ge_u; \ ge_u.e = (d); \ (i) = ge_u.xbits.expsign; \ } while (0) /* Set expsign of a long double from a 16 bit int. */ #define SET_LDBL_EXPSIGN(d,v) \ do { \ union IEEEl2bits se_u; \ se_u.e = (d); \ se_u.xbits.expsign = (v); \ (d) = se_u.e; \ } while (0) //VBS #define STRICT_ASSIGN(type, lval, rval) ((lval) = (rval)) /* VBS #ifdef FLT_EVAL_METHOD // Attempt to get strict C99 semantics for assignment with non-C99 compilers. #if FLT_EVAL_METHOD == 0 || __GNUC__ == 0 #define STRICT_ASSIGN(type, lval, rval) ((lval) = (rval)) #else #define STRICT_ASSIGN(type, lval, rval) do { \ volatile type __lval; \ \ if (sizeof(type) >= sizeof(double)) \ (lval) = (rval); \ else { \ __lval = (rval); \ (lval) = __lval; \ } \ } while (0) #endif #endif */ /* * Common routine to process the arguments to nan(), nanf(), and nanl(). */ void __scan_nan(u_int32_t *__words, int __num_words, const char *__s); #ifdef __GNUCLIKE_ASM /* Asm versions of some functions. */ #ifdef __amd64__ static __inline int irint(double x) { int n; __asm__("cvtsd2si %1,%0" : "=r" (n) : "x" (x)); return (n); } #define HAVE_EFFICIENT_IRINT #endif #ifdef __i386__ static __inline int irint(double x) { int n; __asm__("fistl %0" : "=m" (n) : "t" (x)); return (n); } #define HAVE_EFFICIENT_IRINT #endif #endif /* __GNUCLIKE_ASM */ /* * ieee style elementary functions * * We rename functions here to improve other sources' diffability * against fdlibm. */ #define __ieee754_sqrt sqrt #define __ieee754_acos acos #define __ieee754_acosh acosh #define __ieee754_log log #define __ieee754_log2 log2 #define __ieee754_atanh atanh #define __ieee754_asin asin #define __ieee754_atan2 atan2 #define __ieee754_exp exp #define __ieee754_cosh cosh #define __ieee754_fmod fmod #define __ieee754_pow pow #define __ieee754_lgamma lgamma #define __ieee754_lgamma_r lgamma_r #define __ieee754_log10 log10 #define __ieee754_sinh sinh #define __ieee754_hypot hypot #define __ieee754_j0 j0 #define __ieee754_j1 j1 #define __ieee754_y0 y0 #define __ieee754_y1 y1 #define __ieee754_jn jn #define __ieee754_yn yn #define __ieee754_remainder remainder #define __ieee754_sqrtf sqrtf #define __ieee754_acosf acosf #define __ieee754_acoshf acoshf #define __ieee754_logf logf #define __ieee754_atanhf atanhf #define __ieee754_asinf asinf #define __ieee754_atan2f atan2f #define __ieee754_expf expf #define __ieee754_coshf coshf #define __ieee754_fmodf fmodf #define __ieee754_powf powf #define __ieee754_lgammaf lgammaf #define __ieee754_lgammaf_r lgammaf_r #define __ieee754_log10f log10f #define __ieee754_log2f log2f #define __ieee754_sinhf sinhf #define __ieee754_hypotf hypotf #define __ieee754_j0f j0f #define __ieee754_j1f j1f #define __ieee754_y0f y0f #define __ieee754_y1f y1f #define __ieee754_jnf jnf #define __ieee754_ynf ynf #define __ieee754_remainderf remainderf /* fdlibm kernel function */ int __kernel_rem_pio2(double*,double*,int,int,int); /* double precision kernel functions */ #ifdef INLINE_REM_PIO2 __inline #endif int __ieee754_rem_pio2(double,double*); double __kernel_sin(double,double,int); double __kernel_cos(double,double); double __kernel_tan(double,double,int); double __ldexp_exp(double,int); double complex __ldexp_cexp(double complex,int); /* float precision kernel functions */ #ifdef INLINE_REM_PIO2F __inline #endif int __ieee754_rem_pio2f(float,double*); #ifdef INLINE_KERNEL_SINDF __inline #endif float __kernel_sindf(double); #ifdef INLINE_KERNEL_COSDF __inline #endif float __kernel_cosdf(double); #ifdef INLINE_KERNEL_TANDF __inline #endif float __kernel_tandf(double,int); float __ldexp_expf(float,int); float complex __ldexp_cexpf(float complex,int); /* long double precision kernel functions */ long double __kernel_sinl(long double, long double, int); long double __kernel_cosl(long double, long double); long double __kernel_tanl(long double, long double, int); #ifdef _WIN32 # ifdef IMPORT_EXPORTS # define DLLEXPORT __declspec(dllimport) # else # define DLLEXPORT __declspec(dllexport) # endif #else #define DLLEXPORT __attribute__ ((visibility("default"))) #endif #endif /* !_MATH_PRIVATE_H_ */ openlibm-0.5.0/src/math_private_openbsd.h000066400000000000000000000114211266752446200204730ustar00rootroot00000000000000/* $OpenBSD: math_private.h,v 1.17 2014/06/02 19:31:17 kettenis Exp $ */ /* * ==================================================== * 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. * ==================================================== */ /* * from: @(#)fdlibm.h 5.1 93/09/24 */ #ifndef _MATH_PRIVATE_OPENBSD_H_ #define _MATH_PRIVATE_OPENBSD_H_ #if __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__ typedef union { long double value; struct { u_int32_t mswhi; u_int32_t mswlo; u_int32_t lswhi; u_int32_t lswlo; } parts32; struct { u_int64_t msw; u_int64_t lsw; } parts64; } ieee_quad_shape_type; #endif #if __FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__ typedef union { long double value; struct { u_int32_t lswlo; u_int32_t lswhi; u_int32_t mswlo; u_int32_t mswhi; } parts32; struct { u_int64_t lsw; u_int64_t msw; } parts64; } ieee_quad_shape_type; #endif /* Get two 64 bit ints from a long double. */ #define GET_LDOUBLE_WORDS64(ix0,ix1,d) \ do { \ ieee_quad_shape_type qw_u; \ qw_u.value = (d); \ (ix0) = qw_u.parts64.msw; \ (ix1) = qw_u.parts64.lsw; \ } while (0) /* Set a long double from two 64 bit ints. */ #define SET_LDOUBLE_WORDS64(d,ix0,ix1) \ do { \ ieee_quad_shape_type qw_u; \ qw_u.parts64.msw = (ix0); \ qw_u.parts64.lsw = (ix1); \ (d) = qw_u.value; \ } while (0) /* Get the more significant 64 bits of a long double mantissa. */ #define GET_LDOUBLE_MSW64(v,d) \ do { \ ieee_quad_shape_type sh_u; \ sh_u.value = (d); \ (v) = sh_u.parts64.msw; \ } while (0) /* Set the more significant 64 bits of a long double mantissa from an int. */ #define SET_LDOUBLE_MSW64(d,v) \ do { \ ieee_quad_shape_type sh_u; \ sh_u.value = (d); \ sh_u.parts64.msw = (v); \ (d) = sh_u.value; \ } while (0) /* Get the least significant 64 bits of a long double mantissa. */ #define GET_LDOUBLE_LSW64(v,d) \ do { \ ieee_quad_shape_type sh_u; \ sh_u.value = (d); \ (v) = sh_u.parts64.lsw; \ } while (0) /* A union which permits us to convert between a long double and three 32 bit ints. */ #if __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__ typedef union { long double value; struct { #ifdef __LP64__ int padh:32; #endif int exp:16; int padl:16; u_int32_t msw; u_int32_t lsw; } parts; } ieee_extended_shape_type; #endif #if __FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__ typedef union { long double value; struct { u_int32_t lsw; u_int32_t msw; int exp:16; int padl:16; #ifdef __LP64__ int padh:32; #endif } parts; } ieee_extended_shape_type; #endif /* Get three 32 bit ints from a double. */ #define GET_LDOUBLE_WORDS(se,ix0,ix1,d) \ do { \ ieee_extended_shape_type ew_u; \ ew_u.value = (d); \ (se) = ew_u.parts.exp; \ (ix0) = ew_u.parts.msw; \ (ix1) = ew_u.parts.lsw; \ } while (0) /* Set a double from two 32 bit ints. */ #define SET_LDOUBLE_WORDS(d,se,ix0,ix1) \ do { \ ieee_extended_shape_type iw_u; \ iw_u.parts.exp = (se); \ iw_u.parts.msw = (ix0); \ iw_u.parts.lsw = (ix1); \ (d) = iw_u.value; \ } while (0) /* Get the more significant 32 bits of a long double mantissa. */ #define GET_LDOUBLE_MSW(v,d) \ do { \ ieee_extended_shape_type sh_u; \ sh_u.value = (d); \ (v) = sh_u.parts.msw; \ } while (0) /* Set the more significant 32 bits of a long double mantissa from an int. */ #define SET_LDOUBLE_MSW(d,v) \ do { \ ieee_extended_shape_type sh_u; \ sh_u.value = (d); \ sh_u.parts.msw = (v); \ (d) = sh_u.value; \ } while (0) /* Get int from the exponent of a long double. */ #define GET_LDOUBLE_EXP(se,d) \ do { \ ieee_extended_shape_type ge_u; \ ge_u.value = (d); \ (se) = ge_u.parts.exp; \ } while (0) /* Set exponent of a long double from an int. */ #define SET_LDOUBLE_EXP(d,se) \ do { \ ieee_extended_shape_type se_u; \ se_u.value = (d); \ se_u.parts.exp = (se); \ (d) = se_u.value; \ } while (0) /* * Common routine to process the arguments to nan(), nanf(), and nanl(). */ void __scan_nan(uint32_t *__words, int __num_words, const char *__s); /* * Functions internal to the math package, yet not static. */ double __exp__D(double, double); struct Double __log__D(double); long double __p1evll(long double, void *, int); long double __polevll(long double, void *, int); #endif /* _MATH_PRIVATE_OPENBSD_H_ */ openlibm-0.5.0/src/polevll.c000066400000000000000000000045331266752446200157540ustar00rootroot00000000000000/* $OpenBSD: polevll.c,v 1.2 2013/11/12 20:35:09 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* polevll.c * p1evll.c * * Evaluate polynomial * * * * SYNOPSIS: * * int N; * long double x, y, coef[N+1], polevl[]; * * y = polevll( x, coef, N ); * * * * DESCRIPTION: * * Evaluates polynomial of degree N: * * 2 N * y = C + C x + C x +...+ C x * 0 1 2 N * * Coefficients are stored in reverse order: * * coef[0] = C , ..., coef[N] = C . * N 0 * * The function p1evll() assumes that coef[N] = 1.0 and is * omitted from the array. Its calling arguments are * otherwise the same as polevll(). * * * SPEED: * * In the interest of speed, there are no checks for out * of bounds arithmetic. This routine is used by most of * the functions in the library. Depending on available * equipment features, the user may wish to rewrite the * program in microcode or assembly language. * */ #include #include "math_private.h" /* * Polynomial evaluator: * P[0] x^n + P[1] x^(n-1) + ... + P[n] */ long double __polevll(long double x, void *PP, int n) { long double y; long double *P; P = (long double *)PP; y = *P++; do { y = y * x + *P++; } while (--n); return (y); } /* * Polynomial evaluator: * x^n + P[0] x^(n-1) + P[1] x^(n-2) + ... + P[n] */ long double __p1evll(long double x, void *PP, int n) { long double y; long double *P; P = (long double *)PP; n -= 1; y = x + *P++; do { y = y * x + *P++; } while (--n); return (y); } openlibm-0.5.0/src/powerpc_fpmath.h000066400000000000000000000034221266752446200173160ustar00rootroot00000000000000/*- * Copyright (c) 2003 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ union IEEEl2bits { long double e; struct { unsigned int sign :1; unsigned int exp :11; unsigned int manh :20; unsigned int manl :32; } bits; }; #define mask_nbit_l(u) ((void)0) #define LDBL_IMPLICIT_NBIT #define LDBL_NBIT 0 #define LDBL_MANH_SIZE 20 #define LDBL_MANL_SIZE 32 #define LDBL_TO_ARRAY32(u, a) do { \ (a)[0] = (uint32_t)(u).bits.manl; \ (a)[1] = (uint32_t)(u).bits.manh; \ } while(0) openlibm-0.5.0/src/s_asinh.c000066400000000000000000000032241266752446200157170ustar00rootroot00000000000000/* @(#)s_asinh.c 5.1 93/09/24 */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_asinh.c,v 1.9 2008/02/22 02:30:35 das Exp $"); /* asinh(x) * Method : * Based on * asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ] * we have * asinh(x) := x if 1+x*x=1, * := sign(x)*(log(x)+ln2)) for large |x|, else * := sign(x)*log(2|x|+1/(|x|+sqrt(x*x+1))) if|x|>2, else * := sign(x)*log1p(|x| + x^2/(1 + sqrt(1+x^2))) */ #include #include "math_private.h" static const double one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ ln2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */ huge= 1.00000000000000000000e+300; DLLEXPORT double asinh(double x) { double t,w; int32_t hx,ix; GET_HIGH_WORD(hx,x); ix = hx&0x7fffffff; if(ix>=0x7ff00000) return x+x; /* x is inf or NaN */ if(ix< 0x3e300000) { /* |x|<2**-28 */ if(huge+x>one) return x; /* return x inexact except 0 */ } if(ix>0x41b00000) { /* |x| > 2**28 */ w = __ieee754_log(fabs(x))+ln2; } else if (ix>0x40000000) { /* 2**28 > |x| > 2.0 */ t = fabs(x); w = __ieee754_log(2.0*t+one/(__ieee754_sqrt(x*x+one)+t)); } else { /* 2.0 > |x| > 2**-28 */ t = x*x; w =log1p(fabs(x)+t/(one+__ieee754_sqrt(one+t))); } if(hx>0) return w; else return -w; } openlibm-0.5.0/src/s_asinhf.c000066400000000000000000000026411266752446200160670ustar00rootroot00000000000000/* s_asinhf.c -- float version of s_asinh.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_asinhf.c,v 1.9 2008/02/22 02:30:35 das Exp $"); #include #include "math_private.h" static const float one = 1.0000000000e+00, /* 0x3F800000 */ ln2 = 6.9314718246e-01, /* 0x3f317218 */ huge= 1.0000000000e+30; DLLEXPORT float asinhf(float x) { float t,w; int32_t hx,ix; GET_FLOAT_WORD(hx,x); ix = hx&0x7fffffff; if(ix>=0x7f800000) return x+x; /* x is inf or NaN */ if(ix< 0x31800000) { /* |x|<2**-28 */ if(huge+x>one) return x; /* return x inexact except 0 */ } if(ix>0x4d800000) { /* |x| > 2**28 */ w = __ieee754_logf(fabsf(x))+ln2; } else if (ix>0x40000000) { /* 2**28 > |x| > 2.0 */ t = fabsf(x); w = __ieee754_logf((float)2.0*t+one/(__ieee754_sqrtf(x*x+one)+t)); } else { /* 2.0 > |x| > 2**-28 */ t = x*x; w =log1pf(fabsf(x)+t/(one+__ieee754_sqrtf(one+t))); } if(hx>0) return w; else return -w; } openlibm-0.5.0/src/s_atan.c000066400000000000000000000102511266752446200155360ustar00rootroot00000000000000/* @(#)s_atan.c 5.1 93/09/24 */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_atan.c,v 1.13 2011/02/10 07:37:50 das Exp $"); /* atan(x) * Method * 1. Reduce x to positive by atan(x) = -atan(-x). * 2. According to the integer k=4t+0.25 chopped, t=x, the argument * is further reduced to one of the following intervals and the * arctangent of t is evaluated by the corresponding formula: * * [0,7/16] atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...) * [7/16,11/16] atan(x) = atan(1/2) + atan( (t-0.5)/(1+t/2) ) * [11/16.19/16] atan(x) = atan( 1 ) + atan( (t-1)/(1+t) ) * [19/16,39/16] atan(x) = atan(3/2) + atan( (t-1.5)/(1+1.5t) ) * [39/16,INF] atan(x) = atan(INF) + atan( -1/t ) * * Constants: * The hexadecimal values are the intended ones for the following * constants. The decimal values may be used, provided that the * compiler will convert from decimal to binary accurately enough * to produce the hexadecimal values shown. */ #include #include #include "math_private.h" static const double atanhi[] = { 4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */ 7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */ 9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */ 1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */ }; static const double atanlo[] = { 2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */ 3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */ 1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */ 6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */ }; static const double aT[] = { 3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */ -1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */ 1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */ -1.11111104054623557880e-01, /* 0xBFBC71C6, 0xFE231671 */ 9.09088713343650656196e-02, /* 0x3FB745CD, 0xC54C206E */ -7.69187620504482999495e-02, /* 0xBFB3B0F2, 0xAF749A6D */ 6.66107313738753120669e-02, /* 0x3FB10D66, 0xA0D03D51 */ -5.83357013379057348645e-02, /* 0xBFADDE2D, 0x52DEFD9A */ 4.97687799461593236017e-02, /* 0x3FA97B4B, 0x24760DEB */ -3.65315727442169155270e-02, /* 0xBFA2B444, 0x2C6A6C2F */ 1.62858201153657823623e-02, /* 0x3F90AD3A, 0xE322DA11 */ }; static const double one = 1.0, huge = 1.0e300; DLLEXPORT double atan(double x) { double w,s1,s2,z; int32_t ix,hx,id; GET_HIGH_WORD(hx,x); ix = hx&0x7fffffff; if(ix>=0x44100000) { /* if |x| >= 2^66 */ u_int32_t low; GET_LOW_WORD(low,x); if(ix>0x7ff00000|| (ix==0x7ff00000&&(low!=0))) return x+x; /* NaN */ if(hx>0) return atanhi[3]+*(volatile double *)&atanlo[3]; else return -atanhi[3]-*(volatile double *)&atanlo[3]; } if (ix < 0x3fdc0000) { /* |x| < 0.4375 */ if (ix < 0x3e400000) { /* |x| < 2^-27 */ if(huge+x>one) return x; /* raise inexact */ } id = -1; } else { x = fabs(x); if (ix < 0x3ff30000) { /* |x| < 1.1875 */ if (ix < 0x3fe60000) { /* 7/16 <=|x|<11/16 */ id = 0; x = (2.0*x-one)/(2.0+x); } else { /* 11/16<=|x|< 19/16 */ id = 1; x = (x-one)/(x+one); } } else { if (ix < 0x40038000) { /* |x| < 2.4375 */ id = 2; x = (x-1.5)/(one+1.5*x); } else { /* 2.4375 <= |x| < 2^66 */ id = 3; x = -1.0/x; } }} /* end of argument reduction */ z = x*x; w = z*z; /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */ s1 = z*(aT[0]+w*(aT[2]+w*(aT[4]+w*(aT[6]+w*(aT[8]+w*aT[10]))))); s2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9])))); if (id<0) return x - x*(s1+s2); else { z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x); return (hx<0)? -z:z; } } #if LDBL_MANT_DIG == 53 __weak_reference(atan, atanl); #endif openlibm-0.5.0/src/s_atanf.c000066400000000000000000000050111266752446200157020ustar00rootroot00000000000000/* s_atanf.c -- float version of s_atan.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_atanf.c,v 1.10 2008/08/01 01:24:25 das Exp $"); #include #include "math_private.h" static const float atanhi[] = { 4.6364760399e-01, /* atan(0.5)hi 0x3eed6338 */ 7.8539812565e-01, /* atan(1.0)hi 0x3f490fda */ 9.8279368877e-01, /* atan(1.5)hi 0x3f7b985e */ 1.5707962513e+00, /* atan(inf)hi 0x3fc90fda */ }; static const float atanlo[] = { 5.0121582440e-09, /* atan(0.5)lo 0x31ac3769 */ 3.7748947079e-08, /* atan(1.0)lo 0x33222168 */ 3.4473217170e-08, /* atan(1.5)lo 0x33140fb4 */ 7.5497894159e-08, /* atan(inf)lo 0x33a22168 */ }; static const float aT[] = { 3.3333328366e-01, -1.9999158382e-01, 1.4253635705e-01, -1.0648017377e-01, 6.1687607318e-02, }; static const float one = 1.0, huge = 1.0e30; DLLEXPORT float atanf(float x) { float w,s1,s2,z; int32_t ix,hx,id; GET_FLOAT_WORD(hx,x); ix = hx&0x7fffffff; if(ix>=0x4c800000) { /* if |x| >= 2**26 */ if(ix>0x7f800000) return x+x; /* NaN */ if(hx>0) return atanhi[3]+*(volatile float *)&atanlo[3]; else return -atanhi[3]-*(volatile float *)&atanlo[3]; } if (ix < 0x3ee00000) { /* |x| < 0.4375 */ if (ix < 0x39800000) { /* |x| < 2**-12 */ if(huge+x>one) return x; /* raise inexact */ } id = -1; } else { x = fabsf(x); if (ix < 0x3f980000) { /* |x| < 1.1875 */ if (ix < 0x3f300000) { /* 7/16 <=|x|<11/16 */ id = 0; x = ((float)2.0*x-one)/((float)2.0+x); } else { /* 11/16<=|x|< 19/16 */ id = 1; x = (x-one)/(x+one); } } else { if (ix < 0x401c0000) { /* |x| < 2.4375 */ id = 2; x = (x-(float)1.5)/(one+(float)1.5*x); } else { /* 2.4375 <= |x| < 2**26 */ id = 3; x = -(float)1.0/x; } }} /* end of argument reduction */ z = x*x; w = z*z; /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */ s1 = z*(aT[0]+w*(aT[2]+w*aT[4])); s2 = w*(aT[1]+w*aT[3]); if (id<0) return x - x*(s1+s2); else { z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x); return (hx<0)? -z:z; } } openlibm-0.5.0/src/s_atanl.c000066400000000000000000000046401266752446200157170ustar00rootroot00000000000000/* @(#)s_atan.c 5.1 93/09/24 */ /* FreeBSD: head/lib/msun/src/s_atan.c 176451 2008-02-22 02:30:36Z das */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_atanl.c,v 1.1 2008/07/31 22:41:26 das Exp $"); /* * See comments in s_atan.c. * Converted to long double by David Schultz . */ #include #include #include "invtrig.h" #include "math_private.h" static const long double one = 1.0, huge = 1.0e300; DLLEXPORT long double atanl(long double x) { union IEEEl2bits u; long double w,s1,s2,z; int id; int16_t expsign, expt; int32_t expman; u.e = x; expsign = u.xbits.expsign; expt = expsign & 0x7fff; if(expt >= ATAN_CONST) { /* if |x| is large, atan(x)~=pi/2 */ if(expt == BIAS + LDBL_MAX_EXP && ((u.bits.manh&~LDBL_NBIT)|u.bits.manl)!=0) return x+x; /* NaN */ if(expsign>0) return atanhi[3]+atanlo[3]; else return -atanhi[3]-atanlo[3]; } /* Extract the exponent and the first few bits of the mantissa. */ /* XXX There should be a more convenient way to do this. */ expman = (expt << 8) | ((u.bits.manh >> (MANH_SIZE - 9)) & 0xff); if (expman < ((BIAS - 2) << 8) + 0xc0) { /* |x| < 0.4375 */ if (expt < ATAN_LINEAR) { /* if |x| is small, atanl(x)~=x */ if(huge+x>one) return x; /* raise inexact */ } id = -1; } else { x = fabsl(x); if (expman < (BIAS << 8) + 0x30) { /* |x| < 1.1875 */ if (expman < ((BIAS - 1) << 8) + 0x60) { /* 7/16 <=|x|<11/16 */ id = 0; x = (2.0*x-one)/(2.0+x); } else { /* 11/16<=|x|< 19/16 */ id = 1; x = (x-one)/(x+one); } } else { if (expman < ((BIAS + 1) << 8) + 0x38) { /* |x| < 2.4375 */ id = 2; x = (x-1.5)/(one+1.5*x); } else { /* 2.4375 <= |x| < 2^ATAN_CONST */ id = 3; x = -1.0/x; } }} /* end of argument reduction */ z = x*x; w = z*z; /* break sum aT[i]z**(i+1) into odd and even poly */ s1 = z*T_even(w); s2 = w*T_odd(w); if (id<0) return x - x*(s1+s2); else { z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x); return (expsign<0)? -z:z; } } openlibm-0.5.0/src/s_cabs.c000066400000000000000000000021371266752446200155270ustar00rootroot00000000000000/* $OpenBSD: s_cabs.c,v 1.6 2013/07/03 04:46:36 espie Exp $ */ /* * Copyright (c) 2008 Martynas Venckus * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include #include double cabs(double complex z) { return hypot(__real__ z, __imag__ z); } #if LDBL_MANT_DIG == DBL_MANT_DIG __strong_alias(cabsl, cabs); #endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ openlibm-0.5.0/src/s_cabsf.c000066400000000000000000000017451266752446200157010ustar00rootroot00000000000000/* $OpenBSD: s_cabsf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ /* * Copyright (c) 2008 Martynas Venckus * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include float cabsf(float complex z) { return hypotf(__real__ z, __imag__ z); } openlibm-0.5.0/src/s_cabsl.c000066400000000000000000000017621266752446200157060ustar00rootroot00000000000000/* $OpenBSD: s_cabsl.c,v 1.1 2011/07/08 19:25:31 martynas Exp $ */ /* * Copyright (c) 2011 Martynas Venckus * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include long double cabsl(long double complex z) { return hypotl(__real__ z, __imag__ z); } openlibm-0.5.0/src/s_cacos.c000066400000000000000000000031621266752446200157060ustar00rootroot00000000000000/* $OpenBSD: s_cacos.c,v 1.6 2013/07/03 04:46:36 espie Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* cacos() * * Complex circular arc cosine * * * * SYNOPSIS: * * double complex cacos(); * double complex z, w; * * w = cacos (z); * * * * DESCRIPTION: * * * w = arccos z = PI/2 - arcsin z. * * * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * DEC -10,+10 5200 1.6e-15 2.8e-16 * IEEE -10,+10 30000 1.8e-14 2.2e-15 */ #include #include #include double complex cacos(double complex z) { double complex w; w = casin (z); w = (M_PI_2 - creal (w)) - cimag (w) * I; return (w); } #if LDBL_MANT_DIG == DBL_MANT_DIG __strong_alias(cacosl, cacos); #endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ openlibm-0.5.0/src/s_cacosf.c000066400000000000000000000026711266752446200160600ustar00rootroot00000000000000/* $OpenBSD: s_cacosf.c,v 1.2 2011/07/20 19:28:33 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* cacosf() * * Complex circular arc cosine * * * * SYNOPSIS: * * void cacosf(); * cmplxf z, w; * * cacosf( &z, &w ); * * * * DESCRIPTION: * * * w = arccos z = PI/2 - arcsin z. * * * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE -10,+10 30000 9.2e-6 1.2e-6 * */ #include #include float complex cacosf(float complex z) { float complex w; w = casinf( z ); w = ((float)M_PI_2 - crealf (w)) - cimagf (w) * I; return (w); } openlibm-0.5.0/src/s_cacosh.c000066400000000000000000000030041266752446200160510ustar00rootroot00000000000000/* $OpenBSD: s_cacosh.c,v 1.6 2013/07/03 04:46:36 espie Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* cacosh * * Complex inverse hyperbolic cosine * * * * SYNOPSIS: * * double complex cacosh(); * double complex z, w; * * w = cacosh (z); * * * * DESCRIPTION: * * acosh z = i acos z . * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE -10,+10 30000 1.6e-14 2.1e-15 * */ #include #include #include double complex cacosh(double complex z) { double complex w; w = I * cacos (z); return (w); } #if LDBL_MANT_DIG == DBL_MANT_DIG __strong_alias(cacoshl, cacosh); #endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ openlibm-0.5.0/src/s_cacoshf.c000066400000000000000000000026061266752446200162260ustar00rootroot00000000000000/* $OpenBSD: s_cacoshf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* cacoshf * * Complex inverse hyperbolic cosine * * * * SYNOPSIS: * * float complex cacoshf(); * float complex z, w; * * w = cacoshf (z); * * * * DESCRIPTION: * * acosh z = i acos z . * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE -10,+10 30000 1.6e-14 2.1e-15 * */ #include #include float complex cacoshf(float complex z) { float complex w; w = I * cacosf (z); return (w); } openlibm-0.5.0/src/s_cacoshl.c000066400000000000000000000026441266752446200162360ustar00rootroot00000000000000/* $OpenBSD: s_cacoshl.c,v 1.1 2011/07/08 19:25:31 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* cacoshl * * Complex inverse hyperbolic cosine * * * * SYNOPSIS: * * long double complex cacoshl(); * long double complex z, w; * * w = cacoshl (z); * * * * DESCRIPTION: * * acosh z = i acos z . * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE -10,+10 30000 1.6e-14 2.1e-15 * */ #include #include long double complex cacoshl(long double complex z) { long double complex w; w = I * cacosl(z); return (w); } openlibm-0.5.0/src/s_cacosl.c000066400000000000000000000031451266752446200160630ustar00rootroot00000000000000/* $OpenBSD: s_cacosl.c,v 1.3 2011/07/20 21:02:51 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* cacosl() * * Complex circular arc cosine * * * * SYNOPSIS: * * long double complex cacosl(); * long double complex z, w; * * w = cacosl( z ); * * * * DESCRIPTION: * * * w = arccos z = PI/2 - arcsin z. * * * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * DEC -10,+10 5200 1.6e-15 2.8e-16 * IEEE -10,+10 30000 1.8e-14 2.2e-15 */ #include #include static const long double PIO2L = 1.570796326794896619231321691639751442098585L; long double complex cacosl(long double complex z) { long double complex w; w = casinl(z); w = (PIO2L - creall(w)) - cimagl(w) * I; return (w); } openlibm-0.5.0/src/s_carg.c000066400000000000000000000031671266752446200155370ustar00rootroot00000000000000/*- * Copyright (c) 2005 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_carg.c,v 1.1 2007/12/12 23:43:51 das Exp $"); #include #include #include "math_private.h" DLLEXPORT double carg(double complex z) { return (atan2(cimag(z), creal(z))); } openlibm-0.5.0/src/s_cargf.c000066400000000000000000000031721266752446200157010ustar00rootroot00000000000000/*- * Copyright (c) 2005 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_cargf.c,v 1.1 2007/12/12 23:43:51 das Exp $"); #include #include #include "math_private.h" DLLEXPORT float cargf(float complex z) { return (atan2f(cimagf(z), crealf(z))); } openlibm-0.5.0/src/s_cargl.c000066400000000000000000000032131266752446200157030ustar00rootroot00000000000000/*- * Copyright (c) 2005-2008 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_cargl.c,v 1.1 2008/07/31 22:41:26 das Exp $"); #include #include #include "math_private.h" DLLEXPORT long double cargl(long double complex z) { return (atan2l(cimagl(z), creall(z))); } openlibm-0.5.0/src/s_casin.c000066400000000000000000000054431266752446200157170ustar00rootroot00000000000000/* $OpenBSD: s_casin.c,v 1.6 2013/07/03 04:46:36 espie Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* casin() * * Complex circular arc sine * * * * SYNOPSIS: * * double complex casin(); * double complex z, w; * * w = casin (z); * * * * DESCRIPTION: * * Inverse complex sine: * * 2 * w = -i clog( iz + csqrt( 1 - z ) ). * * casin(z) = -i casinh(iz) * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * DEC -10,+10 10100 2.1e-15 3.4e-16 * IEEE -10,+10 30000 2.2e-14 2.7e-15 * Larger relative error can be observed for z near zero. * Also tested by csin(casin(z)) = z. */ #include #include #include double complex casin(double complex z) { double complex w; static double complex ca, ct, zz, z2; double x, y; x = creal (z); y = cimag (z); if (y == 0.0) { if (fabs(x) > 1.0) { w = M_PI_2 + 0.0 * I; /*mtherr ("casin", DOMAIN);*/ } else { w = asin (x) + 0.0 * I; } return (w); } /* Power series expansion */ /* b = cabs(z); if( b < 0.125 ) { z2.r = (x - y) * (x + y); z2.i = 2.0 * x * y; cn = 1.0; n = 1.0; ca.r = x; ca.i = y; sum.r = x; sum.i = y; do { ct.r = z2.r * ca.r - z2.i * ca.i; ct.i = z2.r * ca.i + z2.i * ca.r; ca.r = ct.r; ca.i = ct.i; cn *= n; n += 1.0; cn /= n; n += 1.0; b = cn/n; ct.r *= b; ct.i *= b; sum.r += ct.r; sum.i += ct.i; b = fabs(ct.r) + fabs(ct.i); } while( b > MACHEP ); w->r = sum.r; w->i = sum.i; return; } */ ca = x + y * I; ct = ca * I; /* sqrt( 1 - z*z) */ /* cmul( &ca, &ca, &zz ) */ /*x * x - y * y */ zz = (x - y) * (x + y) + (2.0 * x * y) * I; zz = 1.0 - creal(zz) - cimag(zz) * I; z2 = csqrt (zz); zz = ct + z2; zz = clog (zz); /* multiply by 1/i = -i */ w = zz * (-1.0 * I); return (w); } #if LDBL_MANT_DIG == DBL_MANT_DIG __strong_alias(casinl, casin); #endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ openlibm-0.5.0/src/s_casinf.c000066400000000000000000000052051266752446200160610ustar00rootroot00000000000000/* $OpenBSD: s_casinf.c,v 1.3 2011/07/20 19:28:33 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* casinf() * * Complex circular arc sine * * * * SYNOPSIS: * * void casinf(); * cmplxf z, w; * * casinf( &z, &w ); * * * * DESCRIPTION: * * Inverse complex sine: * * 2 * w = -i clog( iz + csqrt( 1 - z ) ). * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE -10,+10 30000 1.1e-5 1.5e-6 * Larger relative error can be observed for z near zero. * */ #include #include float complex casinf(float complex z) { float complex w; float x, y; static float complex ca, ct, zz, z2; /* float cn, n; static float a, b, s, t, u, v, y2; static cmplxf sum; */ x = crealf(z); y = cimagf(z); if(y == 0.0f) { if(fabsf(x) > 1.0f) { w = (float)M_PI_2 + 0.0f * I; /*mtherr( "casinf", DOMAIN );*/ } else { w = asinf (x) + 0.0f * I; } return (w); } /* Power series expansion */ /* b = cabsf(z); if(b < 0.125) { z2.r = (x - y) * (x + y); z2.i = 2.0 * x * y; cn = 1.0; n = 1.0; ca.r = x; ca.i = y; sum.r = x; sum.i = y; do { ct.r = z2.r * ca.r - z2.i * ca.i; ct.i = z2.r * ca.i + z2.i * ca.r; ca.r = ct.r; ca.i = ct.i; cn *= n; n += 1.0; cn /= n; n += 1.0; b = cn/n; ct.r *= b; ct.i *= b; sum.r += ct.r; sum.i += ct.i; b = fabsf(ct.r) + fabsf(ct.i); } while(b > MACHEPF); w->r = sum.r; w->i = sum.i; return; } */ ca = x + y * I; ct = ca * I; /* iz */ /* sqrt( 1 - z*z) */ /* cmul( &ca, &ca, &zz ) */ /*x * x - y * y */ zz = (x - y) * (x + y) + (2.0f * x * y) * I; zz = 1.0f - crealf(zz) - cimagf(zz) * I; z2 = csqrtf (zz); zz = ct + z2; zz = clogf (zz); /* multiply by 1/i = -i */ w = zz * (-1.0f * I); return (w); } openlibm-0.5.0/src/s_casinh.c000066400000000000000000000030211266752446200160550ustar00rootroot00000000000000/* $OpenBSD: s_casinh.c,v 1.6 2013/07/03 04:46:36 espie Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* casinh * * Complex inverse hyperbolic sine * * * * SYNOPSIS: * * double complex casinh(); * double complex z, w; * * w = casinh (z); * * * * DESCRIPTION: * * casinh z = -i casin iz . * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE -10,+10 30000 1.8e-14 2.6e-15 * */ #include #include #include double complex casinh(double complex z) { double complex w; w = -1.0 * I * casin (z * I); return (w); } #if LDBL_MANT_DIG == DBL_MANT_DIG __strong_alias(casinhl, casinh); #endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ openlibm-0.5.0/src/s_casinhf.c000066400000000000000000000026241266752446200162330ustar00rootroot00000000000000/* $OpenBSD: s_casinhf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* casinhf * * Complex inverse hyperbolic sine * * * * SYNOPSIS: * * float complex casinhf(); * float complex z, w; * * w = casinhf (z); * * * * DESCRIPTION: * * casinh z = -i casin iz . * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE -10,+10 30000 1.8e-14 2.6e-15 * */ #include #include float complex casinhf(float complex z) { float complex w; w = -1.0f * I * casinf (z * I); return (w); } openlibm-0.5.0/src/s_casinhl.c000066400000000000000000000026621266752446200162430ustar00rootroot00000000000000/* $OpenBSD: s_casinhl.c,v 1.1 2011/07/08 19:25:31 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* casinhl * * Complex inverse hyperbolic sine * * * * SYNOPSIS: * * long double complex casinhf(); * long double complex z, w; * * w = casinhl (z); * * * * DESCRIPTION: * * casinh z = -i casin iz . * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE -10,+10 30000 1.8e-14 2.6e-15 * */ #include #include long double complex casinhl(long double complex z) { long double complex w; w = -1.0L * I * casinl(z * I); return (w); } openlibm-0.5.0/src/s_casinl.c000066400000000000000000000056321266752446200160730ustar00rootroot00000000000000/* $OpenBSD: s_casinl.c,v 1.3 2011/07/20 21:02:51 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* casinl() * * Complex circular arc sine * * * * SYNOPSIS: * * long double complex casinl(); * long double complex z, w; * * w = casinl( z ); * * * * DESCRIPTION: * * Inverse complex sine: * * 2 * w = -i clog( iz + csqrt( 1 - z ) ). * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * DEC -10,+10 10100 2.1e-15 3.4e-16 * IEEE -10,+10 30000 2.2e-14 2.7e-15 * Larger relative error can be observed for z near zero. * Also tested by csin(casin(z)) = z. */ #include #include #include #if LDBL_MANT_DIG == 64 static const long double MACHEPL= 5.42101086242752217003726400434970855712890625E-20L; #elif LDBL_MANT_DIG == 113 static const long double MACHEPL = 9.629649721936179265279889712924636592690508e-35L; #endif static const long double PIO2L = 1.570796326794896619231321691639751442098585L; long double complex casinl(long double complex z) { long double complex w; long double x, y, b; static long double complex ca, ct, zz, z2; x = creall(z); y = cimagl(z); if (y == 0.0L) { if (fabsl(x) > 1.0L) { w = PIO2L + 0.0L * I; /*mtherr( "casinl", DOMAIN );*/ } else { w = asinl(x) + 0.0L * I; } return (w); } /* Power series expansion */ b = cabsl(z); if (b < 0.125L) { long double complex sum; long double n, cn; z2 = (x - y) * (x + y) + (2.0L * x * y) * I; cn = 1.0L; n = 1.0L; ca = x + y * I; sum = x + y * I; do { ct = z2 * ca; ca = ct; cn *= n; n += 1.0L; cn /= n; n += 1.0L; b = cn/n; ct *= b; sum += ct; b = cabsl(ct); } while (b > MACHEPL); w = sum; return w; } ca = x + y * I; ct = ca * I; /* iz */ /* sqrt(1 - z*z) */ /* cmul(&ca, &ca, &zz) */ /* x * x - y * y */ zz = (x - y) * (x + y) + (2.0L * x * y) * I; zz = 1.0L - creall(zz) - cimagl(zz) * I; z2 = csqrtl(zz); zz = ct + z2; zz = clogl(zz); /* multiply by 1/i = -i */ w = zz * (-1.0L * I); return (w); } openlibm-0.5.0/src/s_catan.c000066400000000000000000000055511266752446200157100ustar00rootroot00000000000000/* $OpenBSD: s_catan.c,v 1.6 2013/07/03 04:46:36 espie Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* catan() * * Complex circular arc tangent * * * * SYNOPSIS: * * double complex catan(); * double complex z, w; * * w = catan (z); * * * * DESCRIPTION: * * If * z = x + iy, * * then * 1 ( 2x ) * Re w = - arctan(-----------) + k PI * 2 ( 2 2) * (1 - x - y ) * * ( 2 2) * 1 (x + (y+1) ) * Im w = - log(------------) * 4 ( 2 2) * (x + (y-1) ) * * Where k is an arbitrary integer. * * catan(z) = -i catanh(iz). * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * DEC -10,+10 5900 1.3e-16 7.8e-18 * IEEE -10,+10 30000 2.3e-15 8.5e-17 * The check catan( ctan(z) ) = z, with |x| and |y| < PI/2, * had peak relative error 1.5e-16, rms relative error * 2.9e-17. See also clog(). */ #include #include #include #define MAXNUM 1.0e308 static const double DP1 = 3.14159265160560607910E0; static const double DP2 = 1.98418714791870343106E-9; static const double DP3 = 1.14423774522196636802E-17; static double _redupi(double x) { double t; long i; t = x/M_PI; if(t >= 0.0) t += 0.5; else t -= 0.5; i = t; /* the multiple */ t = i; t = ((x - t * DP1) - t * DP2) - t * DP3; return (t); } double complex catan(double complex z) { double complex w; double a, t, x, x2, y; x = creal (z); y = cimag (z); if ((x == 0.0) && (y > 1.0)) goto ovrf; x2 = x * x; a = 1.0 - x2 - (y * y); if (a == 0.0) goto ovrf; t = 0.5 * atan2 (2.0 * x, a); w = _redupi (t); t = y - 1.0; a = x2 + (t * t); if (a == 0.0) goto ovrf; t = y + 1.0; a = (x2 + (t * t))/a; w = w + (0.25 * log (a)) * I; return (w); ovrf: /*mtherr ("catan", OVERFLOW);*/ w = MAXNUM + MAXNUM * I; return (w); } #if LDBL_MANT_DIG == DBL_MANT_DIG __strong_alias(catanl, catan); #endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ openlibm-0.5.0/src/s_catanf.c000066400000000000000000000050201266752446200160450ustar00rootroot00000000000000/* $OpenBSD: s_catanf.c,v 1.2 2010/07/18 18:42:26 guenther Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* catanf() * * Complex circular arc tangent * * * * SYNOPSIS: * * float complex catanf(); * float complex z, w; * * w = catanf( z ); * * * * DESCRIPTION: * * If * z = x + iy, * * then * 1 ( 2x ) * Re w = - arctan(-----------) + k PI * 2 ( 2 2) * (1 - x - y ) * * ( 2 2) * 1 (x + (y+1) ) * Im w = - log(------------) * 4 ( 2 2) * (x + (y-1) ) * * Where k is an arbitrary integer. * * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE -10,+10 30000 2.3e-6 5.2e-8 * */ #include #include #define MAXNUMF 1.0e38F static const double DP1 = 3.140625; static const double DP2 = 9.67502593994140625E-4; static const double DP3 = 1.509957990978376432E-7; static float _redupif(float xx) { float x, t; long i; x = xx; t = x/(float)M_PI; if(t >= 0.0) t += 0.5; else t -= 0.5; i = t; /* the multiple */ t = i; t = ((x - t * DP1) - t * DP2) - t * DP3; return(t); } float complex catanf(float complex z) { float complex w; float a, t, x, x2, y; x = crealf(z); y = cimagf(z); if((x == 0.0f) && (y > 1.0f)) goto ovrf; x2 = x * x; a = 1.0f - x2 - (y * y); if (a == 0.0f) goto ovrf; t = 0.5f * atan2f(2.0f * x, a); w = _redupif(t); t = y - 1.0f; a = x2 + (t * t); if(a == 0.0f) goto ovrf; t = y + 1.0f; a = (x2 + (t * t))/a; w = w + (0.25f * logf (a)) * I; return (w); ovrf: /*mtherr( "catanf", OVERFLOW );*/ w = MAXNUMF + MAXNUMF * I; return (w); } openlibm-0.5.0/src/s_catanh.c000066400000000000000000000030421266752446200160510ustar00rootroot00000000000000/* $OpenBSD: s_catanh.c,v 1.6 2013/07/03 04:46:36 espie Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* catanh * * Complex inverse hyperbolic tangent * * * * SYNOPSIS: * * double complex catanh(); * double complex z, w; * * w = catanh (z); * * * * DESCRIPTION: * * Inverse tanh, equal to -i catan (iz); * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE -10,+10 30000 2.3e-16 6.2e-17 * */ #include #include #include double complex catanh(double complex z) { double complex w; w = -1.0 * I * catan (z * I); return (w); } #if LDBL_MANT_DIG == DBL_MANT_DIG __strong_alias(catanhl, catanh); #endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ openlibm-0.5.0/src/s_catanhf.c000066400000000000000000000026451266752446200162270ustar00rootroot00000000000000/* $OpenBSD: s_catanhf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* catanhf * * Complex inverse hyperbolic tangent * * * * SYNOPSIS: * * float complex catanhf(); * float complex z, w; * * w = catanhf (z); * * * * DESCRIPTION: * * Inverse tanh, equal to -i catan (iz); * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE -10,+10 30000 2.3e-16 6.2e-17 * */ #include #include float complex catanhf(float complex z) { float complex w; w = -1.0f * I * catanf (z * I); return (w); } openlibm-0.5.0/src/s_catanhl.c000066400000000000000000000027031266752446200162300ustar00rootroot00000000000000/* $OpenBSD: s_catanhl.c,v 1.1 2011/07/08 19:25:31 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* catanhl * * Complex inverse hyperbolic tangent * * * * SYNOPSIS: * * long double complex catanhl(); * long double complex z, w; * * w = catanhl (z); * * * * DESCRIPTION: * * Inverse tanh, equal to -i catan (iz); * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE -10,+10 30000 2.3e-16 6.2e-17 * */ #include #include long double complex catanhl(long double complex z) { long double complex w; w = -1.0L * I * catanl(z * I); return (w); } openlibm-0.5.0/src/s_catanl.c000066400000000000000000000056641266752446200160710ustar00rootroot00000000000000/* $OpenBSD: s_catanl.c,v 1.3 2011/07/20 21:02:51 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* catanl() * * Complex circular arc tangent * * * * SYNOPSIS: * * long double complex catanl(); * long double complex z, w; * * w = catanl( z ); * * * * DESCRIPTION: * * If * z = x + iy, * * then * 1 ( 2x ) * Re w = - arctan(-----------) + k PI * 2 ( 2 2) * (1 - x - y ) * * ( 2 2) * 1 (x + (y+1) ) * Im w = - log(------------) * 4 ( 2 2) * (x + (y-1) ) * * Where k is an arbitrary integer. * * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * DEC -10,+10 5900 1.3e-16 7.8e-18 * IEEE -10,+10 30000 2.3e-15 8.5e-17 * The check catan( ctan(z) ) = z, with |x| and |y| < PI/2, * had peak relative error 1.5e-16, rms relative error * 2.9e-17. See also clog(). */ #include #include #include static const long double PIL = 3.141592653589793238462643383279502884197169L; static const long double DP1 = 3.14159265358979323829596852490908531763125L; static const long double DP2 = 1.6667485837041756656403424829301998703007e-19L; static const long double DP3 = 1.8830410776607851167459095484560349402753e-39L; static long double redupil(long double x) { long double t; long i; t = x / PIL; if (t >= 0.0L) t += 0.5L; else t -= 0.5L; i = t; /* the multiple */ t = i; t = ((x - t * DP1) - t * DP2) - t * DP3; return (t); } long double complex catanl(long double complex z) { long double complex w; long double a, t, x, x2, y; x = creall(z); y = cimagl(z); if ((x == 0.0L) && (y > 1.0L)) goto ovrf; x2 = x * x; a = 1.0L - x2 - (y * y); if (a == 0.0L) goto ovrf; t = atan2l(2.0L * x, a) * 0.5L; w = redupil(t); t = y - 1.0L; a = x2 + (t * t); if (a == 0.0L) goto ovrf; t = y + 1.0L; a = (x2 + (t * t)) / a; w = w + (0.25L * logl(a)) * I; return (w); ovrf: /*mtherr( "catanl", OVERFLOW );*/ w = LDBL_MAX + LDBL_MAX * I; return (w); } openlibm-0.5.0/src/s_cbrt.c000066400000000000000000000101441266752446200155460ustar00rootroot00000000000000/* @(#)s_cbrt.c 5.1 93/09/24 */ /* * ==================================================== * 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. * ==================================================== * * Optimized by Bruce D. Evans. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_cbrt.c,v 1.17 2011/03/12 16:50:39 kargl Exp $"); #include #include "math_private.h" /* cbrt(x) * Return cube root of x */ static const u_int32_t B1 = 715094163, /* B1 = (1023-1023/3-0.03306235651)*2**20 */ B2 = 696219795; /* B2 = (1023-1023/3-54/3-0.03306235651)*2**20 */ /* |1/cbrt(x) - p(x)| < 2**-23.5 (~[-7.93e-8, 7.929e-8]). */ static const double P0 = 1.87595182427177009643, /* 0x3ffe03e6, 0x0f61e692 */ P1 = -1.88497979543377169875, /* 0xbffe28e0, 0x92f02420 */ P2 = 1.621429720105354466140, /* 0x3ff9f160, 0x4a49d6c2 */ P3 = -0.758397934778766047437, /* 0xbfe844cb, 0xbee751d9 */ P4 = 0.145996192886612446982; /* 0x3fc2b000, 0xd4e4edd7 */ DLLEXPORT double cbrt(double x) { int32_t hx; union { double value; u_int64_t bits; } u; double r,s,t=0.0,w; u_int32_t sign; u_int32_t high,low; EXTRACT_WORDS(hx,low,x); sign=hx&0x80000000; /* sign= sign(x) */ hx ^=sign; if(hx>=0x7ff00000) return(x+x); /* cbrt(NaN,INF) is itself */ /* * Rough cbrt to 5 bits: * cbrt(2**e*(1+m) ~= 2**(e/3)*(1+(e%3+m)/3) * where e is integral and >= 0, m is real and in [0, 1), and "/" and * "%" are integer division and modulus with rounding towards minus * infinity. The RHS is always >= the LHS and has a maximum relative * error of about 1 in 16. Adding a bias of -0.03306235651 to the * (e%3+m)/3 term reduces the error to about 1 in 32. With the IEEE * floating point representation, for finite positive normal values, * ordinary integer divison of the value in bits magically gives * almost exactly the RHS of the above provided we first subtract the * exponent bias (1023 for doubles) and later add it back. We do the * subtraction virtually to keep e >= 0 so that ordinary integer * division rounds towards minus infinity; this is also efficient. */ if(hx<0x00100000) { /* zero or subnormal? */ if((hx|low)==0) return(x); /* cbrt(0) is itself */ SET_HIGH_WORD(t,0x43500000); /* set t= 2**54 */ t*=x; GET_HIGH_WORD(high,t); INSERT_WORDS(t,sign|((high&0x7fffffff)/3+B2),0); } else INSERT_WORDS(t,sign|(hx/3+B1),0); /* * New cbrt to 23 bits: * cbrt(x) = t*cbrt(x/t**3) ~= t*P(t**3/x) * where P(r) is a polynomial of degree 4 that approximates 1/cbrt(r) * to within 2**-23.5 when |r - 1| < 1/10. The rough approximation * has produced t such than |t/cbrt(x) - 1| ~< 1/32, and cubing this * gives us bounds for r = t**3/x. * * Try to optimize for parallel evaluation as in k_tanf.c. */ r=(t*t)*(t/x); t=t*((P0+r*(P1+r*P2))+((r*r)*r)*(P3+r*P4)); /* * Round t away from zero to 23 bits (sloppily except for ensuring that * the result is larger in magnitude than cbrt(x) but not much more than * 2 23-bit ulps larger). With rounding towards zero, the error bound * would be ~5/6 instead of ~4/6. With a maximum error of 2 23-bit ulps * in the rounded t, the infinite-precision error in the Newton * approximation barely affects third digit in the final error * 0.667; the error in the rounded t can be up to about 3 23-bit ulps * before the final error is larger than 0.667 ulps. */ u.value=t; u.bits=(u.bits+0x80000000)&0xffffffffc0000000ULL; t=u.value; /* one step Newton iteration to 53 bits with error < 0.667 ulps */ s=t*t; /* t*t is exact */ r=x/s; /* error <= 0.5 ulps; |r| < |t| */ w=t+t; /* t+t is exact */ r=(r-t)/(w+r); /* r-t is exact; w+r ~= 3*t */ t=t+t*r; /* error <= 0.5 + 0.5/3 + epsilon */ return(t); } #if (LDBL_MANT_DIG == 53) __weak_reference(cbrt, cbrtl); #endif openlibm-0.5.0/src/s_cbrtf.c000066400000000000000000000037031266752446200157170ustar00rootroot00000000000000/* s_cbrtf.c -- float version of s_cbrt.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. * Debugged and optimized by Bruce D. Evans. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_cbrtf.c,v 1.18 2008/02/22 02:30:35 das Exp $"); #include #include "math_private.h" /* cbrtf(x) * Return cube root of x */ static const unsigned B1 = 709958130, /* B1 = (127-127.0/3-0.03306235651)*2**23 */ B2 = 642849266; /* B2 = (127-127.0/3-24/3-0.03306235651)*2**23 */ DLLEXPORT float cbrtf(float x) { double r,T; float t; int32_t hx; u_int32_t sign; u_int32_t high; GET_FLOAT_WORD(hx,x); sign=hx&0x80000000; /* sign= sign(x) */ hx ^=sign; if(hx>=0x7f800000) return(x+x); /* cbrt(NaN,INF) is itself */ /* rough cbrt to 5 bits */ if(hx<0x00800000) { /* zero or subnormal? */ if(hx==0) return(x); /* cbrt(+-0) is itself */ SET_FLOAT_WORD(t,0x4b800000); /* set t= 2**24 */ t*=x; GET_FLOAT_WORD(high,t); SET_FLOAT_WORD(t,sign|((high&0x7fffffff)/3+B2)); } else SET_FLOAT_WORD(t,sign|(hx/3+B1)); /* * First step Newton iteration (solving t*t-x/t == 0) to 16 bits. In * double precision so that its terms can be arranged for efficiency * without causing overflow or underflow. */ T=t; r=T*T*T; T=T*((double)x+x+r)/(x+r+r); /* * Second step Newton iteration to 47 bits. In double precision for * efficiency and accuracy. */ r=T*T*T; T=T*((double)x+x+r)/(x+r+r); /* rounding to 24 bits is perfect in round-to-nearest mode */ return(T); } openlibm-0.5.0/src/s_cbrtl.c000066400000000000000000000073131266752446200157260ustar00rootroot00000000000000/*- * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * Copyright (c) 2009-2011, Bruce D. Evans, Steven G. Kargl, David Schultz. * * 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. * ==================================================== * * The argument reduction and testing for exceptional cases was * written by Steven G. Kargl with input from Bruce D. Evans * and David A. Schultz. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_cbrtl.c,v 1.1 2011/03/12 19:37:35 kargl Exp $"); #include #include // VBS //#include #include "fpmath.h" #include "math_private.h" #if defined(__i386__) #include "i387/bsd_ieeefp.h" #endif #define BIAS (LDBL_MAX_EXP - 1) static const unsigned B1 = 709958130; /* B1 = (127-127.0/3-0.03306235651)*2**23 */ DLLEXPORT long double cbrtl(long double x) { union IEEEl2bits u, v; long double r, s, t, w; double dr, dt, dx; float ft, fx; u_int32_t hx; u_int16_t expsign; int k; u.e = x; expsign = u.xbits.expsign; k = expsign & 0x7fff; /* * If x = +-Inf, then cbrt(x) = +-Inf. * If x = NaN, then cbrt(x) = NaN. */ if (k == BIAS + LDBL_MAX_EXP) return (x + x); #ifdef __i386__ fp_prec_t oprec; oprec = fpgetprec(); if (oprec != FP_PE) fpsetprec(FP_PE); #endif if (k == 0) { /* If x = +-0, then cbrt(x) = +-0. */ if ((u.bits.manh | u.bits.manl) == 0) { #ifdef __i386__ if (oprec != FP_PE) fpsetprec(oprec); #endif return (x); } /* Adjust subnormal numbers. */ u.e *= 0x1.0p514; k = u.bits.exp; k -= BIAS + 514; } else k -= BIAS; u.xbits.expsign = BIAS; v.e = 1; x = u.e; switch (k % 3) { case 1: case -2: x = 2*x; k--; break; case 2: case -1: x = 4*x; k -= 2; break; } v.xbits.expsign = (expsign & 0x8000) | (BIAS + k / 3); /* * The following is the guts of s_cbrtf, with the handling of * special values removed and extra care for accuracy not taken, * but with most of the extra accuracy not discarded. */ /* ~5-bit estimate: */ fx = x; GET_FLOAT_WORD(hx, fx); SET_FLOAT_WORD(ft, ((hx & 0x7fffffff) / 3 + B1)); /* ~16-bit estimate: */ dx = x; dt = ft; dr = dt * dt * dt; dt = dt * (dx + dx + dr) / (dx + dr + dr); /* ~47-bit estimate: */ dr = dt * dt * dt; dt = dt * (dx + dx + dr) / (dx + dr + dr); #if LDBL_MANT_DIG == 64 /* * dt is cbrtl(x) to ~47 bits (after x has been reduced to 1 <= x < 8). * Round it away from zero to 32 bits (32 so that t*t is exact, and * away from zero for technical reasons). */ volatile double vd2 = 0x1.0p32; volatile double vd1 = 0x1.0p-31; #define vd ((long double)vd2 + vd1) t = dt + vd - 0x1.0p32; #elif LDBL_MANT_DIG == 113 /* * Round dt away from zero to 47 bits. Since we don't trust the 47, * add 2 47-bit ulps instead of 1 to round up. Rounding is slow and * might be avoidable in this case, since on most machines dt will * have been evaluated in 53-bit precision and the technical reasons * for rounding up might not apply to either case in cbrtl() since * dt is much more accurate than needed. */ t = dt + 0x2.0p-46 + 0x1.0p60L - 0x1.0p60; #else #error "Unsupported long double format" #endif /* * Final step Newton iteration to 64 or 113 bits with * error < 0.667 ulps */ s=t*t; /* t*t is exact */ r=x/s; /* error <= 0.5 ulps; |r| < |t| */ w=t+t; /* t+t is exact */ r=(r-t)/(w+r); /* r-t is exact; w+r ~= 3*t */ t=t+t*r; /* error <= 0.5 + 0.5/3 + epsilon */ t *= v.e; #ifdef __i386__ if (oprec != FP_PE) fpsetprec(oprec); #endif return (t); } openlibm-0.5.0/src/s_ccos.c000066400000000000000000000036601266752446200155500ustar00rootroot00000000000000/* $OpenBSD: s_ccos.c,v 1.6 2013/07/03 04:46:36 espie Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* ccos() * * Complex circular cosine * * * * SYNOPSIS: * * double complex ccos(); * double complex z, w; * * w = ccos (z); * * * * DESCRIPTION: * * If * z = x + iy, * * then * * w = cos x cosh y - i sin x sinh y. * * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * DEC -10,+10 8400 4.5e-17 1.3e-17 * IEEE -10,+10 30000 3.8e-16 1.0e-16 */ #include #include #include /* calculate cosh and sinh */ static void _cchsh(double x, double *c, double *s) { double e, ei; if (fabs(x) <= 0.5) { *c = cosh(x); *s = sinh(x); } else { e = exp(x); ei = 0.5/e; e = 0.5 * e; *s = e - ei; *c = e + ei; } } double complex ccos(double complex z) { double complex w; double ch, sh; _cchsh( cimag(z), &ch, &sh ); w = cos(creal (z)) * ch - (sin (creal (z)) * sh) * I; return (w); } #if LDBL_MANT_DIG == DBL_MANT_DIG __strong_alias(ccosl, ccos); #endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ openlibm-0.5.0/src/s_ccosf.c000066400000000000000000000034031266752446200157110ustar00rootroot00000000000000/* $OpenBSD: s_ccosf.c,v 1.2 2010/07/18 18:42:26 guenther Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* ccosf() * * Complex circular cosine * * * * SYNOPSIS: * * void ccosf(); * cmplxf z, w; * * ccosf( &z, &w ); * * * * DESCRIPTION: * * If * z = x + iy, * * then * * w = cos x cosh y - i sin x sinh y. * * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE -10,+10 30000 1.8e-7 5.5e-8 */ #include #include /* calculate cosh and sinh */ static void _cchshf(float xx, float *c, float *s) { float x, e, ei; x = xx; if(fabsf(x) <= 0.5f) { *c = coshf(x); *s = sinhf(x); } else { e = expf(x); ei = 0.5f/e; e = 0.5f * e; *s = e - ei; *c = e + ei; } } float complex ccosf(float complex z) { float complex w; float ch, sh; _cchshf( cimagf(z), &ch, &sh ); w = cosf( crealf(z) ) * ch + ( -sinf( crealf(z) ) * sh) * I; return (w); } openlibm-0.5.0/src/s_ccosh.c000066400000000000000000000116621266752446200157210ustar00rootroot00000000000000/*- * Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice unmodified, this list of conditions, and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Hyperbolic cosine of a complex argument z = x + i y. * * cosh(z) = cosh(x+iy) * = cosh(x) cos(y) + i sinh(x) sin(y). * * Exceptional values are noted in the comments within the source code. * These values and the return value were taken from n1124.pdf. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_ccosh.c,v 1.2 2011/10/21 06:29:32 das Exp $"); #include #include #include "math_private.h" static const double huge = 0x1p1023; DLLEXPORT double complex ccosh(double complex z) { double x, y, h; int32_t hx, hy, ix, iy, lx, ly; x = creal(z); y = cimag(z); EXTRACT_WORDS(hx, lx, x); EXTRACT_WORDS(hy, ly, y); ix = 0x7fffffff & hx; iy = 0x7fffffff & hy; /* Handle the nearly-non-exceptional cases where x and y are finite. */ if (ix < 0x7ff00000 && iy < 0x7ff00000) { if ((iy | ly) == 0) return (CMPLX(cosh(x), x * y)); if (ix < 0x40360000) /* small x: normal case */ return (CMPLX(cosh(x) * cos(y), sinh(x) * sin(y))); /* |x| >= 22, so cosh(x) ~= exp(|x|) */ if (ix < 0x40862e42) { /* x < 710: exp(|x|) won't overflow */ h = exp(fabs(x)) * 0.5; return (CMPLX(h * cos(y), copysign(h, x) * sin(y))); } else if (ix < 0x4096bbaa) { /* x < 1455: scale to avoid overflow */ z = __ldexp_cexp(CMPLX(fabs(x), y), -1); return (CMPLX(creal(z), cimag(z) * copysign(1, x))); } else { /* x >= 1455: the result always overflows */ h = huge * x; return (CMPLX(h * h * cos(y), h * sin(y))); } } /* * cosh(+-0 +- I Inf) = dNaN + I sign(d(+-0, dNaN))0. * The sign of 0 in the result is unspecified. Choice = normally * the same as dNaN. Raise the invalid floating-point exception. * * cosh(+-0 +- I NaN) = d(NaN) + I sign(d(+-0, NaN))0. * The sign of 0 in the result is unspecified. Choice = normally * the same as d(NaN). */ if ((ix | lx) == 0 && iy >= 0x7ff00000) return (CMPLX(y - y, copysign(0, x * (y - y)))); /* * cosh(+-Inf +- I 0) = +Inf + I (+-)(+-)0. * * cosh(NaN +- I 0) = d(NaN) + I sign(d(NaN, +-0))0. * The sign of 0 in the result is unspecified. */ if ((iy | ly) == 0 && ix >= 0x7ff00000) { if (((hx & 0xfffff) | lx) == 0) return (CMPLX(x * x, copysign(0, x) * y)); return (CMPLX(x * x, copysign(0, (x + x) * y))); } /* * cosh(x +- I Inf) = dNaN + I dNaN. * Raise the invalid floating-point exception for finite nonzero x. * * cosh(x + I NaN) = d(NaN) + I d(NaN). * Optionally raises the invalid floating-point exception for finite * nonzero x. Choice = don't raise (except for signaling NaNs). */ if (ix < 0x7ff00000 && iy >= 0x7ff00000) return (CMPLX(y - y, x * (y - y))); /* * cosh(+-Inf + I NaN) = +Inf + I d(NaN). * * cosh(+-Inf +- I Inf) = +Inf + I dNaN. * The sign of Inf in the result is unspecified. Choice = always +. * Raise the invalid floating-point exception. * * cosh(+-Inf + I y) = +Inf cos(y) +- I Inf sin(y) */ if (ix >= 0x7ff00000 && ((hx & 0xfffff) | lx) == 0) { if (iy >= 0x7ff00000) return (CMPLX(x * x, x * (y - y))); return (CMPLX((x * x) * cos(y), x * sin(y))); } /* * cosh(NaN + I NaN) = d(NaN) + I d(NaN). * * cosh(NaN +- I Inf) = d(NaN) + I d(NaN). * Optionally raises the invalid floating-point exception. * Choice = raise. * * cosh(NaN + I y) = d(NaN) + I d(NaN). * Optionally raises the invalid floating-point exception for finite * nonzero y. Choice = don't raise (except for signaling NaNs). */ return (CMPLX((x * x) * (y - y), (x + x) * (y - y))); } DLLEXPORT double complex ccos(double complex z) { /* ccos(z) = ccosh(I * z) */ return (ccosh(CMPLX(-cimag(z), creal(z)))); } openlibm-0.5.0/src/s_ccoshf.c000066400000000000000000000063271266752446200160710ustar00rootroot00000000000000/*- * Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice unmodified, this list of conditions, and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Hyperbolic cosine of a complex argument. See s_ccosh.c for details. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_ccoshf.c,v 1.2 2011/10/21 06:29:32 das Exp $"); #include #include #include "math_private.h" static const float huge = 0x1p127; DLLEXPORT float complex ccoshf(float complex z) { float x, y, h; int32_t hx, hy, ix, iy; x = crealf(z); y = cimagf(z); GET_FLOAT_WORD(hx, x); GET_FLOAT_WORD(hy, y); ix = 0x7fffffff & hx; iy = 0x7fffffff & hy; if (ix < 0x7f800000 && iy < 0x7f800000) { if (iy == 0) return (CMPLXF(coshf(x), x * y)); if (ix < 0x41100000) /* small x: normal case */ return (CMPLXF(coshf(x) * cosf(y), sinhf(x) * sinf(y))); /* |x| >= 9, so cosh(x) ~= exp(|x|) */ if (ix < 0x42b17218) { /* x < 88.7: expf(|x|) won't overflow */ h = expf(fabsf(x)) * 0.5f; return (CMPLXF(h * cosf(y), copysignf(h, x) * sinf(y))); } else if (ix < 0x4340b1e7) { /* x < 192.7: scale to avoid overflow */ z = __ldexp_cexpf(CMPLXF(fabsf(x), y), -1); return (CMPLXF(crealf(z), cimagf(z) * copysignf(1, x))); } else { /* x >= 192.7: the result always overflows */ h = huge * x; return (CMPLXF(h * h * cosf(y), h * sinf(y))); } } if (ix == 0 && iy >= 0x7f800000) return (CMPLXF(y - y, copysignf(0, x * (y - y)))); if (iy == 0 && ix >= 0x7f800000) { if ((hx & 0x7fffff) == 0) return (CMPLXF(x * x, copysignf(0, x) * y)); return (CMPLXF(x * x, copysignf(0, (x + x) * y))); } if (ix < 0x7f800000 && iy >= 0x7f800000) return (CMPLXF(y - y, x * (y - y))); if (ix >= 0x7f800000 && (hx & 0x7fffff) == 0) { if (iy >= 0x7f800000) return (CMPLXF(x * x, x * (y - y))); return (CMPLXF((x * x) * cosf(y), x * sinf(y))); } return (CMPLXF((x * x) * (y - y), (x + x) * (y - y))); } DLLEXPORT float complex ccosf(float complex z) { return (ccoshf(CMPLXF(-cimagf(z), crealf(z)))); } openlibm-0.5.0/src/s_ccoshl.c000066400000000000000000000030011266752446200160610ustar00rootroot00000000000000/* $OpenBSD: s_ccoshl.c,v 1.2 2011/07/20 19:28:33 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* ccoshl * * Complex hyperbolic cosine * * * * SYNOPSIS: * * long double complex ccoshl(); * long double complex z, w; * * w = ccoshl (z); * * * * DESCRIPTION: * * ccosh(z) = cosh x cos y + i sinh x sin y . * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE -10,+10 30000 2.9e-16 8.1e-17 * */ #include #include long double complex ccoshl(long double complex z) { long double complex w; long double x, y; x = creall(z); y = cimagl(z); w = coshl(x) * cosl(y) + (sinhl(x) * sinl(y)) * I; return (w); } openlibm-0.5.0/src/s_ccosl.c000066400000000000000000000035251266752446200157240ustar00rootroot00000000000000/* $OpenBSD: s_ccosl.c,v 1.2 2011/07/20 19:28:33 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* ccosl() * * Complex circular cosine * * * * SYNOPSIS: * * long double complex ccosl(); * long double complex z, w; * * w = ccosl( z ); * * * * DESCRIPTION: * * If * z = x + iy, * * then * * w = cos x cosh y - i sin x sinh y. * * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * DEC -10,+10 8400 4.5e-17 1.3e-17 * IEEE -10,+10 30000 3.8e-16 1.0e-16 */ #include #include static void cchshl(long double x, long double *c, long double *s) { long double e, ei; if(fabsl(x) <= 0.5L) { *c = coshl(x); *s = sinhl(x); } else { e = expl(x); ei = 0.5L/e; e = 0.5L * e; *s = e - ei; *c = e + ei; } } long double complex ccosl(long double complex z) { long double complex w; long double ch, sh; cchshl(cimagl(z), &ch, &sh); w = cosl(creall(z)) * ch + (-sinl(creall(z)) * sh) * I; return (w); } openlibm-0.5.0/src/s_ceil.c000066400000000000000000000034771266752446200155430ustar00rootroot00000000000000/* @(#)s_ceil.c 5.1 93/09/24 */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_ceil.c,v 1.11 2008/02/15 07:01:40 bde Exp $"); /* * ceil(x) * Return x rounded toward -inf to integral value * Method: * Bit twiddling. * Exception: * Inexact flag raised if x not equal to ceil(x). */ #include #include #include "math_private.h" static const double huge = 1.0e300; DLLEXPORT double ceil(double x) { int32_t i0,i1,j0; u_int32_t i,j; EXTRACT_WORDS(i0,i1,x); j0 = ((i0>>20)&0x7ff)-0x3ff; if(j0<20) { if(j0<0) { /* raise inexact if x != 0 */ if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */ if(i0<0) {i0=0x80000000;i1=0;} else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;} } } else { i = (0x000fffff)>>j0; if(((i0&i)|i1)==0) return x; /* x is integral */ if(huge+x>0.0) { /* raise inexact flag */ if(i0>0) i0 += (0x00100000)>>j0; i0 &= (~i); i1=0; } } } else if (j0>51) { if(j0==0x400) return x+x; /* inf or NaN */ else return x; /* x is integral */ } else { i = ((u_int32_t)(0xffffffff))>>(j0-20); if((i1&i)==0) return x; /* x is integral */ if(huge+x>0.0) { /* raise inexact flag */ if(i0>0) { if(j0==20) i0+=1; else { j = i1 + (1<<(52-j0)); if(j #include "math_private.h" static const float huge = 1.0e30; DLLEXPORT float ceilf(float x) { int32_t i0,j0; u_int32_t i; GET_FLOAT_WORD(i0,x); j0 = ((i0>>23)&0xff)-0x7f; if(j0<23) { if(j0<0) { /* raise inexact if x != 0 */ if(huge+x>(float)0.0) {/* return 0*sign(x) if |x|<1 */ if(i0<0) {i0=0x80000000;} else if(i0!=0) { i0=0x3f800000;} } } else { i = (0x007fffff)>>j0; if((i0&i)==0) return x; /* x is integral */ if(huge+x>(float)0.0) { /* raise inexact flag */ if(i0>0) i0 += (0x00800000)>>j0; i0 &= (~i); } } } else { if(j0==0x80) return x+x; /* inf or NaN */ else return x; /* x is integral */ } SET_FLOAT_WORD(x,i0); return x; } openlibm-0.5.0/src/s_ceill.c000066400000000000000000000047721266752446200157160ustar00rootroot00000000000000/* * ==================================================== * 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. * ==================================================== * * From: @(#)s_ceil.c 5.1 93/09/24 */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_ceill.c,v 1.9 2008/02/14 15:10:33 bde Exp $"); /* * ceill(x) * Return x rounded toward -inf to integral value * Method: * Bit twiddling. * Exception: * Inexact flag raised if x not equal to ceill(x). */ #include #include #include #include "fpmath.h" #include "math_private.h" #ifdef LDBL_IMPLICIT_NBIT #define MANH_SIZE (LDBL_MANH_SIZE + 1) #define INC_MANH(u, c) do { \ u_int64_t o = u.bits.manh; \ u.bits.manh += (c); \ if (u.bits.manh < o) \ u.bits.exp++; \ } while (0) #else #define MANH_SIZE LDBL_MANH_SIZE #define INC_MANH(u, c) do { \ u_int64_t o = u.bits.manh; \ u.bits.manh += (c); \ if (u.bits.manh < o) { \ u.bits.exp++; \ u.bits.manh |= 1llu << (LDBL_MANH_SIZE - 1); \ } \ } while (0) #endif static const long double huge = 1.0e300; DLLEXPORT long double ceill(long double x) { union IEEEl2bits u = { .e = x }; int e = u.bits.exp - LDBL_MAX_EXP + 1; if (e < MANH_SIZE - 1) { if (e < 0) { /* raise inexact if x != 0 */ if (huge + x > 0.0) if (u.bits.exp > 0 || (u.bits.manh | u.bits.manl) != 0) u.e = u.bits.sign ? -0.0 : 1.0; } else { u_int64_t m = ((1llu << MANH_SIZE) - 1) >> (e + 1); if (((u.bits.manh & m) | u.bits.manl) == 0) return (x); /* x is integral */ if (!u.bits.sign) { #ifdef LDBL_IMPLICIT_NBIT if (e == 0) u.bits.exp++; else #endif INC_MANH(u, 1llu << (MANH_SIZE - e - 1)); } if (huge + x > 0.0) { /* raise inexact flag */ u.bits.manh &= ~m; u.bits.manl = 0; } } } else if (e < LDBL_MANT_DIG - 1) { u_int64_t m = (u_int64_t)-1 >> (64 - LDBL_MANT_DIG + e + 1); if ((u.bits.manl & m) == 0) return (x); /* x is integral */ if (!u.bits.sign) { if (e == MANH_SIZE - 1) INC_MANH(u, 1); else { u_int64_t o = u.bits.manl; u.bits.manl += 1llu << (LDBL_MANT_DIG - e - 1); if (u.bits.manl < o) /* got a carry */ INC_MANH(u, 1); } } if (huge + x > 0.0) /* raise inexact flag */ u.bits.manl &= ~m; } return (u.e); } openlibm-0.5.0/src/s_cexp.c000066400000000000000000000056671266752446200155710ustar00rootroot00000000000000/*- * Copyright (c) 2011 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_cexp.c,v 1.3 2011/10/21 06:27:56 das Exp $"); #include #include #include "math_private.h" static const u_int32_t exp_ovfl = 0x40862e42, /* high bits of MAX_EXP * ln2 ~= 710 */ cexp_ovfl = 0x4096b8e4; /* (MAX_EXP - MIN_DENORM_EXP) * ln2 */ DLLEXPORT double complex cexp(double complex z) { double x, y, exp_x; u_int32_t hx, hy, lx, ly; x = creal(z); y = cimag(z); EXTRACT_WORDS(hy, ly, y); hy &= 0x7fffffff; /* cexp(x + I 0) = exp(x) + I 0 */ if ((hy | ly) == 0) return (CMPLX(exp(x), y)); EXTRACT_WORDS(hx, lx, x); /* cexp(0 + I y) = cos(y) + I sin(y) */ if (((hx & 0x7fffffff) | lx) == 0) return (CMPLX(cos(y), sin(y))); if (hy >= 0x7ff00000) { if (lx != 0 || (hx & 0x7fffffff) != 0x7ff00000) { /* cexp(finite|NaN +- I Inf|NaN) = NaN + I NaN */ return (CMPLX(y - y, y - y)); } else if (hx & 0x80000000) { /* cexp(-Inf +- I Inf|NaN) = 0 + I 0 */ return (CMPLX(0.0, 0.0)); } else { /* cexp(+Inf +- I Inf|NaN) = Inf + I NaN */ return (CMPLX(x, y - y)); } } if (hx >= exp_ovfl && hx <= cexp_ovfl) { /* * x is between 709.7 and 1454.3, so we must scale to avoid * overflow in exp(x). */ return (__ldexp_cexp(z, 0)); } else { /* * Cases covered here: * - x < exp_ovfl and exp(x) won't overflow (common case) * - x > cexp_ovfl, so exp(x) * s overflows for all s > 0 * - x = +-Inf (generated by exp()) * - x = NaN (spurious inexact exception from y) */ exp_x = exp(x); return (CMPLX(exp_x * cos(y), exp_x * sin(y))); } } openlibm-0.5.0/src/s_cexpf.c000066400000000000000000000056251266752446200157310ustar00rootroot00000000000000/*- * Copyright (c) 2011 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_cexpf.c,v 1.3 2011/10/21 06:27:56 das Exp $"); #include #include #include "math_private.h" static const u_int32_t exp_ovfl = 0x42b17218, /* MAX_EXP * ln2 ~= 88.722839355 */ cexp_ovfl = 0x43400074; /* (MAX_EXP - MIN_DENORM_EXP) * ln2 */ DLLEXPORT float complex cexpf(float complex z) { float x, y, exp_x; u_int32_t hx, hy; x = crealf(z); y = cimagf(z); GET_FLOAT_WORD(hy, y); hy &= 0x7fffffff; /* cexp(x + I 0) = exp(x) + I 0 */ if (hy == 0) return (CMPLXF(expf(x), y)); GET_FLOAT_WORD(hx, x); /* cexp(0 + I y) = cos(y) + I sin(y) */ if ((hx & 0x7fffffff) == 0) return (CMPLXF(cosf(y), sinf(y))); if (hy >= 0x7f800000) { if ((hx & 0x7fffffff) != 0x7f800000) { /* cexp(finite|NaN +- I Inf|NaN) = NaN + I NaN */ return (CMPLXF(y - y, y - y)); } else if (hx & 0x80000000) { /* cexp(-Inf +- I Inf|NaN) = 0 + I 0 */ return (CMPLXF(0.0, 0.0)); } else { /* cexp(+Inf +- I Inf|NaN) = Inf + I NaN */ return (CMPLXF(x, y - y)); } } if (hx >= exp_ovfl && hx <= cexp_ovfl) { /* * x is between 88.7 and 192, so we must scale to avoid * overflow in expf(x). */ return (__ldexp_cexpf(z, 0)); } else { /* * Cases covered here: * - x < exp_ovfl and exp(x) won't overflow (common case) * - x > cexp_ovfl, so exp(x) * s overflows for all s > 0 * - x = +-Inf (generated by exp()) * - x = NaN (spurious inexact exception from y) */ exp_x = expf(x); return (CMPLXF(exp_x * cosf(y), exp_x * sinf(y))); } } openlibm-0.5.0/src/s_cexpl.c000066400000000000000000000032671266752446200157370ustar00rootroot00000000000000/* $OpenBSD: s_cexpl.c,v 1.2 2011/07/20 19:28:33 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* cexpl() * * Complex exponential function * * * * SYNOPSIS: * * long double complex cexpl(); * long double complex z, w; * * w = cexpl( z ); * * * * DESCRIPTION: * * Returns the exponential of the complex argument z * into the complex result w. * * If * z = x + iy, * r = exp(x), * * then * * w = r cos y + i r sin y. * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * DEC -10,+10 8700 3.7e-17 1.1e-17 * IEEE -10,+10 30000 3.0e-16 8.7e-17 * */ #include #include long double complex cexpl(long double complex z) { long double complex w; long double r; r = expl(creall(z)); w = r * cosl(cimagl(z)) + (r * sinl(cimagl(z))) * I; return (w); } openlibm-0.5.0/src/s_cimag.c000066400000000000000000000030241266752446200156730ustar00rootroot00000000000000/*- * Copyright (c) 2004 Stefan Farfeleder * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/lib/msun/src/s_cimag.c,v 1.3 2009/03/14 18:24:15 das Exp $ */ #include #include "math_private.h" DLLEXPORT double cimag(double complex z) { return (__imag__ z); } openlibm-0.5.0/src/s_cimagf.c000066400000000000000000000030241266752446200160410ustar00rootroot00000000000000/*- * Copyright (c) 2004 Stefan Farfeleder * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/lib/msun/src/s_cimagf.c,v 1.3 2009/03/14 18:24:15 das Exp $ */ #include #include "math_private.h" DLLEXPORT float cimagf(float complex z) { return (__imag__ z); } openlibm-0.5.0/src/s_cimagl.c000066400000000000000000000030401266752446200160450ustar00rootroot00000000000000/*- * Copyright (c) 2004 Stefan Farfeleder * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/lib/msun/src/s_cimagl.c,v 1.3 2009/03/14 18:24:15 das Exp $ */ #include #include "math_private.h" DLLEXPORT long double cimagl(long double complex z) { return (__imag__ z); } openlibm-0.5.0/src/s_clog.c000066400000000000000000000040041266752446200155360ustar00rootroot00000000000000/* $OpenBSD: s_clog.c,v 1.6 2013/07/03 04:46:36 espie Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* clog.c * * Complex natural logarithm * * * * SYNOPSIS: * * double complex clog(); * double complex z, w; * * w = clog (z); * * * * DESCRIPTION: * * Returns complex logarithm to the base e (2.718...) of * the complex argument x. * * If z = x + iy, r = sqrt( x**2 + y**2 ), * then * w = log(r) + i arctan(y/x). * * The arctangent ranges from -PI to +PI. * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * DEC -10,+10 7000 8.5e-17 1.9e-17 * IEEE -10,+10 30000 5.0e-15 1.1e-16 * * Larger relative error can be observed for z near 1 +i0. * In IEEE arithmetic the peak absolute error is 5.2e-16, rms * absolute error 1.0e-16. */ #include #include #include double complex clog(double complex z) { double complex w; double p, rr; /*rr = sqrt( z->r * z->r + z->i * z->i );*/ rr = cabs(z); p = log(rr); rr = atan2 (cimag (z), creal (z)); w = p + rr * I; return (w); } #if LDBL_MANT_DIG == DBL_MANT_DIG __strong_alias(clogl, clog); #endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ openlibm-0.5.0/src/s_clogf.c000066400000000000000000000034071266752446200157120ustar00rootroot00000000000000/* $OpenBSD: s_clogf.c,v 1.2 2010/07/18 18:42:26 guenther Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* clogf.c * * Complex natural logarithm * * * * SYNOPSIS: * * void clogf(); * cmplxf z, w; * * clogf( &z, &w ); * * * * DESCRIPTION: * * Returns complex logarithm to the base e (2.718...) of * the complex argument x. * * If z = x + iy, r = sqrt( x**2 + y**2 ), * then * w = log(r) + i arctan(y/x). * * The arctangent ranges from -PI to +PI. * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE -10,+10 30000 1.9e-6 6.2e-8 * * Larger relative error can be observed for z near 1 +i0. * In IEEE arithmetic the peak absolute error is 3.1e-7. * */ #include #include float complex clogf(float complex z) { float complex w; float p, rr, x, y; x = crealf(z); y = cimagf(z); rr = atan2f(y, x); p = cabsf(z); p = logf(p); w = p + rr * I; return (w); } openlibm-0.5.0/src/s_clogl.c000066400000000000000000000036531266752446200157230ustar00rootroot00000000000000/* $OpenBSD: s_clogl.c,v 1.2 2011/07/20 19:28:33 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* clogl.c * * Complex natural logarithm * * * * SYNOPSIS: * * long double complex clogl(); * long double complex z, w; * * w = clogl( z ); * * * * DESCRIPTION: * * Returns complex logarithm to the base e (2.718...) of * the complex argument x. * * If z = x + iy, r = sqrt( x**2 + y**2 ), * then * w = log(r) + i arctan(y/x). * * The arctangent ranges from -PI to +PI. * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * DEC -10,+10 7000 8.5e-17 1.9e-17 * IEEE -10,+10 30000 5.0e-15 1.1e-16 * * Larger relative error can be observed for z near 1 +i0. * In IEEE arithmetic the peak absolute error is 5.2e-16, rms * absolute error 1.0e-16. */ #include #include long double complex clogl(long double complex z) { long double complex w; long double p, rr; /*rr = sqrt(z->r * z->r + z->i * z->i);*/ p = cabsl(z); p = logl(p); rr = atan2l(cimagl(z), creall(z)); w = p + rr * I; return (w); } openlibm-0.5.0/src/s_conj.c000066400000000000000000000030531266752446200155460ustar00rootroot00000000000000/*- * Copyright (c) 2004 Stefan Farfeleder * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/lib/msun/src/s_conj.c,v 1.2 2008/08/07 14:39:56 das Exp $ */ #include #include "math_private.h" DLLEXPORT double complex conj(double complex z) { return (CMPLX(creal(z), -cimag(z))); } openlibm-0.5.0/src/s_conjf.c000066400000000000000000000030561266752446200157170ustar00rootroot00000000000000/*- * Copyright (c) 2004 Stefan Farfeleder * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/lib/msun/src/s_conjf.c,v 1.2 2008/08/07 14:39:56 das Exp $ */ #include #include "math_private.h" DLLEXPORT float complex conjf(float complex z) { return (CMPLXF(crealf(z), -cimagf(z))); } openlibm-0.5.0/src/s_conjl.c000066400000000000000000000030721266752446200157230ustar00rootroot00000000000000/*- * Copyright (c) 2004 Stefan Farfeleder * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/lib/msun/src/s_conjl.c,v 1.2 2008/08/07 14:39:56 das Exp $ */ #include #include "math_private.h" DLLEXPORT long double complex conjl(long double complex z) { return (CMPLXL(creall(z), -cimagl(z))); } openlibm-0.5.0/src/s_copysign.c000066400000000000000000000016041266752446200164500ustar00rootroot00000000000000/* @(#)s_copysign.c 5.1 93/09/24 */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_copysign.c,v 1.10 2008/02/22 02:30:35 das Exp $"); /* * copysign(double x, double y) * copysign(x,y) returns a value with the magnitude of x and * with the sign bit of y. */ #include #include "math_private.h" DLLEXPORT double copysign(double x, double y) { u_int32_t hx,hy; GET_HIGH_WORD(hx,x); GET_HIGH_WORD(hy,y); SET_HIGH_WORD(x,(hx&0x7fffffff)|(hy&0x80000000)); return x; } openlibm-0.5.0/src/s_copysignf.c000066400000000000000000000017461266752446200166250ustar00rootroot00000000000000/* s_copysignf.c -- float version of s_copysign.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_copysignf.c,v 1.10 2008/02/22 02:30:35 das Exp $"); /* * copysignf(float x, float y) * copysignf(x,y) returns a value with the magnitude of x and * with the sign bit of y. */ #include #include "math_private.h" DLLEXPORT float copysignf(float x, float y) { u_int32_t ix,iy; GET_FLOAT_WORD(ix,x); GET_FLOAT_WORD(iy,y); SET_FLOAT_WORD(x,(ix&0x7fffffff)|(iy&0x80000000)); return x; } openlibm-0.5.0/src/s_copysignl.c000066400000000000000000000032071266752446200166250ustar00rootroot00000000000000/*- * Copyright (c) 2004 Stefan Farfeleder * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/lib/msun/src/s_copysignl.c,v 1.2 2007/01/07 07:54:21 das Exp $ */ #include #include "fpmath.h" #include "math_private.h" DLLEXPORT long double copysignl(long double x, long double y) { union IEEEl2bits ux, uy; ux.e = x; uy.e = y; ux.bits.sign = uy.bits.sign; return (ux.e); } openlibm-0.5.0/src/s_cos.c000066400000000000000000000044371266752446200154100ustar00rootroot00000000000000/* @(#)s_cos.c 5.1 93/09/24 */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_cos.c,v 1.13 2011/02/10 07:37:50 das Exp $"); /* cos(x) * Return cosine function of x. * * kernel function: * __kernel_sin ... sine function on [-pi/4,pi/4] * __kernel_cos ... cosine function on [-pi/4,pi/4] * __ieee754_rem_pio2 ... argument reduction routine * * Method. * Let S,C and T denote the sin, cos and tan respectively on * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 * in [-pi/4 , +pi/4], and let n = k mod 4. * We have * * n sin(x) cos(x) tan(x) * ---------------------------------------------------------- * 0 S C T * 1 C -S -1/T * 2 -S -C T * 3 -C S -1/T * ---------------------------------------------------------- * * Special cases: * Let trig be any of sin, cos, or tan. * trig(+-INF) is NaN, with signals; * trig(NaN) is that NaN; * * Accuracy: * TRIG(x) returns trig(x) nearly rounded */ #include #include //#define INLINE_REM_PIO2 #include "math_private.h" //#include "e_rem_pio2.c" DLLEXPORT double cos(double x) { double y[2],z=0.0; int32_t n, ix; /* High word of x. */ GET_HIGH_WORD(ix,x); /* |x| ~< pi/4 */ ix &= 0x7fffffff; if(ix <= 0x3fe921fb) { if(ix<0x3e46a09e) /* if x < 2**-27 * sqrt(2) */ if(((int)x)==0) return 1.0; /* generate inexact */ return __kernel_cos(x,z); } /* cos(Inf or NaN) is NaN */ else if (ix>=0x7ff00000) return x-x; /* argument reduction needed */ else { n = __ieee754_rem_pio2(x,y); switch(n&3) { case 0: return __kernel_cos(y[0],y[1]); case 1: return -__kernel_sin(y[0],y[1],1); case 2: return -__kernel_cos(y[0],y[1]); default: return __kernel_sin(y[0],y[1],1); } } } #if (LDBL_MANT_DIG == 53) __weak_reference(cos, cosl); #endif openlibm-0.5.0/src/s_cosf.c000066400000000000000000000044511266752446200155520ustar00rootroot00000000000000/* s_cosf.c -- float version of s_cos.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. * Optimized by Bruce D. Evans. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_cosf.c,v 1.18 2008/02/25 22:19:17 bde Exp $"); #include #include //#define INLINE_KERNEL_COSDF //#define INLINE_KERNEL_SINDF //#define INLINE_REM_PIO2F #include "math_private.h" //#include "e_rem_pio2f.c" //#include "k_cosf.c" //#include "k_sinf.c" /* Small multiples of pi/2 rounded to double precision. */ static const double c1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */ c2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */ c3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */ c4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */ DLLEXPORT float cosf(float x) { double y; int32_t n, hx, ix; GET_FLOAT_WORD(hx,x); ix = hx & 0x7fffffff; if(ix <= 0x3f490fda) { /* |x| ~<= pi/4 */ if(ix<0x39800000) /* |x| < 2**-12 */ if(((int)x)==0) return 1.0; /* 1 with inexact if x != 0 */ return __kernel_cosdf(x); } if(ix<=0x407b53d1) { /* |x| ~<= 5*pi/4 */ if(ix<=0x4016cbe3) { /* |x| ~> 3*pi/4 */ if(hx>0) return __kernel_sindf(c1pio2 - x); else return __kernel_sindf(x + c1pio2); } else return -__kernel_cosdf(x + (hx > 0 ? -c2pio2 : c2pio2)); } if(ix<=0x40e231d5) { /* |x| ~<= 9*pi/4 */ if(ix<=0x40afeddf) { /* |x| ~> 7*pi/4 */ if(hx>0) return __kernel_sindf(x - c3pio2); else return __kernel_sindf(-c3pio2 - x); } else return __kernel_cosdf(x + (hx > 0 ? -c4pio2 : c4pio2)); } /* cos(Inf or NaN) is NaN */ else if (ix>=0x7f800000) return x-x; /* general argument reduction needed */ else { n = __ieee754_rem_pio2f(x,&y); switch(n&3) { case 0: return __kernel_cosdf(y); case 1: return __kernel_sindf(-y); case 2: return -__kernel_cosdf(y); default: return __kernel_sindf(y); } } } openlibm-0.5.0/src/s_cosl.c000066400000000000000000000050451266752446200155600ustar00rootroot00000000000000/*- * Copyright (c) 2007 Steven G. Kargl * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice unmodified, this list of conditions, and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_cosl.c,v 1.3 2011/05/30 19:41:28 kargl Exp $"); /* * Limited testing on pseudorandom numbers drawn within [-2e8:4e8] shows * an accuracy of <= 0.7412 ULP. */ #include #include #include "math_private.h" #if LDBL_MANT_DIG == 64 #include "../ld80/e_rem_pio2l.h" #elif LDBL_MANT_DIG == 113 #include "../ld128/e_rem_pio2l.h" #else #error "Unsupported long double format" #endif DLLEXPORT long double cosl(long double x) { union IEEEl2bits z; int e0; long double y[2]; long double hi, lo; z.e = x; z.bits.sign = 0; /* If x = +-0 or x is a subnormal number, then cos(x) = 1 */ if (z.bits.exp == 0) return (1.0); /* If x = NaN or Inf, then cos(x) = NaN. */ if (z.bits.exp == 32767) return ((x - x) / (x - x)); /* Optimize the case where x is already within range. */ if (z.e < M_PI_4) return (__kernel_cosl(z.e, 0)); e0 = __ieee754_rem_pio2l(x, y); hi = y[0]; lo = y[1]; switch (e0 & 3) { case 0: hi = __kernel_cosl(hi, lo); break; case 1: hi = - __kernel_sinl(hi, lo, 1); break; case 2: hi = - __kernel_cosl(hi, lo); break; case 3: hi = __kernel_sinl(hi, lo, 1); break; } return (hi); } openlibm-0.5.0/src/s_cpow.c000066400000000000000000000037101266752446200155650ustar00rootroot00000000000000/* $OpenBSD: s_cpow.c,v 1.6 2013/07/03 04:46:36 espie Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* cpow * * Complex power function * * * * SYNOPSIS: * * double complex cpow(); * double complex a, z, w; * * w = cpow (a, z); * * * * DESCRIPTION: * * Raises complex A to the complex Zth power. * Definition is per AMS55 # 4.2.8, * analytically equivalent to cpow(a,z) = cexp(z clog(a)). * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE -10,+10 30000 9.4e-15 1.5e-15 * */ #include #include #include #include "math_private.h" DLLEXPORT double complex cpow(double complex a, double complex z) { double complex w; double x, y, r, theta, absa, arga; x = creal (z); y = cimag (z); absa = cabs (a); if (absa == 0.0) { return (0.0 + 0.0 * I); } arga = carg (a); r = pow (absa, x); theta = x * arga; if (y != 0.0) { r = r * exp (-y * arga); theta = theta + y * log (absa); } w = r * cos (theta) + (r * sin (theta)) * I; return (w); } #if LDBL_MANT_DIG == DBL_MANT_DIG __strong_alias(cpowl, cpow); #endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ openlibm-0.5.0/src/s_cpowf.c000066400000000000000000000035261266752446200157400ustar00rootroot00000000000000/* $OpenBSD: s_cpowf.c,v 1.2 2010/07/18 18:42:26 guenther Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* cpowf * * Complex power function * * * * SYNOPSIS: * * float complex cpowf(); * float complex a, z, w; * * w = cpowf (a, z); * * * * DESCRIPTION: * * Raises complex A to the complex Zth power. * Definition is per AMS55 # 4.2.8, * analytically equivalent to cpow(a,z) = cexp(z clog(a)). * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE -10,+10 30000 9.4e-15 1.5e-15 * */ #include #include #include "math_private.h" DLLEXPORT float complex cpowf(float complex a, float complex z) { float complex w; float x, y, r, theta, absa, arga; x = crealf(z); y = cimagf(z); absa = cabsf (a); if (absa == 0.0f) { return (0.0f + 0.0f * I); } arga = cargf (a); r = powf (absa, x); theta = x * arga; if (y != 0.0f) { r = r * expf (-y * arga); theta = theta + y * logf (absa); } w = r * cosf (theta) + (r * sinf (theta)) * I; return (w); } openlibm-0.5.0/src/s_cpowl.c000066400000000000000000000035721266752446200157470ustar00rootroot00000000000000/* $OpenBSD: s_cpowl.c,v 1.2 2011/07/20 19:28:33 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* cpowl * * Complex power function * * * * SYNOPSIS: * * long double complex cpowl(); * long double complex a, z, w; * * w = cpowl (a, z); * * * * DESCRIPTION: * * Raises complex A to the complex Zth power. * Definition is per AMS55 # 4.2.8, * analytically equivalent to cpow(a,z) = cexp(z clog(a)). * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE -10,+10 30000 9.4e-15 1.5e-15 * */ #include #include #include "math_private.h" DLLEXPORT long double complex cpowl(long double complex a, long double complex z) { long double complex w; long double x, y, r, theta, absa, arga; x = creall(z); y = cimagl(z); absa = cabsl(a); if (absa == 0.0L) { return (0.0L + 0.0L * I); } arga = cargl(a); r = powl(absa, x); theta = x * arga; if (y != 0.0L) { r = r * expl(-y * arga); theta = theta + y * logl(absa); } w = r * cosl(theta) + (r * sinl(theta)) * I; return (w); } openlibm-0.5.0/src/s_cproj.c000066400000000000000000000034211266752446200157310ustar00rootroot00000000000000/*- * Copyright (c) 2008 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_cproj.c,v 1.1 2008/08/07 15:07:48 das Exp $"); #include #include #include "math_private.h" DLLEXPORT double complex cproj(double complex z) { if (!isinf(creal(z)) && !isinf(cimag(z))) return (z); else return (CMPLX(INFINITY, copysign(0.0, cimag(z)))); } #if LDBL_MANT_DIG == 53 __weak_reference(cproj, cprojl); #endif openlibm-0.5.0/src/s_cprojf.c000066400000000000000000000033251266752446200161020ustar00rootroot00000000000000/*- * Copyright (c) 2008 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_cprojf.c,v 1.1 2008/08/07 15:07:48 das Exp $"); #include #include #include "math_private.h" DLLEXPORT float complex cprojf(float complex z) { if (!isinf(crealf(z)) && !isinf(cimagf(z))) return (z); else return (CMPLXF(INFINITY, copysignf(0.0, cimagf(z)))); } openlibm-0.5.0/src/s_cprojl.c000066400000000000000000000033411266752446200161060ustar00rootroot00000000000000/*- * Copyright (c) 2008 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_cprojl.c,v 1.1 2008/08/07 15:07:48 das Exp $"); #include #include #include "math_private.h" DLLEXPORT long double complex cprojl(long double complex z) { if (!isinf(creall(z)) && !isinf(cimagl(z))) return (z); else return (CMPLXL(INFINITY, copysignl(0.0, cimagl(z)))); } openlibm-0.5.0/src/s_creal.c000066400000000000000000000030151266752446200157010ustar00rootroot00000000000000/*- * Copyright (c) 2004 Stefan Farfeleder * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/lib/msun/src/s_creal.c,v 1.1 2004/05/30 09:21:56 stefanf Exp $ */ #include #include "math_private.h" DLLEXPORT double creal(double complex z) { return z; } openlibm-0.5.0/src/s_crealf.c000066400000000000000000000030151266752446200160470ustar00rootroot00000000000000/*- * Copyright (c) 2004 Stefan Farfeleder * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/lib/msun/src/s_crealf.c,v 1.1 2004/05/30 09:21:56 stefanf Exp $ */ #include #include "math_private.h" DLLEXPORT float crealf(float complex z) { return z; } openlibm-0.5.0/src/s_creall.c000066400000000000000000000030311266752446200160530ustar00rootroot00000000000000/*- * Copyright (c) 2004 Stefan Farfeleder * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/lib/msun/src/s_creall.c,v 1.1 2004/05/30 09:21:56 stefanf Exp $ */ #include #include "math_private.h" DLLEXPORT long double creall(long double complex z) { return z; } openlibm-0.5.0/src/s_csin.c000066400000000000000000000037551266752446200155620ustar00rootroot00000000000000/* $OpenBSD: s_csin.c,v 1.6 2013/07/03 04:46:36 espie Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* csin() * * Complex circular sine * * * * SYNOPSIS: * * double complex csin(); * double complex z, w; * * w = csin (z); * * * * DESCRIPTION: * * If * z = x + iy, * * then * * w = sin x cosh y + i cos x sinh y. * * csin(z) = -i csinh(iz). * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * DEC -10,+10 8400 5.3e-17 1.3e-17 * IEEE -10,+10 30000 3.8e-16 1.0e-16 * Also tested by csin(casin(z)) = z. * */ #include #include #include /* calculate cosh and sinh */ static void cchsh(double x, double *c, double *s) { double e, ei; if (fabs(x) <= 0.5) { *c = cosh(x); *s = sinh(x); } else { e = exp(x); ei = 0.5/e; e = 0.5 * e; *s = e - ei; *c = e + ei; } } double complex csin(double complex z) { double complex w; double ch, sh; cchsh( cimag (z), &ch, &sh ); w = sin (creal(z)) * ch + (cos (creal(z)) * sh) * I; return (w); } #if LDBL_MANT_DIG == DBL_MANT_DIG __strong_alias(csinl, csin); #endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ openlibm-0.5.0/src/s_csinf.c000066400000000000000000000033721266752446200157230ustar00rootroot00000000000000/* $OpenBSD: s_csinf.c,v 1.2 2010/07/18 18:42:26 guenther Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* csinf() * * Complex circular sine * * * * SYNOPSIS: * * void csinf(); * cmplxf z, w; * * csinf( &z, &w ); * * * * DESCRIPTION: * * If * z = x + iy, * * then * * w = sin x cosh y + i cos x sinh y. * * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE -10,+10 30000 1.9e-7 5.5e-8 * */ #include #include /* calculate cosh and sinh */ static void cchshf(float xx, float *c, float *s) { float x, e, ei; x = xx; if(fabsf(x) <= 0.5f) { *c = coshf(x); *s = sinhf(x); } else { e = expf(x); ei = 0.5f/e; e = 0.5f * e; *s = e - ei; *c = e + ei; } } float complex csinf(float complex z) { float complex w; float ch, sh; cchshf(cimagf(z), &ch, &sh); w = sinf(crealf(z)) * ch + (cosf(crealf(z)) * sh) * I; return (w); } openlibm-0.5.0/src/s_csinh.c000066400000000000000000000117121266752446200157220ustar00rootroot00000000000000/*- * Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice unmodified, this list of conditions, and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Hyperbolic sine of a complex argument z = x + i y. * * sinh(z) = sinh(x+iy) * = sinh(x) cos(y) + i cosh(x) sin(y). * * Exceptional values are noted in the comments within the source code. * These values and the return value were taken from n1124.pdf. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_csinh.c,v 1.2 2011/10/21 06:29:32 das Exp $"); #include #include #include "math_private.h" static const double huge = 0x1p1023; DLLEXPORT double complex csinh(double complex z) { double x, y, h; int32_t hx, hy, ix, iy, lx, ly; x = creal(z); y = cimag(z); EXTRACT_WORDS(hx, lx, x); EXTRACT_WORDS(hy, ly, y); ix = 0x7fffffff & hx; iy = 0x7fffffff & hy; /* Handle the nearly-non-exceptional cases where x and y are finite. */ if (ix < 0x7ff00000 && iy < 0x7ff00000) { if ((iy | ly) == 0) return (CMPLX(sinh(x), y)); if (ix < 0x40360000) /* small x: normal case */ return (CMPLX(sinh(x) * cos(y), cosh(x) * sin(y))); /* |x| >= 22, so cosh(x) ~= exp(|x|) */ if (ix < 0x40862e42) { /* x < 710: exp(|x|) won't overflow */ h = exp(fabs(x)) * 0.5; return (CMPLX(copysign(h, x) * cos(y), h * sin(y))); } else if (ix < 0x4096bbaa) { /* x < 1455: scale to avoid overflow */ z = __ldexp_cexp(CMPLX(fabs(x), y), -1); return (CMPLX(creal(z) * copysign(1, x), cimag(z))); } else { /* x >= 1455: the result always overflows */ h = huge * x; return (CMPLX(h * cos(y), h * h * sin(y))); } } /* * sinh(+-0 +- I Inf) = sign(d(+-0, dNaN))0 + I dNaN. * The sign of 0 in the result is unspecified. Choice = normally * the same as dNaN. Raise the invalid floating-point exception. * * sinh(+-0 +- I NaN) = sign(d(+-0, NaN))0 + I d(NaN). * The sign of 0 in the result is unspecified. Choice = normally * the same as d(NaN). */ if ((ix | lx) == 0 && iy >= 0x7ff00000) return (CMPLX(copysign(0, x * (y - y)), y - y)); /* * sinh(+-Inf +- I 0) = +-Inf + I +-0. * * sinh(NaN +- I 0) = d(NaN) + I +-0. */ if ((iy | ly) == 0 && ix >= 0x7ff00000) { if (((hx & 0xfffff) | lx) == 0) return (CMPLX(x, y)); return (CMPLX(x, copysign(0, y))); } /* * sinh(x +- I Inf) = dNaN + I dNaN. * Raise the invalid floating-point exception for finite nonzero x. * * sinh(x + I NaN) = d(NaN) + I d(NaN). * Optionally raises the invalid floating-point exception for finite * nonzero x. Choice = don't raise (except for signaling NaNs). */ if (ix < 0x7ff00000 && iy >= 0x7ff00000) return (CMPLX(y - y, x * (y - y))); /* * sinh(+-Inf + I NaN) = +-Inf + I d(NaN). * The sign of Inf in the result is unspecified. Choice = normally * the same as d(NaN). * * sinh(+-Inf +- I Inf) = +Inf + I dNaN. * The sign of Inf in the result is unspecified. Choice = always +. * Raise the invalid floating-point exception. * * sinh(+-Inf + I y) = +-Inf cos(y) + I Inf sin(y) */ if (ix >= 0x7ff00000 && ((hx & 0xfffff) | lx) == 0) { if (iy >= 0x7ff00000) return (CMPLX(x * x, x * (y - y))); return (CMPLX(x * cos(y), INFINITY * sin(y))); } /* * sinh(NaN + I NaN) = d(NaN) + I d(NaN). * * sinh(NaN +- I Inf) = d(NaN) + I d(NaN). * Optionally raises the invalid floating-point exception. * Choice = raise. * * sinh(NaN + I y) = d(NaN) + I d(NaN). * Optionally raises the invalid floating-point exception for finite * nonzero y. Choice = don't raise (except for signaling NaNs). */ return (CMPLX((x * x) * (y - y), (x + x) * (y - y))); } DLLEXPORT double complex csin(double complex z) { /* csin(z) = -I * csinh(I * z) */ z = csinh(CMPLX(-cimag(z), creal(z))); return (CMPLX(cimag(z), -creal(z))); } openlibm-0.5.0/src/s_csinhf.c000066400000000000000000000063241266752446200160730ustar00rootroot00000000000000/*- * Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice unmodified, this list of conditions, and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Hyperbolic sine of a complex argument z. See s_csinh.c for details. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_csinhf.c,v 1.2 2011/10/21 06:29:32 das Exp $"); #include #include #include "math_private.h" static const float huge = 0x1p127; DLLEXPORT float complex csinhf(float complex z) { float x, y, h; int32_t hx, hy, ix, iy; x = crealf(z); y = cimagf(z); GET_FLOAT_WORD(hx, x); GET_FLOAT_WORD(hy, y); ix = 0x7fffffff & hx; iy = 0x7fffffff & hy; if (ix < 0x7f800000 && iy < 0x7f800000) { if (iy == 0) return (CMPLXF(sinhf(x), y)); if (ix < 0x41100000) /* small x: normal case */ return (CMPLXF(sinhf(x) * cosf(y), coshf(x) * sinf(y))); /* |x| >= 9, so cosh(x) ~= exp(|x|) */ if (ix < 0x42b17218) { /* x < 88.7: expf(|x|) won't overflow */ h = expf(fabsf(x)) * 0.5f; return (CMPLXF(copysignf(h, x) * cosf(y), h * sinf(y))); } else if (ix < 0x4340b1e7) { /* x < 192.7: scale to avoid overflow */ z = __ldexp_cexpf(CMPLXF(fabsf(x), y), -1); return (CMPLXF(crealf(z) * copysignf(1, x), cimagf(z))); } else { /* x >= 192.7: the result always overflows */ h = huge * x; return (CMPLXF(h * cosf(y), h * h * sinf(y))); } } if (ix == 0 && iy >= 0x7f800000) return (CMPLXF(copysignf(0, x * (y - y)), y - y)); if (iy == 0 && ix >= 0x7f800000) { if ((hx & 0x7fffff) == 0) return (CMPLXF(x, y)); return (CMPLXF(x, copysignf(0, y))); } if (ix < 0x7f800000 && iy >= 0x7f800000) return (CMPLXF(y - y, x * (y - y))); if (ix >= 0x7f800000 && (hx & 0x7fffff) == 0) { if (iy >= 0x7f800000) return (CMPLXF(x * x, x * (y - y))); return (CMPLXF(x * cosf(y), INFINITY * sinf(y))); } return (CMPLXF((x * x) * (y - y), (x + x) * (y - y))); } DLLEXPORT float complex csinf(float complex z) { z = csinhf(CMPLXF(-cimagf(z), crealf(z))); return (CMPLXF(cimagf(z), -crealf(z))); } openlibm-0.5.0/src/s_csinhl.c000066400000000000000000000030411266752446200160720ustar00rootroot00000000000000/* $OpenBSD: s_csinhl.c,v 1.2 2011/07/20 19:28:33 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* csinhl * * Complex hyperbolic sine * * * * SYNOPSIS: * * long double complex csinhl(); * long double complex z, w; * * w = csinhl (z); * * DESCRIPTION: * * csinh z = (cexp(z) - cexp(-z))/2 * = sinh x * cos y + i cosh x * sin y . * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE -10,+10 30000 3.1e-16 8.2e-17 * */ #include #include long double complex csinhl(long double complex z) { long double complex w; long double x, y; x = creall(z); y = cimagl(z); w = sinhl(x) * cosl(y) + (coshl(x) * sinl(y)) * I; return (w); } openlibm-0.5.0/src/s_csinl.c000066400000000000000000000035731266752446200157340ustar00rootroot00000000000000/* $OpenBSD: s_csinl.c,v 1.2 2011/07/20 19:28:33 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* csinl() * * Complex circular sine * * * * SYNOPSIS: * * long double complex csinl(); * long double complex z, w; * * w = csinl( z ); * * * * DESCRIPTION: * * If * z = x + iy, * * then * * w = sin x cosh y + i cos x sinh y. * * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * DEC -10,+10 8400 5.3e-17 1.3e-17 * IEEE -10,+10 30000 3.8e-16 1.0e-16 * Also tested by csin(casin(z)) = z. * */ #include #include static void cchshl(long double x, long double *c, long double *s) { long double e, ei; if(fabsl(x) <= 0.5L) { *c = coshl(x); *s = sinhl(x); } else { e = expl(x); ei = 0.5L/e; e = 0.5L * e; *s = e - ei; *c = e + ei; } } long double complex csinl(long double complex z) { long double complex w; long double ch, sh; cchshl(cimagl(z), &ch, &sh); w = sinl(creall(z)) * ch + (cosl(creall(z)) * sh) * I; return (w); } openlibm-0.5.0/src/s_csqrt.c000066400000000000000000000065071266752446200157600ustar00rootroot00000000000000/*- * Copyright (c) 2007 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_csqrt.c,v 1.4 2008/08/08 00:15:16 das Exp $"); #include #include #include #include "math_private.h" /* * gcc doesn't implement complex multiplication or division correctly, * so we need to handle infinities specially. We turn on this pragma to * notify conforming c99 compilers that the fast-but-incorrect code that * gcc generates is acceptable, since the special cases have already been * handled. */ #ifndef __GNUC__ #pragma STDC CX_LIMITED_RANGE ON #endif /* We risk spurious overflow for components >= DBL_MAX / (1 + sqrt(2)). */ #define THRESH 0x1.a827999fcef32p+1022 DLLEXPORT double complex csqrt(double complex z) { double complex result; double a, b; double t; int scale; a = creal(z); b = cimag(z); /* Handle special cases. */ if (z == 0) return (CMPLX(0, b)); if (isinf(b)) return (CMPLX(INFINITY, b)); if (isnan(a)) { t = (b - b) / (b - b); /* raise invalid if b is not a NaN */ return (CMPLX(a, t)); /* return NaN + NaN i */ } if (isinf(a)) { /* * csqrt(inf + NaN i) = inf + NaN i * csqrt(inf + y i) = inf + 0 i * csqrt(-inf + NaN i) = NaN +- inf i * csqrt(-inf + y i) = 0 + inf i */ if (signbit(a)) return (CMPLX(fabs(b - b), copysign(a, b))); else return (CMPLX(a, copysign(b - b, b))); } /* * The remaining special case (b is NaN) is handled just fine by * the normal code path below. */ /* Scale to avoid overflow. */ if (fabs(a) >= THRESH || fabs(b) >= THRESH) { a *= 0.25; b *= 0.25; scale = 1; } else { scale = 0; } /* Algorithm 312, CACM vol 10, Oct 1967. */ if (a >= 0) { t = sqrt((a + hypot(a, b)) * 0.5); result = CMPLX(t, b / (2 * t)); } else { t = sqrt((-a + hypot(a, b)) * 0.5); result = CMPLX(fabs(b) / (2 * t), copysign(t, b)); } /* Rescale. */ if (scale) return (result * 2); else return (result); } #if LDBL_MANT_DIG == 53 __weak_reference(csqrt, csqrtl); #endif openlibm-0.5.0/src/s_csqrtf.c000066400000000000000000000060101266752446200161130ustar00rootroot00000000000000/*- * Copyright (c) 2007 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_csqrtf.c,v 1.3 2008/08/08 00:15:16 das Exp $"); #include #include #include "math_private.h" /* * gcc doesn't implement complex multiplication or division correctly, * so we need to handle infinities specially. We turn on this pragma to * notify conforming c99 compilers that the fast-but-incorrect code that * gcc generates is acceptable, since the special cases have already been * handled. */ #ifndef __GNUC__ #pragma STDC CX_LIMITED_RANGE ON #endif DLLEXPORT float complex csqrtf(float complex z) { float a = crealf(z), b = cimagf(z); double t; /* Handle special cases. */ if (z == 0) return (CMPLXF(0, b)); if (isinf(b)) return (CMPLXF(INFINITY, b)); if (isnan(a)) { t = (b - b) / (b - b); /* raise invalid if b is not a NaN */ return (CMPLXF(a, t)); /* return NaN + NaN i */ } if (isinf(a)) { /* * csqrtf(inf + NaN i) = inf + NaN i * csqrtf(inf + y i) = inf + 0 i * csqrtf(-inf + NaN i) = NaN +- inf i * csqrtf(-inf + y i) = 0 + inf i */ if (signbit(a)) return (CMPLXF(fabsf(b - b), copysignf(a, b))); else return (CMPLXF(a, copysignf(b - b, b))); } /* * The remaining special case (b is NaN) is handled just fine by * the normal code path below. */ /* * We compute t in double precision to avoid overflow and to * provide correct rounding in nearly all cases. * This is Algorithm 312, CACM vol 10, Oct 1967. */ if (a >= 0) { t = sqrt((a + hypot(a, b)) * 0.5); return (CMPLXF(t, b / (2.0 * t))); } else { t = sqrt((-a + hypot(a, b)) * 0.5); return (CMPLXF(fabsf(b) / (2.0 * t), copysignf(t, b))); } } openlibm-0.5.0/src/s_csqrtl.c000066400000000000000000000063741266752446200161360ustar00rootroot00000000000000/*- * Copyright (c) 2007-2008 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" #include #include #include #include "math_private.h" /* * gcc doesn't implement complex multiplication or division correctly, * so we need to handle infinities specially. We turn on this pragma to * notify conforming c99 compilers that the fast-but-incorrect code that * gcc generates is acceptable, since the special cases have already been * handled. */ #ifndef __GNUC__ #pragma STDC CX_LIMITED_RANGE ON #endif /* We risk spurious overflow for components >= LDBL_MAX / (1 + sqrt(2)). */ #define THRESH (LDBL_MAX / 2.414213562373095048801688724209698L) DLLEXPORT long double complex csqrtl(long double complex z) { long double complex result; long double a, b; long double t; int scale; a = creall(z); b = cimagl(z); /* Handle special cases. */ if (z == 0) return (CMPLXL(0, b)); if (isinf(b)) return (CMPLXL(INFINITY, b)); if (isnan(a)) { t = (b - b) / (b - b); /* raise invalid if b is not a NaN */ return (CMPLXL(a, t)); /* return NaN + NaN i */ } if (isinf(a)) { /* * csqrt(inf + NaN i) = inf + NaN i * csqrt(inf + y i) = inf + 0 i * csqrt(-inf + NaN i) = NaN +- inf i * csqrt(-inf + y i) = 0 + inf i */ if (signbit(a)) return (CMPLXL(fabsl(b - b), copysignl(a, b))); else return (CMPLXL(a, copysignl(b - b, b))); } /* * The remaining special case (b is NaN) is handled just fine by * the normal code path below. */ /* Scale to avoid overflow. */ if (fabsl(a) >= THRESH || fabsl(b) >= THRESH) { a *= 0.25; b *= 0.25; scale = 1; } else { scale = 0; } /* Algorithm 312, CACM vol 10, Oct 1967. */ if (a >= 0) { t = sqrtl((a + hypotl(a, b)) * 0.5); result = CMPLXL(t, b / (2 * t)); } else { t = sqrtl((-a + hypotl(a, b)) * 0.5); result = CMPLXL(fabsl(b) / (2 * t), copysignl(t, b)); } /* Rescale. */ if (scale) return (result * 2); else return (result); } openlibm-0.5.0/src/s_ctan.c000066400000000000000000000061201266752446200155400ustar00rootroot00000000000000/* $OpenBSD: s_ctan.c,v 1.6 2013/07/03 04:46:36 espie Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* ctan() * * Complex circular tangent * * * * SYNOPSIS: * * double complex ctan(); * double complex z, w; * * w = ctan (z); * * * * DESCRIPTION: * * If * z = x + iy, * * then * * sin 2x + i sinh 2y * w = --------------------. * cos 2x + cosh 2y * * On the real axis the denominator is zero at odd multiples * of PI/2. The denominator is evaluated by its Taylor * series near these points. * * ctan(z) = -i ctanh(iz). * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * DEC -10,+10 5200 7.1e-17 1.6e-17 * IEEE -10,+10 30000 7.2e-16 1.2e-16 * Also tested by ctan * ccot = 1 and catan(ctan(z)) = z. */ #include #include #include #define MACHEP 1.1e-16 #define MAXNUM 1.0e308 static const double DP1 = 3.14159265160560607910E0; static const double DP2 = 1.98418714791870343106E-9; static const double DP3 = 1.14423774522196636802E-17; static double _redupi(double x) { double t; long i; t = x/M_PI; if (t >= 0.0) t += 0.5; else t -= 0.5; i = t; /* the multiple */ t = i; t = ((x - t * DP1) - t * DP2) - t * DP3; return (t); } /* Taylor series expansion for cosh(2y) - cos(2x) */ static double _ctans(double complex z) { double f, x, x2, y, y2, rn, t; double d; x = fabs (2.0 * creal (z)); y = fabs (2.0 * cimag(z)); x = _redupi(x); x = x * x; y = y * y; x2 = 1.0; y2 = 1.0; f = 1.0; rn = 0.0; d = 0.0; do { rn += 1.0; f *= rn; rn += 1.0; f *= rn; x2 *= x; y2 *= y; t = y2 + x2; t /= f; d += t; rn += 1.0; f *= rn; rn += 1.0; f *= rn; x2 *= x; y2 *= y; t = y2 - x2; t /= f; d += t; } while (fabs(t/d) > MACHEP) ; return (d); } double complex ctan(double complex z) { double complex w; double d; d = cos (2.0 * creal (z)) + cosh (2.0 * cimag (z)); if (fabs(d) < 0.25) d = _ctans (z); if (d == 0.0) { /*mtherr ("ctan", OVERFLOW);*/ w = MAXNUM + MAXNUM * I; return (w); } w = sin (2.0 * creal(z)) / d + (sinh (2.0 * cimag(z)) / d) * I; return (w); } #if LDBL_MANT_DIG == DBL_MANT_DIG __strong_alias(ctanl, ctan); #endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ openlibm-0.5.0/src/s_ctanf.c000066400000000000000000000055031266752446200157120ustar00rootroot00000000000000/* $OpenBSD: s_ctanf.c,v 1.2 2011/07/20 19:28:33 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* ctanf() * * Complex circular tangent * * * * SYNOPSIS: * * void ctanf(); * cmplxf z, w; * * ctanf( &z, &w ); * * * * DESCRIPTION: * * If * z = x + iy, * * then * * sin 2x + i sinh 2y * w = --------------------. * cos 2x + cosh 2y * * On the real axis the denominator is zero at odd multiples * of PI/2. The denominator is evaluated by its Taylor * series near these points. * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE -10,+10 30000 3.3e-7 5.1e-8 */ #include #include #define MACHEPF 3.0e-8 #define MAXNUMF 1.0e38f static const double DP1 = 3.140625; static const double DP2 = 9.67502593994140625E-4; static const double DP3 = 1.509957990978376432E-7; static float _redupif(float xx) { float x, t; long i; x = xx; t = x/(float)M_PI; if(t >= 0.0) t += 0.5; else t -= 0.5; i = t; /* the multiple */ t = i; t = ((x - t * DP1) - t * DP2) - t * DP3; return(t); } /* Taylor series expansion for cosh(2y) - cos(2x) */ static float _ctansf(float complex z) { float f, x, x2, y, y2, rn, t, d; x = fabsf(2.0f * crealf(z)); y = fabsf(2.0f * cimagf(z)); x = _redupif(x); x = x * x; y = y * y; x2 = 1.0f; y2 = 1.0f; f = 1.0f; rn = 0.0f; d = 0.0f; do { rn += 1.0f; f *= rn; rn += 1.0f; f *= rn; x2 *= x; y2 *= y; t = y2 + x2; t /= f; d += t; rn += 1.0f; f *= rn; rn += 1.0f; f *= rn; x2 *= x; y2 *= y; t = y2 - x2; t /= f; d += t; } while (fabsf(t/d) > MACHEPF) ; return(d); } float complex ctanf(float complex z) { float complex w; float d; d = cosf( 2.0f * crealf(z) ) + coshf( 2.0f * cimagf(z) ); if(fabsf(d) < 0.25f) d = _ctansf(z); if (d == 0.0f) { /*mtherr( "ctanf", OVERFLOW );*/ w = MAXNUMF + MAXNUMF * I; return (w); } w = sinf (2.0f * crealf(z)) / d + (sinhf (2.0f * cimagf(z)) / d) * I; return (w); } openlibm-0.5.0/src/s_ctanh.c000066400000000000000000000104521266752446200157130ustar00rootroot00000000000000/*- * Copyright (c) 2011 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice unmodified, this list of conditions, and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Hyperbolic tangent of a complex argument z = x + i y. * * The algorithm is from: * * W. Kahan. Branch Cuts for Complex Elementary Functions or Much * Ado About Nothing's Sign Bit. In The State of the Art in * Numerical Analysis, pp. 165 ff. Iserles and Powell, eds., 1987. * * Method: * * Let t = tan(x) * beta = 1/cos^2(y) * s = sinh(x) * rho = cosh(x) * * We have: * * tanh(z) = sinh(z) / cosh(z) * * sinh(x) cos(y) + i cosh(x) sin(y) * = --------------------------------- * cosh(x) cos(y) + i sinh(x) sin(y) * * cosh(x) sinh(x) / cos^2(y) + i tan(y) * = ------------------------------------- * 1 + sinh^2(x) / cos^2(y) * * beta rho s + i t * = ---------------- * 1 + beta s^2 * * Modifications: * * I omitted the original algorithm's handling of overflow in tan(x) after * verifying with nearpi.c that this can't happen in IEEE single or double * precision. I also handle large x differently. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_ctanh.c,v 1.2 2011/10/21 06:30:16 das Exp $"); #include #include #include "math_private.h" DLLEXPORT double complex ctanh(double complex z) { double x, y; double t, beta, s, rho, denom; u_int32_t hx, ix, lx; x = creal(z); y = cimag(z); EXTRACT_WORDS(hx, lx, x); ix = hx & 0x7fffffff; /* * ctanh(NaN + i 0) = NaN + i 0 * * ctanh(NaN + i y) = NaN + i NaN for y != 0 * * The imaginary part has the sign of x*sin(2*y), but there's no * special effort to get this right. * * ctanh(+-Inf +- i Inf) = +-1 +- 0 * * ctanh(+-Inf + i y) = +-1 + 0 sin(2y) for y finite * * The imaginary part of the sign is unspecified. This special * case is only needed to avoid a spurious invalid exception when * y is infinite. */ if (ix >= 0x7ff00000) { if ((ix & 0xfffff) | lx) /* x is NaN */ return (CMPLX(x, (y == 0 ? y : x * y))); SET_HIGH_WORD(x, hx - 0x40000000); /* x = copysign(1, x) */ return (CMPLX(x, copysign(0, isinf(y) ? y : sin(y) * cos(y)))); } /* * ctanh(x + i NAN) = NaN + i NaN * ctanh(x +- i Inf) = NaN + i NaN */ if (!isfinite(y)) return (CMPLX(y - y, y - y)); /* * ctanh(+-huge + i +-y) ~= +-1 +- i 2sin(2y)/exp(2x), using the * approximation sinh^2(huge) ~= exp(2*huge) / 4. * We use a modified formula to avoid spurious overflow. */ if (ix >= 0x40360000) { /* x >= 22 */ double exp_mx = exp(-fabs(x)); return (CMPLX(copysign(1, x), 4 * sin(y) * cos(y) * exp_mx * exp_mx)); } /* Kahan's algorithm */ t = tan(y); beta = 1.0 + t * t; /* = 1 / cos^2(y) */ s = sinh(x); rho = sqrt(1 + s * s); /* = cosh(x) */ denom = 1 + beta * s * s; return (CMPLX((beta * rho * s) / denom, t / denom)); } DLLEXPORT double complex ctan(double complex z) { /* ctan(z) = -I * ctanh(I * z) */ z = ctanh(CMPLX(-cimag(z), creal(z))); return (CMPLX(cimag(z), -creal(z))); } openlibm-0.5.0/src/s_ctanhf.c000066400000000000000000000047501266752446200160650ustar00rootroot00000000000000/*- * Copyright (c) 2011 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice unmodified, this list of conditions, and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Hyperbolic tangent of a complex argument z. See s_ctanh.c for details. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_ctanhf.c,v 1.2 2011/10/21 06:30:16 das Exp $"); #include #include #include "math_private.h" DLLEXPORT float complex ctanhf(float complex z) { float x, y; float t, beta, s, rho, denom; u_int32_t hx, ix; x = crealf(z); y = cimagf(z); GET_FLOAT_WORD(hx, x); ix = hx & 0x7fffffff; if (ix >= 0x7f800000) { if (ix & 0x7fffff) return (CMPLXF(x, (y == 0 ? y : x * y))); SET_FLOAT_WORD(x, hx - 0x40000000); return (CMPLXF(x, copysignf(0, isinf(y) ? y : sinf(y) * cosf(y)))); } if (!isfinite(y)) return (CMPLXF(y - y, y - y)); if (ix >= 0x41300000) { /* x >= 11 */ float exp_mx = expf(-fabsf(x)); return (CMPLXF(copysignf(1, x), 4 * sinf(y) * cosf(y) * exp_mx * exp_mx)); } t = tanf(y); beta = 1.0 + t * t; s = sinhf(x); rho = sqrtf(1 + s * s); denom = 1 + beta * s * s; return (CMPLXF((beta * rho * s) / denom, t / denom)); } DLLEXPORT float complex ctanf(float complex z) { z = ctanhf(CMPLXF(-cimagf(z), crealf(z))); return (CMPLXF(cimagf(z), -crealf(z))); } openlibm-0.5.0/src/s_ctanhl.c000066400000000000000000000030701266752446200160650ustar00rootroot00000000000000/* $OpenBSD: s_ctanhl.c,v 1.2 2011/07/20 19:28:33 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* ctanhl * * Complex hyperbolic tangent * * * * SYNOPSIS: * * long double complex ctanhl(); * long double complex z, w; * * w = ctanhl (z); * * * * DESCRIPTION: * * tanh z = (sinh 2x + i sin 2y) / (cosh 2x + cos 2y) . * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE -10,+10 30000 1.7e-14 2.4e-16 * */ #include #include long double complex ctanhl(long double complex z) { long double complex w; long double x, y, d; x = creall(z); y = cimagl(z); d = coshl(2.0L * x) + cosl(2.0L * y); w = sinhl(2.0L * x) / d + (sinl(2.0L * y) / d) * I; return (w); } openlibm-0.5.0/src/s_ctanl.c000066400000000000000000000065501266752446200157230ustar00rootroot00000000000000/* $OpenBSD: s_ctanl.c,v 1.3 2011/07/20 21:02:51 martynas Exp $ */ /* * Copyright (c) 2008 Stephen L. Moshier * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* ctanl() * * Complex circular tangent * * * * SYNOPSIS: * * long double complex ctanl(); * long double complex z, w; * * w = ctanl( z ); * * * * DESCRIPTION: * * If * z = x + iy, * * then * * sin 2x + i sinh 2y * w = --------------------. * cos 2x + cosh 2y * * On the real axis the denominator is zero at odd multiples * of PI/2. The denominator is evaluated by its Taylor * series near these points. * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * DEC -10,+10 5200 7.1e-17 1.6e-17 * IEEE -10,+10 30000 7.2e-16 1.2e-16 * Also tested by ctan * ccot = 1 and catan(ctan(z)) = z. */ #include #include #include #if LDBL_MANT_DIG == 64 static const long double MACHEPL= 5.42101086242752217003726400434970855712890625E-20L; #elif LDBL_MANT_DIG == 113 static const long double MACHEPL = 9.629649721936179265279889712924636592690508e-35L; #endif static const long double PIL = 3.141592653589793238462643383279502884197169L; static const long double DP1 = 3.14159265358979323829596852490908531763125L; static const long double DP2 = 1.6667485837041756656403424829301998703007e-19L; static const long double DP3 = 1.8830410776607851167459095484560349402753e-39L; static long double redupil(long double x) { long double t; long i; t = x / PIL; if (t >= 0.0L) t += 0.5L; else t -= 0.5L; i = t; /* the multiple */ t = i; t = ((x - t * DP1) - t * DP2) - t * DP3; return (t); } static long double ctansl(long double complex z) { long double f, x, x2, y, y2, rn, t; long double d; x = fabsl(2.0L * creall(z)); y = fabsl(2.0L * cimagl(z)); x = redupil(x); x = x * x; y = y * y; x2 = 1.0L; y2 = 1.0L; f = 1.0L; rn = 0.0L; d = 0.0L; do { rn += 1.0L; f *= rn; rn += 1.0L; f *= rn; x2 *= x; y2 *= y; t = y2 + x2; t /= f; d += t; rn += 1.0L; f *= rn; rn += 1.0L; f *= rn; x2 *= x; y2 *= y; t = y2 - x2; t /= f; d += t; } while (fabsl(t/d) > MACHEPL); return(d); } long double complex ctanl(long double complex z) { long double complex w; long double d, x, y; x = creall(z); y = cimagl(z); d = cosl(2.0L * x) + coshl(2.0L * y); if (fabsl(d) < 0.25L) { d = fabsl(d); d = ctansl(z); } if (d == 0.0L) { /*mtherr( "ctan", OVERFLOW );*/ w = LDBL_MAX + LDBL_MAX * I; return (w); } w = sinl(2.0L * x) / d + (sinhl(2.0L * y) / d) * I; return (w); } openlibm-0.5.0/src/s_erf.c000066400000000000000000000256501266752446200154000ustar00rootroot00000000000000/* @(#)s_erf.c 5.1 93/09/24 */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_erf.c,v 1.8 2008/02/22 02:30:35 das Exp $"); /* double erf(double x) * double erfc(double x) * x * 2 |\ * erf(x) = --------- | exp(-t*t)dt * sqrt(pi) \| * 0 * * erfc(x) = 1-erf(x) * Note that * erf(-x) = -erf(x) * erfc(-x) = 2 - erfc(x) * * Method: * 1. For |x| in [0, 0.84375] * erf(x) = x + x*R(x^2) * erfc(x) = 1 - erf(x) if x in [-.84375,0.25] * = 0.5 + ((0.5-x)-x*R) if x in [0.25,0.84375] * where R = P/Q where P is an odd poly of degree 8 and * Q is an odd poly of degree 10. * -57.90 * | R - (erf(x)-x)/x | <= 2 * * * Remark. The formula is derived by noting * erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....) * and that * 2/sqrt(pi) = 1.128379167095512573896158903121545171688 * is close to one. The interval is chosen because the fix * point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is * near 0.6174), and by some experiment, 0.84375 is chosen to * guarantee the error is less than one ulp for erf. * * 2. For |x| in [0.84375,1.25], let s = |x| - 1, and * c = 0.84506291151 rounded to single (24 bits) * erf(x) = sign(x) * (c + P1(s)/Q1(s)) * erfc(x) = (1-c) - P1(s)/Q1(s) if x > 0 * 1+(c+P1(s)/Q1(s)) if x < 0 * |P1/Q1 - (erf(|x|)-c)| <= 2**-59.06 * Remark: here we use the taylor series expansion at x=1. * erf(1+s) = erf(1) + s*Poly(s) * = 0.845.. + P1(s)/Q1(s) * That is, we use rational approximation to approximate * erf(1+s) - (c = (single)0.84506291151) * Note that |P1/Q1|< 0.078 for x in [0.84375,1.25] * where * P1(s) = degree 6 poly in s * Q1(s) = degree 6 poly in s * * 3. For x in [1.25,1/0.35(~2.857143)], * erfc(x) = (1/x)*exp(-x*x-0.5625+R1/S1) * erf(x) = 1 - erfc(x) * where * R1(z) = degree 7 poly in z, (z=1/x^2) * S1(z) = degree 8 poly in z * * 4. For x in [1/0.35,28] * erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0 * = 2.0 - (1/x)*exp(-x*x-0.5625+R2/S2) if -6 x >= 28 * erf(x) = sign(x) *(1 - tiny) (raise inexact) * erfc(x) = tiny*tiny (raise underflow) if x > 0 * = 2 - tiny if x<0 * * 7. Special case: * erf(0) = 0, erf(inf) = 1, erf(-inf) = -1, * erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2, * erfc/erf(NaN) is NaN */ #include #include "math_private.h" static const double tiny = 1e-300, half= 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */ one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ two = 2.00000000000000000000e+00, /* 0x40000000, 0x00000000 */ /* c = (float)0.84506291151 */ erx = 8.45062911510467529297e-01, /* 0x3FEB0AC1, 0x60000000 */ /* * Coefficients for approximation to erf on [0,0.84375] */ efx = 1.28379167095512586316e-01, /* 0x3FC06EBA, 0x8214DB69 */ efx8= 1.02703333676410069053e+00, /* 0x3FF06EBA, 0x8214DB69 */ pp0 = 1.28379167095512558561e-01, /* 0x3FC06EBA, 0x8214DB68 */ pp1 = -3.25042107247001499370e-01, /* 0xBFD4CD7D, 0x691CB913 */ pp2 = -2.84817495755985104766e-02, /* 0xBF9D2A51, 0xDBD7194F */ pp3 = -5.77027029648944159157e-03, /* 0xBF77A291, 0x236668E4 */ pp4 = -2.37630166566501626084e-05, /* 0xBEF8EAD6, 0x120016AC */ qq1 = 3.97917223959155352819e-01, /* 0x3FD97779, 0xCDDADC09 */ qq2 = 6.50222499887672944485e-02, /* 0x3FB0A54C, 0x5536CEBA */ qq3 = 5.08130628187576562776e-03, /* 0x3F74D022, 0xC4D36B0F */ qq4 = 1.32494738004321644526e-04, /* 0x3F215DC9, 0x221C1A10 */ qq5 = -3.96022827877536812320e-06, /* 0xBED09C43, 0x42A26120 */ /* * Coefficients for approximation to erf in [0.84375,1.25] */ pa0 = -2.36211856075265944077e-03, /* 0xBF6359B8, 0xBEF77538 */ pa1 = 4.14856118683748331666e-01, /* 0x3FDA8D00, 0xAD92B34D */ pa2 = -3.72207876035701323847e-01, /* 0xBFD7D240, 0xFBB8C3F1 */ pa3 = 3.18346619901161753674e-01, /* 0x3FD45FCA, 0x805120E4 */ pa4 = -1.10894694282396677476e-01, /* 0xBFBC6398, 0x3D3E28EC */ pa5 = 3.54783043256182359371e-02, /* 0x3FA22A36, 0x599795EB */ pa6 = -2.16637559486879084300e-03, /* 0xBF61BF38, 0x0A96073F */ qa1 = 1.06420880400844228286e-01, /* 0x3FBB3E66, 0x18EEE323 */ qa2 = 5.40397917702171048937e-01, /* 0x3FE14AF0, 0x92EB6F33 */ qa3 = 7.18286544141962662868e-02, /* 0x3FB2635C, 0xD99FE9A7 */ qa4 = 1.26171219808761642112e-01, /* 0x3FC02660, 0xE763351F */ qa5 = 1.36370839120290507362e-02, /* 0x3F8BEDC2, 0x6B51DD1C */ qa6 = 1.19844998467991074170e-02, /* 0x3F888B54, 0x5735151D */ /* * Coefficients for approximation to erfc in [1.25,1/0.35] */ ra0 = -9.86494403484714822705e-03, /* 0xBF843412, 0x600D6435 */ ra1 = -6.93858572707181764372e-01, /* 0xBFE63416, 0xE4BA7360 */ ra2 = -1.05586262253232909814e+01, /* 0xC0251E04, 0x41B0E726 */ ra3 = -6.23753324503260060396e+01, /* 0xC04F300A, 0xE4CBA38D */ ra4 = -1.62396669462573470355e+02, /* 0xC0644CB1, 0x84282266 */ ra5 = -1.84605092906711035994e+02, /* 0xC067135C, 0xEBCCABB2 */ ra6 = -8.12874355063065934246e+01, /* 0xC0545265, 0x57E4D2F2 */ ra7 = -9.81432934416914548592e+00, /* 0xC023A0EF, 0xC69AC25C */ sa1 = 1.96512716674392571292e+01, /* 0x4033A6B9, 0xBD707687 */ sa2 = 1.37657754143519042600e+02, /* 0x4061350C, 0x526AE721 */ sa3 = 4.34565877475229228821e+02, /* 0x407B290D, 0xD58A1A71 */ sa4 = 6.45387271733267880336e+02, /* 0x40842B19, 0x21EC2868 */ sa5 = 4.29008140027567833386e+02, /* 0x407AD021, 0x57700314 */ sa6 = 1.08635005541779435134e+02, /* 0x405B28A3, 0xEE48AE2C */ sa7 = 6.57024977031928170135e+00, /* 0x401A47EF, 0x8E484A93 */ sa8 = -6.04244152148580987438e-02, /* 0xBFAEEFF2, 0xEE749A62 */ /* * Coefficients for approximation to erfc in [1/.35,28] */ rb0 = -9.86494292470009928597e-03, /* 0xBF843412, 0x39E86F4A */ rb1 = -7.99283237680523006574e-01, /* 0xBFE993BA, 0x70C285DE */ rb2 = -1.77579549177547519889e+01, /* 0xC031C209, 0x555F995A */ rb3 = -1.60636384855821916062e+02, /* 0xC064145D, 0x43C5ED98 */ rb4 = -6.37566443368389627722e+02, /* 0xC083EC88, 0x1375F228 */ rb5 = -1.02509513161107724954e+03, /* 0xC0900461, 0x6A2E5992 */ rb6 = -4.83519191608651397019e+02, /* 0xC07E384E, 0x9BDC383F */ sb1 = 3.03380607434824582924e+01, /* 0x403E568B, 0x261D5190 */ sb2 = 3.25792512996573918826e+02, /* 0x40745CAE, 0x221B9F0A */ sb3 = 1.53672958608443695994e+03, /* 0x409802EB, 0x189D5118 */ sb4 = 3.19985821950859553908e+03, /* 0x40A8FFB7, 0x688C246A */ sb5 = 2.55305040643316442583e+03, /* 0x40A3F219, 0xCEDF3BE6 */ sb6 = 4.74528541206955367215e+02, /* 0x407DA874, 0xE79FE763 */ sb7 = -2.24409524465858183362e+01; /* 0xC03670E2, 0x42712D62 */ DLLEXPORT double erf(double x) { int32_t hx,ix,i; double R,S,P,Q,s,y,z,r; GET_HIGH_WORD(hx,x); ix = hx&0x7fffffff; if(ix>=0x7ff00000) { /* erf(nan)=nan */ i = ((u_int32_t)hx>>31)<<1; return (double)(1-i)+one/x; /* erf(+-inf)=+-1 */ } if(ix < 0x3feb0000) { /* |x|<0.84375 */ if(ix < 0x3e300000) { /* |x|<2**-28 */ if (ix < 0x00800000) return 0.125*(8.0*x+efx8*x); /*avoid underflow */ return x + efx*x; } z = x*x; r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4))); s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5)))); y = r/s; return x + x*y; } if(ix < 0x3ff40000) { /* 0.84375 <= |x| < 1.25 */ s = fabs(x)-one; P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6))))); Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6))))); if(hx>=0) return erx + P/Q; else return -erx - P/Q; } if (ix >= 0x40180000) { /* inf>|x|>=6 */ if(hx>=0) return one-tiny; else return tiny-one; } x = fabs(x); s = one/(x*x); if(ix< 0x4006DB6E) { /* |x| < 1/0.35 */ R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*( ra5+s*(ra6+s*ra7)))))); S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*( sa5+s*(sa6+s*(sa7+s*sa8))))))); } else { /* |x| >= 1/0.35 */ R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*( rb5+s*rb6))))); S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*( sb5+s*(sb6+s*sb7)))))); } z = x; SET_LOW_WORD(z,0); r = __ieee754_exp(-z*z-0.5625)*__ieee754_exp((z-x)*(z+x)+R/S); if(hx>=0) return one-r/x; else return r/x-one; } DLLEXPORT double erfc(double x) { int32_t hx,ix; double R,S,P,Q,s,y,z,r; GET_HIGH_WORD(hx,x); ix = hx&0x7fffffff; if(ix>=0x7ff00000) { /* erfc(nan)=nan */ /* erfc(+-inf)=0,2 */ return (double)(((u_int32_t)hx>>31)<<1)+one/x; } if(ix < 0x3feb0000) { /* |x|<0.84375 */ if(ix < 0x3c700000) /* |x|<2**-56 */ return one-x; z = x*x; r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4))); s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5)))); y = r/s; if(hx < 0x3fd00000) { /* x<1/4 */ return one-(x+x*y); } else { r = x*y; r += (x-half); return half - r ; } } if(ix < 0x3ff40000) { /* 0.84375 <= |x| < 1.25 */ s = fabs(x)-one; P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6))))); Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6))))); if(hx>=0) { z = one-erx; return z - P/Q; } else { z = erx+P/Q; return one+z; } } if (ix < 0x403c0000) { /* |x|<28 */ x = fabs(x); s = one/(x*x); if(ix< 0x4006DB6D) { /* |x| < 1/.35 ~ 2.857143*/ R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*( ra5+s*(ra6+s*ra7)))))); S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*( sa5+s*(sa6+s*(sa7+s*sa8))))))); } else { /* |x| >= 1/.35 ~ 2.857143 */ if(hx<0&&ix>=0x40180000) return two-tiny;/* x < -6 */ R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*( rb5+s*rb6))))); S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*( sb5+s*(sb6+s*sb7)))))); } z = x; SET_LOW_WORD(z,0); r = __ieee754_exp(-z*z-0.5625)* __ieee754_exp((z-x)*(z+x)+R/S); if(hx>0) return r/x; else return two-r/x; } else { if(hx>0) return tiny*tiny; else return two-tiny; } } openlibm-0.5.0/src/s_erff.c000066400000000000000000000134321266752446200155410ustar00rootroot00000000000000/* s_erff.c -- float version of s_erf.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_erff.c,v 1.8 2008/02/22 02:30:35 das Exp $"); #include #include "math_private.h" static const float tiny = 1e-30, half= 5.0000000000e-01, /* 0x3F000000 */ one = 1.0000000000e+00, /* 0x3F800000 */ two = 2.0000000000e+00, /* 0x40000000 */ /* * Coefficients for approximation to erf on [0,0.84375] */ efx = 1.2837916613e-01, /* 0x3e0375d4 */ efx8= 1.0270333290e+00, /* 0x3f8375d4 */ /* * Domain [0, 0.84375], range ~[-5.4446e-10,5.5197e-10]: * |(erf(x) - x)/x - p(x)/q(x)| < 2**-31. */ pp0 = 1.28379166e-01F, /* 0x1.06eba8p-3 */ pp1 = -3.36030394e-01F, /* -0x1.58185ap-2 */ pp2 = -1.86260219e-03F, /* -0x1.e8451ep-10 */ qq1 = 3.12324286e-01F, /* 0x1.3fd1f0p-2 */ qq2 = 2.16070302e-02F, /* 0x1.620274p-6 */ qq3 = -1.98859419e-03F, /* -0x1.04a626p-9 */ /* * Domain [0.84375, 1.25], range ~[-1.953e-11,1.940e-11]: * |(erf(x) - erx) - p(x)/q(x)| < 2**-36. */ erx = 8.42697144e-01F, /* 0x1.af7600p-1. erf(1) rounded to 16 bits. */ pa0 = 3.64939137e-06F, /* 0x1.e9d022p-19 */ pa1 = 4.15109694e-01F, /* 0x1.a91284p-2 */ pa2 = -1.65179938e-01F, /* -0x1.5249dcp-3 */ pa3 = 1.10914491e-01F, /* 0x1.c64e46p-4 */ qa1 = 6.02074385e-01F, /* 0x1.344318p-1 */ qa2 = 5.35934687e-01F, /* 0x1.126608p-1 */ qa3 = 1.68576106e-01F, /* 0x1.593e6ep-3 */ qa4 = 5.62181212e-02F, /* 0x1.cc89f2p-5 */ /* * Domain [1.25,1/0.35], range ~[-7.043e-10,7.457e-10]: * |log(x*erfc(x)) + x**2 + 0.5625 - r(x)/s(x)| < 2**-30 */ ra0 = -9.87132732e-03F, /* -0x1.4376b2p-7 */ ra1 = -5.53605914e-01F, /* -0x1.1b723cp-1 */ ra2 = -2.17589188e+00F, /* -0x1.1683a0p+1 */ ra3 = -1.43268085e+00F, /* -0x1.6ec42cp+0 */ sa1 = 5.45995426e+00F, /* 0x1.5d6fe4p+2 */ sa2 = 6.69798088e+00F, /* 0x1.acabb8p+2 */ sa3 = 1.43113089e+00F, /* 0x1.6e5e98p+0 */ sa4 = -5.77397496e-02F, /* -0x1.d90108p-5 */ /* * Domain [1/0.35, 11], range ~[-2.264e-13,2.336e-13]: * |log(x*erfc(x)) + x**2 + 0.5625 - r(x)/s(x)| < 2**-42 */ rb0 = -9.86494310e-03F, /* -0x1.434124p-7 */ rb1 = -6.25171244e-01F, /* -0x1.401672p-1 */ rb2 = -6.16498327e+00F, /* -0x1.8a8f16p+2 */ rb3 = -1.66696873e+01F, /* -0x1.0ab70ap+4 */ rb4 = -9.53764343e+00F, /* -0x1.313460p+3 */ sb1 = 1.26884899e+01F, /* 0x1.96081cp+3 */ sb2 = 4.51839523e+01F, /* 0x1.6978bcp+5 */ sb3 = 4.72810211e+01F, /* 0x1.7a3f88p+5 */ sb4 = 8.93033314e+00F; /* 0x1.1dc54ap+3 */ DLLEXPORT float erff(float x) { int32_t hx,ix,i; float R,S,P,Q,s,y,z,r; GET_FLOAT_WORD(hx,x); ix = hx&0x7fffffff; if(ix>=0x7f800000) { /* erf(nan)=nan */ i = ((u_int32_t)hx>>31)<<1; return (float)(1-i)+one/x; /* erf(+-inf)=+-1 */ } if(ix < 0x3f580000) { /* |x|<0.84375 */ if(ix < 0x38800000) { /* |x|<2**-14 */ if (ix < 0x04000000) /* |x|<0x1p-119 */ return (8*x+efx8*x)/8; /* avoid spurious underflow */ return x + efx*x; } z = x*x; r = pp0+z*(pp1+z*pp2); s = one+z*(qq1+z*(qq2+z*qq3)); y = r/s; return x + x*y; } if(ix < 0x3fa00000) { /* 0.84375 <= |x| < 1.25 */ s = fabsf(x)-one; P = pa0+s*(pa1+s*(pa2+s*pa3)); Q = one+s*(qa1+s*(qa2+s*(qa3+s*qa4))); if(hx>=0) return erx + P/Q; else return -erx - P/Q; } if (ix >= 0x40800000) { /* inf>|x|>=4 */ if(hx>=0) return one-tiny; else return tiny-one; } x = fabsf(x); s = one/(x*x); if(ix< 0x4036DB6E) { /* |x| < 1/0.35 */ R=ra0+s*(ra1+s*(ra2+s*ra3)); S=one+s*(sa1+s*(sa2+s*(sa3+s*sa4))); } else { /* |x| >= 1/0.35 */ R=rb0+s*(rb1+s*(rb2+s*(rb3+s*rb4))); S=one+s*(sb1+s*(sb2+s*(sb3+s*sb4))); } SET_FLOAT_WORD(z,hx&0xffffe000); r = expf(-z*z-0.5625F)*expf((z-x)*(z+x)+R/S); if(hx>=0) return one-r/x; else return r/x-one; } DLLEXPORT float erfcf(float x) { int32_t hx,ix; float R,S,P,Q,s,y,z,r; GET_FLOAT_WORD(hx,x); ix = hx&0x7fffffff; if(ix>=0x7f800000) { /* erfc(nan)=nan */ /* erfc(+-inf)=0,2 */ return (float)(((u_int32_t)hx>>31)<<1)+one/x; } if(ix < 0x3f580000) { /* |x|<0.84375 */ if(ix < 0x33800000) /* |x|<2**-56 */ return one-x; z = x*x; r = pp0+z*(pp1+z*pp2); s = one+z*(qq1+z*(qq2+z*qq3)); y = r/s; if(hx < 0x3e800000) { /* x<1/4 */ return one-(x+x*y); } else { r = x*y; r += (x-half); return half - r ; } } if(ix < 0x3fa00000) { /* 0.84375 <= |x| < 1.25 */ s = fabsf(x)-one; P = pa0+s*(pa1+s*(pa2+s*pa3)); Q = one+s*(qa1+s*(qa2+s*(qa3+s*qa4))); if(hx>=0) { z = one-erx; return z - P/Q; } else { z = erx+P/Q; return one+z; } } if (ix < 0x41300000) { /* |x|<28 */ x = fabsf(x); s = one/(x*x); if(ix< 0x4036DB6D) { /* |x| < 1/.35 ~ 2.857143*/ R=ra0+s*(ra1+s*(ra2+s*ra3)); S=one+s*(sa1+s*(sa2+s*(sa3+s*sa4))); } else { /* |x| >= 1/.35 ~ 2.857143 */ if(hx<0&&ix>=0x40a00000) return two-tiny;/* x < -5 */ R=rb0+s*(rb1+s*(rb2+s*(rb3+s*rb4))); S=one+s*(sb1+s*(sb2+s*(sb3+s*sb4))); } SET_FLOAT_WORD(z,hx&0xffffe000); r = expf(-z*z-0.5625F)*expf((z-x)*(z+x)+R/S); if(hx>0) return r/x; else return two-r/x; } else { if(hx>0) return tiny*tiny; else return two-tiny; } } openlibm-0.5.0/src/s_exp2.c000066400000000000000000000340761266752446200155040ustar00rootroot00000000000000/*- * Copyright (c) 2005 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_exp2.c,v 1.7 2008/02/22 02:27:34 das Exp $"); #include #include #include "math_private.h" #define TBLBITS 8 #define TBLSIZE (1 << TBLBITS) static const double huge = 0x1p1000, redux = 0x1.8p52 / TBLSIZE, P1 = 0x1.62e42fefa39efp-1, P2 = 0x1.ebfbdff82c575p-3, P3 = 0x1.c6b08d704a0a6p-5, P4 = 0x1.3b2ab88f70400p-7, P5 = 0x1.5d88003875c74p-10; static volatile double twom1000 = 0x1p-1000; static const double tbl[TBLSIZE * 2] = { /* exp2(z + eps) eps */ 0x1.6a09e667f3d5dp-1, 0x1.9880p-44, 0x1.6b052fa751744p-1, 0x1.8000p-50, 0x1.6c012750bd9fep-1, -0x1.8780p-45, 0x1.6cfdcddd476bfp-1, 0x1.ec00p-46, 0x1.6dfb23c651a29p-1, -0x1.8000p-50, 0x1.6ef9298593ae3p-1, -0x1.c000p-52, 0x1.6ff7df9519386p-1, -0x1.fd80p-45, 0x1.70f7466f42da3p-1, -0x1.c880p-45, 0x1.71f75e8ec5fc3p-1, 0x1.3c00p-46, 0x1.72f8286eacf05p-1, -0x1.8300p-44, 0x1.73f9a48a58152p-1, -0x1.0c00p-47, 0x1.74fbd35d7ccfcp-1, 0x1.f880p-45, 0x1.75feb564267f1p-1, 0x1.3e00p-47, 0x1.77024b1ab6d48p-1, -0x1.7d00p-45, 0x1.780694fde5d38p-1, -0x1.d000p-50, 0x1.790b938ac1d00p-1, 0x1.3000p-49, 0x1.7a11473eb0178p-1, -0x1.d000p-49, 0x1.7b17b0976d060p-1, 0x1.0400p-45, 0x1.7c1ed0130c133p-1, 0x1.0000p-53, 0x1.7d26a62ff8636p-1, -0x1.6900p-45, 0x1.7e2f336cf4e3bp-1, -0x1.2e00p-47, 0x1.7f3878491c3e8p-1, -0x1.4580p-45, 0x1.80427543e1b4ep-1, 0x1.3000p-44, 0x1.814d2add1071ap-1, 0x1.f000p-47, 0x1.82589994ccd7ep-1, -0x1.1c00p-45, 0x1.8364c1eb942d0p-1, 0x1.9d00p-45, 0x1.8471a4623cab5p-1, 0x1.7100p-43, 0x1.857f4179f5bbcp-1, 0x1.2600p-45, 0x1.868d99b4491afp-1, -0x1.2c40p-44, 0x1.879cad931a395p-1, -0x1.3000p-45, 0x1.88ac7d98a65b8p-1, -0x1.a800p-45, 0x1.89bd0a4785800p-1, -0x1.d000p-49, 0x1.8ace5422aa223p-1, 0x1.3280p-44, 0x1.8be05bad619fap-1, 0x1.2b40p-43, 0x1.8cf3216b54383p-1, -0x1.ed00p-45, 0x1.8e06a5e08664cp-1, -0x1.0500p-45, 0x1.8f1ae99157807p-1, 0x1.8280p-45, 0x1.902fed0282c0ep-1, -0x1.cb00p-46, 0x1.9145b0b91ff96p-1, -0x1.5e00p-47, 0x1.925c353aa2ff9p-1, 0x1.5400p-48, 0x1.93737b0cdc64ap-1, 0x1.7200p-46, 0x1.948b82b5f98aep-1, -0x1.9000p-47, 0x1.95a44cbc852cbp-1, 0x1.5680p-45, 0x1.96bdd9a766f21p-1, -0x1.6d00p-44, 0x1.97d829fde4e2ap-1, -0x1.1000p-47, 0x1.98f33e47a23a3p-1, 0x1.d000p-45, 0x1.9a0f170ca0604p-1, -0x1.8a40p-44, 0x1.9b2bb4d53ff89p-1, 0x1.55c0p-44, 0x1.9c49182a3f15bp-1, 0x1.6b80p-45, 0x1.9d674194bb8c5p-1, -0x1.c000p-49, 0x1.9e86319e3238ep-1, 0x1.7d00p-46, 0x1.9fa5e8d07f302p-1, 0x1.6400p-46, 0x1.a0c667b5de54dp-1, -0x1.5000p-48, 0x1.a1e7aed8eb8f6p-1, 0x1.9e00p-47, 0x1.a309bec4a2e27p-1, 0x1.ad80p-45, 0x1.a42c980460a5dp-1, -0x1.af00p-46, 0x1.a5503b23e259bp-1, 0x1.b600p-47, 0x1.a674a8af46213p-1, 0x1.8880p-44, 0x1.a799e1330b3a7p-1, 0x1.1200p-46, 0x1.a8bfe53c12e8dp-1, 0x1.6c00p-47, 0x1.a9e6b5579fcd2p-1, -0x1.9b80p-45, 0x1.ab0e521356fb8p-1, 0x1.b700p-45, 0x1.ac36bbfd3f381p-1, 0x1.9000p-50, 0x1.ad5ff3a3c2780p-1, 0x1.4000p-49, 0x1.ae89f995ad2a3p-1, -0x1.c900p-45, 0x1.afb4ce622f367p-1, 0x1.6500p-46, 0x1.b0e07298db790p-1, 0x1.fd40p-45, 0x1.b20ce6c9a89a9p-1, 0x1.2700p-46, 0x1.b33a2b84f1a4bp-1, 0x1.d470p-43, 0x1.b468415b747e7p-1, -0x1.8380p-44, 0x1.b59728de5593ap-1, 0x1.8000p-54, 0x1.b6c6e29f1c56ap-1, 0x1.ad00p-47, 0x1.b7f76f2fb5e50p-1, 0x1.e800p-50, 0x1.b928cf22749b2p-1, -0x1.4c00p-47, 0x1.ba5b030a10603p-1, -0x1.d700p-47, 0x1.bb8e0b79a6f66p-1, 0x1.d900p-47, 0x1.bcc1e904bc1ffp-1, 0x1.2a00p-47, 0x1.bdf69c3f3a16fp-1, -0x1.f780p-46, 0x1.bf2c25bd71db8p-1, -0x1.0a00p-46, 0x1.c06286141b2e9p-1, -0x1.1400p-46, 0x1.c199bdd8552e0p-1, 0x1.be00p-47, 0x1.c2d1cd9fa64eep-1, -0x1.9400p-47, 0x1.c40ab5fffd02fp-1, -0x1.ed00p-47, 0x1.c544778fafd15p-1, 0x1.9660p-44, 0x1.c67f12e57d0cbp-1, -0x1.a100p-46, 0x1.c7ba88988c1b6p-1, -0x1.8458p-42, 0x1.c8f6d9406e733p-1, -0x1.a480p-46, 0x1.ca3405751c4dfp-1, 0x1.b000p-51, 0x1.cb720dcef9094p-1, 0x1.1400p-47, 0x1.ccb0f2e6d1689p-1, 0x1.0200p-48, 0x1.cdf0b555dc412p-1, 0x1.3600p-48, 0x1.cf3155b5bab3bp-1, -0x1.6900p-47, 0x1.d072d4a0789bcp-1, 0x1.9a00p-47, 0x1.d1b532b08c8fap-1, -0x1.5e00p-46, 0x1.d2f87080d8a85p-1, 0x1.d280p-46, 0x1.d43c8eacaa203p-1, 0x1.1a00p-47, 0x1.d5818dcfba491p-1, 0x1.f000p-50, 0x1.d6c76e862e6a1p-1, -0x1.3a00p-47, 0x1.d80e316c9834ep-1, -0x1.cd80p-47, 0x1.d955d71ff6090p-1, 0x1.4c00p-48, 0x1.da9e603db32aep-1, 0x1.f900p-48, 0x1.dbe7cd63a8325p-1, 0x1.9800p-49, 0x1.dd321f301b445p-1, -0x1.5200p-48, 0x1.de7d5641c05bfp-1, -0x1.d700p-46, 0x1.dfc97337b9aecp-1, -0x1.6140p-46, 0x1.e11676b197d5ep-1, 0x1.b480p-47, 0x1.e264614f5a3e7p-1, 0x1.0ce0p-43, 0x1.e3b333b16ee5cp-1, 0x1.c680p-47, 0x1.e502ee78b3fb4p-1, -0x1.9300p-47, 0x1.e653924676d68p-1, -0x1.5000p-49, 0x1.e7a51fbc74c44p-1, -0x1.7f80p-47, 0x1.e8f7977cdb726p-1, -0x1.3700p-48, 0x1.ea4afa2a490e8p-1, 0x1.5d00p-49, 0x1.eb9f4867ccae4p-1, 0x1.61a0p-46, 0x1.ecf482d8e680dp-1, 0x1.5500p-48, 0x1.ee4aaa2188514p-1, 0x1.6400p-51, 0x1.efa1bee615a13p-1, -0x1.e800p-49, 0x1.f0f9c1cb64106p-1, -0x1.a880p-48, 0x1.f252b376bb963p-1, -0x1.c900p-45, 0x1.f3ac948dd7275p-1, 0x1.a000p-53, 0x1.f50765b6e4524p-1, -0x1.4f00p-48, 0x1.f6632798844fdp-1, 0x1.a800p-51, 0x1.f7bfdad9cbe38p-1, 0x1.abc0p-48, 0x1.f91d802243c82p-1, -0x1.4600p-50, 0x1.fa7c1819e908ep-1, -0x1.b0c0p-47, 0x1.fbdba3692d511p-1, -0x1.0e00p-51, 0x1.fd3c22b8f7194p-1, -0x1.0de8p-46, 0x1.fe9d96b2a23eep-1, 0x1.e430p-49, 0x1.0000000000000p+0, 0x0.0000p+0, 0x1.00b1afa5abcbep+0, -0x1.3400p-52, 0x1.0163da9fb3303p+0, -0x1.2170p-46, 0x1.02168143b0282p+0, 0x1.a400p-52, 0x1.02c9a3e77806cp+0, 0x1.f980p-49, 0x1.037d42e11bbcap+0, -0x1.7400p-51, 0x1.04315e86e7f89p+0, 0x1.8300p-50, 0x1.04e5f72f65467p+0, -0x1.a3f0p-46, 0x1.059b0d315855ap+0, -0x1.2840p-47, 0x1.0650a0e3c1f95p+0, 0x1.1600p-48, 0x1.0706b29ddf71ap+0, 0x1.5240p-46, 0x1.07bd42b72a82dp+0, -0x1.9a00p-49, 0x1.0874518759bd0p+0, 0x1.6400p-49, 0x1.092bdf66607c8p+0, -0x1.0780p-47, 0x1.09e3ecac6f383p+0, -0x1.8000p-54, 0x1.0a9c79b1f3930p+0, 0x1.fa00p-48, 0x1.0b5586cf988fcp+0, -0x1.ac80p-48, 0x1.0c0f145e46c8ap+0, 0x1.9c00p-50, 0x1.0cc922b724816p+0, 0x1.5200p-47, 0x1.0d83b23395dd8p+0, -0x1.ad00p-48, 0x1.0e3ec32d3d1f3p+0, 0x1.bac0p-46, 0x1.0efa55fdfa9a6p+0, -0x1.4e80p-47, 0x1.0fb66affed2f0p+0, -0x1.d300p-47, 0x1.1073028d7234bp+0, 0x1.1500p-48, 0x1.11301d0125b5bp+0, 0x1.c000p-49, 0x1.11edbab5e2af9p+0, 0x1.6bc0p-46, 0x1.12abdc06c31d5p+0, 0x1.8400p-49, 0x1.136a814f2047dp+0, -0x1.ed00p-47, 0x1.1429aaea92de9p+0, 0x1.8e00p-49, 0x1.14e95934f3138p+0, 0x1.b400p-49, 0x1.15a98c8a58e71p+0, 0x1.5300p-47, 0x1.166a45471c3dfp+0, 0x1.3380p-47, 0x1.172b83c7d5211p+0, 0x1.8d40p-45, 0x1.17ed48695bb9fp+0, -0x1.5d00p-47, 0x1.18af9388c8d93p+0, -0x1.c880p-46, 0x1.1972658375d66p+0, 0x1.1f00p-46, 0x1.1a35beb6fcba7p+0, 0x1.0480p-46, 0x1.1af99f81387e3p+0, -0x1.7390p-43, 0x1.1bbe084045d54p+0, 0x1.4e40p-45, 0x1.1c82f95281c43p+0, -0x1.a200p-47, 0x1.1d4873168b9b2p+0, 0x1.3800p-49, 0x1.1e0e75eb44031p+0, 0x1.ac00p-49, 0x1.1ed5022fcd938p+0, 0x1.1900p-47, 0x1.1f9c18438cdf7p+0, -0x1.b780p-46, 0x1.2063b88628d8fp+0, 0x1.d940p-45, 0x1.212be3578a81ep+0, 0x1.8000p-50, 0x1.21f49917ddd41p+0, 0x1.b340p-45, 0x1.22bdda2791323p+0, 0x1.9f80p-46, 0x1.2387a6e7561e7p+0, -0x1.9c80p-46, 0x1.2451ffb821427p+0, 0x1.2300p-47, 0x1.251ce4fb2a602p+0, -0x1.3480p-46, 0x1.25e85711eceb0p+0, 0x1.2700p-46, 0x1.26b4565e27d16p+0, 0x1.1d00p-46, 0x1.2780e341de00fp+0, 0x1.1ee0p-44, 0x1.284dfe1f5633ep+0, -0x1.4c00p-46, 0x1.291ba7591bb30p+0, -0x1.3d80p-46, 0x1.29e9df51fdf09p+0, 0x1.8b00p-47, 0x1.2ab8a66d10e9bp+0, -0x1.27c0p-45, 0x1.2b87fd0dada3ap+0, 0x1.a340p-45, 0x1.2c57e39771af9p+0, -0x1.0800p-46, 0x1.2d285a6e402d9p+0, -0x1.ed00p-47, 0x1.2df961f641579p+0, -0x1.4200p-48, 0x1.2ecafa93e2ecfp+0, -0x1.4980p-45, 0x1.2f9d24abd8822p+0, -0x1.6300p-46, 0x1.306fe0a31b625p+0, -0x1.2360p-44, 0x1.31432edeea50bp+0, -0x1.0df8p-40, 0x1.32170fc4cd7b8p+0, -0x1.2480p-45, 0x1.32eb83ba8e9a2p+0, -0x1.5980p-45, 0x1.33c08b2641766p+0, 0x1.ed00p-46, 0x1.3496266e3fa27p+0, -0x1.c000p-50, 0x1.356c55f929f0fp+0, -0x1.0d80p-44, 0x1.36431a2de88b9p+0, 0x1.2c80p-45, 0x1.371a7373aaa39p+0, 0x1.0600p-45, 0x1.37f26231e74fep+0, -0x1.6600p-46, 0x1.38cae6d05d838p+0, -0x1.ae00p-47, 0x1.39a401b713ec3p+0, -0x1.4720p-43, 0x1.3a7db34e5a020p+0, 0x1.8200p-47, 0x1.3b57fbfec6e95p+0, 0x1.e800p-44, 0x1.3c32dc313a8f2p+0, 0x1.f800p-49, 0x1.3d0e544ede122p+0, -0x1.7a00p-46, 0x1.3dea64c1234bbp+0, 0x1.6300p-45, 0x1.3ec70df1c4eccp+0, -0x1.8a60p-43, 0x1.3fa4504ac7e8cp+0, -0x1.cdc0p-44, 0x1.40822c367a0bbp+0, 0x1.5b80p-45, 0x1.4160a21f72e95p+0, 0x1.ec00p-46, 0x1.423fb27094646p+0, -0x1.3600p-46, 0x1.431f5d950a920p+0, 0x1.3980p-45, 0x1.43ffa3f84b9ebp+0, 0x1.a000p-48, 0x1.44e0860618919p+0, -0x1.6c00p-48, 0x1.45c2042a7d201p+0, -0x1.bc00p-47, 0x1.46a41ed1d0016p+0, -0x1.2800p-46, 0x1.4786d668b3326p+0, 0x1.0e00p-44, 0x1.486a2b5c13c00p+0, -0x1.d400p-45, 0x1.494e1e192af04p+0, 0x1.c200p-47, 0x1.4a32af0d7d372p+0, -0x1.e500p-46, 0x1.4b17dea6db801p+0, 0x1.7800p-47, 0x1.4bfdad53629e1p+0, -0x1.3800p-46, 0x1.4ce41b817c132p+0, 0x1.0800p-47, 0x1.4dcb299fddddbp+0, 0x1.c700p-45, 0x1.4eb2d81d8ab96p+0, -0x1.ce00p-46, 0x1.4f9b2769d2d02p+0, 0x1.9200p-46, 0x1.508417f4531c1p+0, -0x1.8c00p-47, 0x1.516daa2cf662ap+0, -0x1.a000p-48, 0x1.5257de83f51eap+0, 0x1.a080p-43, 0x1.5342b569d4edap+0, -0x1.6d80p-45, 0x1.542e2f4f6ac1ap+0, -0x1.2440p-44, 0x1.551a4ca5d94dbp+0, 0x1.83c0p-43, 0x1.56070dde9116bp+0, 0x1.4b00p-45, 0x1.56f4736b529dep+0, 0x1.15a0p-43, 0x1.57e27dbe2c40ep+0, -0x1.9e00p-45, 0x1.58d12d497c76fp+0, -0x1.3080p-45, 0x1.59c0827ff0b4cp+0, 0x1.dec0p-43, 0x1.5ab07dd485427p+0, -0x1.4000p-51, 0x1.5ba11fba87af4p+0, 0x1.0080p-44, 0x1.5c9268a59460bp+0, -0x1.6c80p-45, 0x1.5d84590998e3fp+0, 0x1.69a0p-43, 0x1.5e76f15ad20e1p+0, -0x1.b400p-46, 0x1.5f6a320dcebcap+0, 0x1.7700p-46, 0x1.605e1b976dcb8p+0, 0x1.6f80p-45, 0x1.6152ae6cdf715p+0, 0x1.1000p-47, 0x1.6247eb03a5531p+0, -0x1.5d00p-46, 0x1.633dd1d1929b5p+0, -0x1.2d00p-46, 0x1.6434634ccc313p+0, -0x1.a800p-49, 0x1.652b9febc8efap+0, -0x1.8600p-45, 0x1.6623882553397p+0, 0x1.1fe0p-40, 0x1.671c1c708328ep+0, -0x1.7200p-44, 0x1.68155d44ca97ep+0, 0x1.6800p-49, 0x1.690f4b19e9471p+0, -0x1.9780p-45, }; /* * exp2(x): compute the base 2 exponential of x * * Accuracy: Peak error < 0.503 ulp for normalized results. * * Method: (accurate tables) * * Reduce x: * x = 2**k + y, for integer k and |y| <= 1/2. * Thus we have exp2(x) = 2**k * exp2(y). * * Reduce y: * y = i/TBLSIZE + z - eps[i] for integer i near y * TBLSIZE. * Thus we have exp2(y) = exp2(i/TBLSIZE) * exp2(z - eps[i]), * with |z - eps[i]| <= 2**-9 + 2**-39 for the table used. * * We compute exp2(i/TBLSIZE) via table lookup and exp2(z - eps[i]) via * a degree-5 minimax polynomial with maximum error under 1.3 * 2**-61. * The values in exp2t[] and eps[] are chosen such that * exp2t[i] = exp2(i/TBLSIZE + eps[i]), and eps[i] is a small offset such * that exp2t[i] is accurate to 2**-64. * * Note that the range of i is +-TBLSIZE/2, so we actually index the tables * by i0 = i + TBLSIZE/2. For cache efficiency, exp2t[] and eps[] are * virtual tables, interleaved in the real table tbl[]. * * This method is due to Gal, with many details due to Gal and Bachelis: * * Gal, S. and Bachelis, B. An Accurate Elementary Mathematical Library * for the IEEE Floating Point Standard. TOMS 17(1), 26-46 (1991). */ DLLEXPORT double exp2(double x) { double r, t, twopk, twopkp1000, z; u_int32_t hx, ix, lx, i0; int k; /* Filter out exceptional cases. */ GET_HIGH_WORD(hx,x); ix = hx & 0x7fffffff; /* high word of |x| */ if(ix >= 0x40900000) { /* |x| >= 1024 */ if(ix >= 0x7ff00000) { GET_LOW_WORD(lx,x); if(((ix & 0xfffff) | lx) != 0 || (hx & 0x80000000) == 0) return (x + x); /* x is NaN or +Inf */ else return (0.0); /* x is -Inf */ } if(x >= 0x1.0p10) return (huge * huge); /* overflow */ if(x <= -0x1.0ccp10) return (twom1000 * twom1000); /* underflow */ } else if (ix < 0x3c900000) { /* |x| < 0x1p-54 */ return (1.0 + x); } /* Reduce x, computing z, i0, and k. */ STRICT_ASSIGN(double, t, x + redux); GET_LOW_WORD(i0, t); i0 += TBLSIZE / 2; k = (i0 >> TBLBITS) << 20; i0 = (i0 & (TBLSIZE - 1)) << 1; t -= redux; z = x - t; /* Compute r = exp2(y) = exp2t[i0] * p(z - eps[i]). */ t = tbl[i0]; /* exp2t[i0] */ z -= tbl[i0 + 1]; /* eps[i0] */ if (k >= -(1021 << 20)) INSERT_WORDS(twopk, 0x3ff00000 + k, 0); else INSERT_WORDS(twopkp1000, 0x3ff00000 + k + (1000 << 20), 0); r = t + t * z * (P1 + z * (P2 + z * (P3 + z * (P4 + z * P5)))); /* Scale by 2**(k>>20). */ if(k >= -(1021 << 20)) { if (k == 1024 << 20) return (r * 2.0 * 0x1p1023); return (r * twopk); } else { return (r * twopkp1000 * twom1000); } } #if (LDBL_MANT_DIG == 53) __weak_reference(exp2, exp2l); #endif openlibm-0.5.0/src/s_exp2f.c000066400000000000000000000102621266752446200156410ustar00rootroot00000000000000/*- * Copyright (c) 2005 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_exp2f.c,v 1.9 2008/02/22 02:27:34 das Exp $"); #include #include #include "math_private.h" #define TBLBITS 4 #define TBLSIZE (1 << TBLBITS) static const float huge = 0x1p100f, redux = 0x1.8p23f / TBLSIZE, P1 = 0x1.62e430p-1f, P2 = 0x1.ebfbe0p-3f, P3 = 0x1.c6b348p-5f, P4 = 0x1.3b2c9cp-7f; static volatile float twom100 = 0x1p-100f; static const double exp2ft[TBLSIZE] = { 0x1.6a09e667f3bcdp-1, 0x1.7a11473eb0187p-1, 0x1.8ace5422aa0dbp-1, 0x1.9c49182a3f090p-1, 0x1.ae89f995ad3adp-1, 0x1.c199bdd85529cp-1, 0x1.d5818dcfba487p-1, 0x1.ea4afa2a490dap-1, 0x1.0000000000000p+0, 0x1.0b5586cf9890fp+0, 0x1.172b83c7d517bp+0, 0x1.2387a6e756238p+0, 0x1.306fe0a31b715p+0, 0x1.3dea64c123422p+0, 0x1.4bfdad5362a27p+0, 0x1.5ab07dd485429p+0, }; /* * exp2f(x): compute the base 2 exponential of x * * Accuracy: Peak error < 0.501 ulp; location of peak: -0.030110927. * * Method: (equally-spaced tables) * * Reduce x: * x = 2**k + y, for integer k and |y| <= 1/2. * Thus we have exp2f(x) = 2**k * exp2(y). * * Reduce y: * y = i/TBLSIZE + z for integer i near y * TBLSIZE. * Thus we have exp2(y) = exp2(i/TBLSIZE) * exp2(z), * with |z| <= 2**-(TBLSIZE+1). * * We compute exp2(i/TBLSIZE) via table lookup and exp2(z) via a * degree-4 minimax polynomial with maximum error under 1.4 * 2**-33. * Using double precision for everything except the reduction makes * roundoff error insignificant and simplifies the scaling step. * * This method is due to Tang, but I do not use his suggested parameters: * * Tang, P. Table-driven Implementation of the Exponential Function * in IEEE Floating-Point Arithmetic. TOMS 15(2), 144-157 (1989). */ DLLEXPORT float exp2f(float x) { double tv, twopk, u, z; float t; u_int32_t hx, ix, i0; int32_t k; /* Filter out exceptional cases. */ GET_FLOAT_WORD(hx, x); ix = hx & 0x7fffffff; /* high word of |x| */ if(ix >= 0x43000000) { /* |x| >= 128 */ if(ix >= 0x7f800000) { if ((ix & 0x7fffff) != 0 || (hx & 0x80000000) == 0) return (x + x); /* x is NaN or +Inf */ else return (0.0); /* x is -Inf */ } if(x >= 0x1.0p7f) return (huge * huge); /* overflow */ if(x <= -0x1.2cp7f) return (twom100 * twom100); /* underflow */ } else if (ix <= 0x33000000) { /* |x| <= 0x1p-25 */ return (1.0f + x); } /* Reduce x, computing z, i0, and k. */ STRICT_ASSIGN(float, t, x + redux); GET_FLOAT_WORD(i0, t); i0 += TBLSIZE / 2; k = (i0 >> TBLBITS) << 20; i0 &= TBLSIZE - 1; t -= redux; z = x - t; INSERT_WORDS(twopk, 0x3ff00000 + k, 0); /* Compute r = exp2(y) = exp2ft[i0] * p(z). */ tv = exp2ft[i0]; u = tv * z; tv = tv + u * (P1 + z * P2) + u * (z * z) * (P3 + z * P4); /* Scale by 2**(k>>20). */ return (tv * twopk); } openlibm-0.5.0/src/s_expm1.c000066400000000000000000000162541266752446200156560ustar00rootroot00000000000000/* @(#)s_expm1.c 5.1 93/09/24 */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_expm1.c,v 1.12 2011/10/21 06:26:38 das Exp $"); /* expm1(x) * Returns exp(x)-1, the exponential of x minus 1. * * Method * 1. Argument reduction: * Given x, find r and integer k such that * * x = k*ln2 + r, |r| <= 0.5*ln2 ~ 0.34658 * * Here a correction term c will be computed to compensate * the error in r when rounded to a floating-point number. * * 2. Approximating expm1(r) by a special rational function on * the interval [0,0.34658]: * Since * r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 - r^4/360 + ... * we define R1(r*r) by * r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 * R1(r*r) * That is, * R1(r**2) = 6/r *((exp(r)+1)/(exp(r)-1) - 2/r) * = 6/r * ( 1 + 2.0*(1/(exp(r)-1) - 1/r)) * = 1 - r^2/60 + r^4/2520 - r^6/100800 + ... * We use a special Reme algorithm on [0,0.347] to generate * a polynomial of degree 5 in r*r to approximate R1. The * maximum error of this polynomial approximation is bounded * by 2**-61. In other words, * R1(z) ~ 1.0 + Q1*z + Q2*z**2 + Q3*z**3 + Q4*z**4 + Q5*z**5 * where Q1 = -1.6666666666666567384E-2, * Q2 = 3.9682539681370365873E-4, * Q3 = -9.9206344733435987357E-6, * Q4 = 2.5051361420808517002E-7, * Q5 = -6.2843505682382617102E-9; * z = r*r, * with error bounded by * | 5 | -61 * | 1.0+Q1*z+...+Q5*z - R1(z) | <= 2 * | | * * expm1(r) = exp(r)-1 is then computed by the following * specific way which minimize the accumulation rounding error: * 2 3 * r r [ 3 - (R1 + R1*r/2) ] * expm1(r) = r + --- + --- * [--------------------] * 2 2 [ 6 - r*(3 - R1*r/2) ] * * To compensate the error in the argument reduction, we use * expm1(r+c) = expm1(r) + c + expm1(r)*c * ~ expm1(r) + c + r*c * Thus c+r*c will be added in as the correction terms for * expm1(r+c). Now rearrange the term to avoid optimization * screw up: * ( 2 2 ) * ({ ( r [ R1 - (3 - R1*r/2) ] ) } r ) * expm1(r+c)~r - ({r*(--- * [--------------------]-c)-c} - --- ) * ({ ( 2 [ 6 - r*(3 - R1*r/2) ] ) } 2 ) * ( ) * * = r - E * 3. Scale back to obtain expm1(x): * From step 1, we have * expm1(x) = either 2^k*[expm1(r)+1] - 1 * = or 2^k*[expm1(r) + (1-2^-k)] * 4. Implementation notes: * (A). To save one multiplication, we scale the coefficient Qi * to Qi*2^i, and replace z by (x^2)/2. * (B). To achieve maximum accuracy, we compute expm1(x) by * (i) if x < -56*ln2, return -1.0, (raise inexact if x!=inf) * (ii) if k=0, return r-E * (iii) if k=-1, return 0.5*(r-E)-0.5 * (iv) if k=1 if r < -0.25, return 2*((r+0.5)- E) * else return 1.0+2.0*(r-E); * (v) if (k<-2||k>56) return 2^k(1-(E-r)) - 1 (or exp(x)-1) * (vi) if k <= 20, return 2^k((1-2^-k)-(E-r)), else * (vii) return 2^k(1-((E+2^-k)-r)) * * Special cases: * expm1(INF) is INF, expm1(NaN) is NaN; * expm1(-INF) is -1, and * for finite argument, only expm1(0)=0 is exact. * * Accuracy: * according to an error analysis, the error is always less than * 1 ulp (unit in the last place). * * Misc. info. * For IEEE double * if x > 7.09782712893383973096e+02 then expm1(x) overflow * * Constants: * The hexadecimal values are the intended ones for the following * constants. The decimal values may be used, provided that the * compiler will convert from decimal to binary accurately enough * to produce the hexadecimal values shown. */ #include #include #include "math_private.h" static const double one = 1.0, huge = 1.0e+300, tiny = 1.0e-300, o_threshold = 7.09782712893383973096e+02,/* 0x40862E42, 0xFEFA39EF */ ln2_hi = 6.93147180369123816490e-01,/* 0x3fe62e42, 0xfee00000 */ ln2_lo = 1.90821492927058770002e-10,/* 0x3dea39ef, 0x35793c76 */ invln2 = 1.44269504088896338700e+00,/* 0x3ff71547, 0x652b82fe */ /* Scaled Q's: Qn_here = 2**n * Qn_above, for R(2*z) where z = hxs = x*x/2: */ Q1 = -3.33333333333331316428e-02, /* BFA11111 111110F4 */ Q2 = 1.58730158725481460165e-03, /* 3F5A01A0 19FE5585 */ Q3 = -7.93650757867487942473e-05, /* BF14CE19 9EAADBB7 */ Q4 = 4.00821782732936239552e-06, /* 3ED0CFCA 86E65239 */ Q5 = -2.01099218183624371326e-07; /* BE8AFDB7 6E09C32D */ DLLEXPORT double expm1(double x) { double y,hi,lo,c,t,e,hxs,hfx,r1,twopk; int32_t k,xsb; u_int32_t hx; GET_HIGH_WORD(hx,x); xsb = hx&0x80000000; /* sign bit of x */ hx &= 0x7fffffff; /* high word of |x| */ /* filter out huge and non-finite argument */ if(hx >= 0x4043687A) { /* if |x|>=56*ln2 */ if(hx >= 0x40862E42) { /* if |x|>=709.78... */ if(hx>=0x7ff00000) { u_int32_t low; GET_LOW_WORD(low,x); if(((hx&0xfffff)|low)!=0) return x+x; /* NaN */ else return (xsb==0)? x:-1.0;/* exp(+-inf)={inf,-1} */ } if(x > o_threshold) return huge*huge; /* overflow */ } if(xsb!=0) { /* x < -56*ln2, return -1.0 with inexact */ if(x+tiny<0.0) /* raise inexact */ return tiny-one; /* return -1 */ } } /* argument reduction */ if(hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */ if(hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */ if(xsb==0) {hi = x - ln2_hi; lo = ln2_lo; k = 1;} else {hi = x + ln2_hi; lo = -ln2_lo; k = -1;} } else { k = invln2*x+((xsb==0)?0.5:-0.5); t = k; hi = x - t*ln2_hi; /* t*ln2_hi is exact here */ lo = t*ln2_lo; } STRICT_ASSIGN(double, x, hi - lo); c = (hi-x)-lo; } else if(hx < 0x3c900000) { /* when |x|<2**-54, return x */ t = huge+x; /* return x with inexact flags when x!=0 */ return x - (t-(huge+x)); } else k = 0; /* x is now in primary range */ hfx = 0.5*x; hxs = x*hfx; r1 = one+hxs*(Q1+hxs*(Q2+hxs*(Q3+hxs*(Q4+hxs*Q5)))); t = 3.0-r1*hfx; e = hxs*((r1-t)/(6.0 - x*t)); if(k==0) return x - (x*e-hxs); /* c is 0 */ else { INSERT_WORDS(twopk,0x3ff00000+(k<<20),0); /* 2^k */ e = (x*(e-c)-c); e -= hxs; if(k== -1) return 0.5*(x-e)-0.5; if(k==1) { if(x < -0.25) return -2.0*(e-(x+0.5)); else return one+2.0*(x-e); } if (k <= -2 || k>56) { /* suffice to return exp(x)-1 */ y = one-(e-x); if (k == 1024) y = y*2.0*0x1p1023; else y = y*twopk; return y-one; } t = one; if(k<20) { SET_HIGH_WORD(t,0x3ff00000 - (0x200000>>k)); /* t=1-2^-k */ y = t-(e-x); y = y*twopk; } else { SET_HIGH_WORD(t,((0x3ff-k)<<20)); /* 2^-k */ y = x-(e+t); y += one; y = y*twopk; } } return y; } openlibm-0.5.0/src/s_expm1f.c000066400000000000000000000067401266752446200160230ustar00rootroot00000000000000/* s_expm1f.c -- float version of s_expm1.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_expm1f.c,v 1.12 2011/10/21 06:26:38 das Exp $"); #include #include #include "math_private.h" static const float one = 1.0, huge = 1.0e+30, tiny = 1.0e-30, o_threshold = 8.8721679688e+01,/* 0x42b17180 */ ln2_hi = 6.9313812256e-01,/* 0x3f317180 */ ln2_lo = 9.0580006145e-06,/* 0x3717f7d1 */ invln2 = 1.4426950216e+00,/* 0x3fb8aa3b */ /* * Domain [-0.34568, 0.34568], range ~[-6.694e-10, 6.696e-10]: * |6 / x * (1 + 2 * (1 / (exp(x) - 1) - 1 / x)) - q(x)| < 2**-30.04 * Scaled coefficients: Qn_here = 2**n * Qn_for_q (see s_expm1.c): */ Q1 = -3.3333212137e-2, /* -0x888868.0p-28 */ Q2 = 1.5807170421e-3; /* 0xcf3010.0p-33 */ DLLEXPORT float expm1f(float x) { float y,hi,lo,c,t,e,hxs,hfx,r1,twopk; int32_t k,xsb; u_int32_t hx; GET_FLOAT_WORD(hx,x); xsb = hx&0x80000000; /* sign bit of x */ hx &= 0x7fffffff; /* high word of |x| */ /* filter out huge and non-finite argument */ if(hx >= 0x4195b844) { /* if |x|>=27*ln2 */ if(hx >= 0x42b17218) { /* if |x|>=88.721... */ if(hx>0x7f800000) return x+x; /* NaN */ if(hx==0x7f800000) return (xsb==0)? x:-1.0;/* exp(+-inf)={inf,-1} */ if(x > o_threshold) return huge*huge; /* overflow */ } if(xsb!=0) { /* x < -27*ln2, return -1.0 with inexact */ if(x+tiny<(float)0.0) /* raise inexact */ return tiny-one; /* return -1 */ } } /* argument reduction */ if(hx > 0x3eb17218) { /* if |x| > 0.5 ln2 */ if(hx < 0x3F851592) { /* and |x| < 1.5 ln2 */ if(xsb==0) {hi = x - ln2_hi; lo = ln2_lo; k = 1;} else {hi = x + ln2_hi; lo = -ln2_lo; k = -1;} } else { k = invln2*x+((xsb==0)?(float)0.5:(float)-0.5); t = k; hi = x - t*ln2_hi; /* t*ln2_hi is exact here */ lo = t*ln2_lo; } STRICT_ASSIGN(float, x, hi - lo); c = (hi-x)-lo; } else if(hx < 0x33000000) { /* when |x|<2**-25, return x */ t = huge+x; /* return x with inexact flags when x!=0 */ return x - (t-(huge+x)); } else k = 0; /* x is now in primary range */ hfx = (float)0.5*x; hxs = x*hfx; r1 = one+hxs*(Q1+hxs*Q2); t = (float)3.0-r1*hfx; e = hxs*((r1-t)/((float)6.0 - x*t)); if(k==0) return x - (x*e-hxs); /* c is 0 */ else { SET_FLOAT_WORD(twopk,0x3f800000+(k<<23)); /* 2^k */ e = (x*(e-c)-c); e -= hxs; if(k== -1) return (float)0.5*(x-e)-(float)0.5; if(k==1) { if(x < (float)-0.25) return -(float)2.0*(e-(x+(float)0.5)); else return one+(float)2.0*(x-e); } if (k <= -2 || k>56) { /* suffice to return exp(x)-1 */ y = one-(e-x); if (k == 128) y = y*2.0F*0x1p127F; else y = y*twopk; return y-one; } t = one; if(k<23) { SET_FLOAT_WORD(t,0x3f800000 - (0x1000000>>k)); /* t=1-2^-k */ y = t-(e-x); y = y*twopk; } else { SET_FLOAT_WORD(t,((0x7f-k)<<23)); /* 2^-k */ y = x-(e+t); y += one; y = y*twopk; } } return y; } openlibm-0.5.0/src/s_fabs.c000066400000000000000000000012121266752446200155230ustar00rootroot00000000000000/* @(#)s_fabs.c 5.1 93/09/24 */ /* * ==================================================== * 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. * ==================================================== */ /* * fabs(x) returns the absolute value of x. */ #include #include "math_private.h" DLLEXPORT double fabs(double x) { u_int32_t high; GET_HIGH_WORD(high,x); SET_HIGH_WORD(x,high&0x7fffffff); return x; } openlibm-0.5.0/src/s_fabsf.c000066400000000000000000000015251266752446200157000ustar00rootroot00000000000000/* s_fabsf.c -- float version of s_fabs.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_fabsf.c,v 1.8 2008/02/22 02:30:35 das Exp $"); /* * fabsf(x) returns the absolute value of x. */ #include #include "math_private.h" DLLEXPORT float fabsf(float x) { u_int32_t ix; GET_FLOAT_WORD(ix,x); SET_FLOAT_WORD(x,ix&0x7fffffff); return x; } openlibm-0.5.0/src/s_fabsl.c000066400000000000000000000033721266752446200157100ustar00rootroot00000000000000/*- * Copyright (c) 2003 Dag-Erling Coïdan Smørgrav * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer * in this position and unchanged. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/lib/msun/src/s_fabsl.c,v 1.2 2003/10/25 19:53:28 des Exp $ */ #include #include "math_private.h" #include "fpmath.h" DLLEXPORT long double fabsl(long double x) { union IEEEl2bits u; u.e = x; u.bits.sign = 0; return (u.e); } openlibm-0.5.0/src/s_fdim.c000066400000000000000000000034061266752446200155360ustar00rootroot00000000000000/*- * Copyright (c) 2004 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_fdim.c,v 1.1 2004/06/30 07:04:01 das Exp $"); #include #include "math_private.h" #define DECL(type, fn) \ DLLEXPORT type \ fn(type x, type y) \ { \ \ if (isnan(x)) \ return (x); \ if (isnan(y)) \ return (y); \ return (x > y ? x - y : 0.0); \ } DECL(double, fdim) DECL(float, fdimf) DECL(long double, fdiml) openlibm-0.5.0/src/s_floor.c000066400000000000000000000035131266752446200157370ustar00rootroot00000000000000/* @(#)s_floor.c 5.1 93/09/24 */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_floor.c,v 1.11 2008/02/15 07:01:40 bde Exp $"); /* * floor(x) * Return x rounded toward -inf to integral value * Method: * Bit twiddling. * Exception: * Inexact flag raised if x not equal to floor(x). */ #include #include #include "math_private.h" static const double huge = 1.0e300; DLLEXPORT double floor(double x) { int32_t i0,i1,j0; u_int32_t i,j; EXTRACT_WORDS(i0,i1,x); j0 = ((i0>>20)&0x7ff)-0x3ff; if(j0<20) { if(j0<0) { /* raise inexact if x != 0 */ if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */ if(i0>=0) {i0=i1=0;} else if(((i0&0x7fffffff)|i1)!=0) { i0=0xbff00000;i1=0;} } } else { i = (0x000fffff)>>j0; if(((i0&i)|i1)==0) return x; /* x is integral */ if(huge+x>0.0) { /* raise inexact flag */ if(i0<0) i0 += (0x00100000)>>j0; i0 &= (~i); i1=0; } } } else if (j0>51) { if(j0==0x400) return x+x; /* inf or NaN */ else return x; /* x is integral */ } else { i = ((u_int32_t)(0xffffffff))>>(j0-20); if((i1&i)==0) return x; /* x is integral */ if(huge+x>0.0) { /* raise inexact flag */ if(i0<0) { if(j0==20) i0+=1; else { j = i1+(1<<(52-j0)); if(j #include "math_private.h" static const float huge = 1.0e30; DLLEXPORT float floorf(float x) { int32_t i0,j0; u_int32_t i; GET_FLOAT_WORD(i0,x); j0 = ((i0>>23)&0xff)-0x7f; if(j0<23) { if(j0<0) { /* raise inexact if x != 0 */ if(huge+x>(float)0.0) {/* return 0*sign(x) if |x|<1 */ if(i0>=0) {i0=0;} else if((i0&0x7fffffff)!=0) { i0=0xbf800000;} } } else { i = (0x007fffff)>>j0; if((i0&i)==0) return x; /* x is integral */ if(huge+x>(float)0.0) { /* raise inexact flag */ if(i0<0) i0 += (0x00800000)>>j0; i0 &= (~i); } } } else { if(j0==0x80) return x+x; /* inf or NaN */ else return x; /* x is integral */ } SET_FLOAT_WORD(x,i0); return x; } openlibm-0.5.0/src/s_floorl.c000066400000000000000000000047671266752446200161270ustar00rootroot00000000000000/* * ==================================================== * 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. * ==================================================== * * From: @(#)s_floor.c 5.1 93/09/24 */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_floorl.c,v 1.8 2008/02/14 15:10:34 bde Exp $"); /* * floorl(x) * Return x rounded toward -inf to integral value * Method: * Bit twiddling. * Exception: * Inexact flag raised if x not equal to floorl(x). */ #include #include #include #include "fpmath.h" #include "math_private.h" #ifdef LDBL_IMPLICIT_NBIT #define MANH_SIZE (LDBL_MANH_SIZE + 1) #define INC_MANH(u, c) do { \ uint64_t o = u.bits.manh; \ u.bits.manh += (c); \ if (u.bits.manh < o) \ u.bits.exp++; \ } while (0) #else #define MANH_SIZE LDBL_MANH_SIZE #define INC_MANH(u, c) do { \ uint64_t o = u.bits.manh; \ u.bits.manh += (c); \ if (u.bits.manh < o) { \ u.bits.exp++; \ u.bits.manh |= 1llu << (LDBL_MANH_SIZE - 1); \ } \ } while (0) #endif static const long double huge = 1.0e300; DLLEXPORT long double floorl(long double x) { union IEEEl2bits u = { .e = x }; int e = u.bits.exp - LDBL_MAX_EXP + 1; if (e < MANH_SIZE - 1) { if (e < 0) { /* raise inexact if x != 0 */ if (huge + x > 0.0) if (u.bits.exp > 0 || (u.bits.manh | u.bits.manl) != 0) u.e = u.bits.sign ? -1.0 : 0.0; } else { uint64_t m = ((1llu << MANH_SIZE) - 1) >> (e + 1); if (((u.bits.manh & m) | u.bits.manl) == 0) return (x); /* x is integral */ if (u.bits.sign) { #ifdef LDBL_IMPLICIT_NBIT if (e == 0) u.bits.exp++; else #endif INC_MANH(u, 1llu << (MANH_SIZE - e - 1)); } if (huge + x > 0.0) { /* raise inexact flag */ u.bits.manh &= ~m; u.bits.manl = 0; } } } else if (e < LDBL_MANT_DIG - 1) { uint64_t m = (uint64_t)-1 >> (64 - LDBL_MANT_DIG + e + 1); if ((u.bits.manl & m) == 0) return (x); /* x is integral */ if (u.bits.sign) { if (e == MANH_SIZE - 1) INC_MANH(u, 1); else { uint64_t o = u.bits.manl; u.bits.manl += 1llu << (LDBL_MANT_DIG - e - 1); if (u.bits.manl < o) /* got a carry */ INC_MANH(u, 1); } } if (huge + x > 0.0) /* raise inexact flag */ u.bits.manl &= ~m; } return (u.e); } openlibm-0.5.0/src/s_fma.c000066400000000000000000000175501266752446200153670ustar00rootroot00000000000000/*- * Copyright (c) 2005-2011 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_fma.c,v 1.8 2011/10/21 06:30:43 das Exp $"); #include #include #include #include "math_private.h" /* * A struct dd represents a floating-point number with twice the precision * of a double. We maintain the invariant that "hi" stores the 53 high-order * bits of the result. */ struct dd { double hi; double lo; }; /* * Compute a+b exactly, returning the exact result in a struct dd. We assume * that both a and b are finite, but make no assumptions about their relative * magnitudes. */ static inline struct dd dd_add(double a, double b) { struct dd ret; double s; ret.hi = a + b; s = ret.hi - a; ret.lo = (a - (ret.hi - s)) + (b - s); return (ret); } /* * Compute a+b, with a small tweak: The least significant bit of the * result is adjusted into a sticky bit summarizing all the bits that * were lost to rounding. This adjustment negates the effects of double * rounding when the result is added to another number with a higher * exponent. For an explanation of round and sticky bits, see any reference * on FPU design, e.g., * * J. Coonen. An Implementation Guide to a Proposed Standard for * Floating-Point Arithmetic. Computer, vol. 13, no. 1, Jan 1980. */ static inline double add_adjusted(double a, double b) { struct dd sum; u_int64_t hibits, lobits; sum = dd_add(a, b); if (sum.lo != 0) { EXTRACT_WORD64(hibits, sum.hi); if ((hibits & 1) == 0) { /* hibits += (int)copysign(1.0, sum.hi * sum.lo) */ EXTRACT_WORD64(lobits, sum.lo); hibits += 1 - ((hibits ^ lobits) >> 62); INSERT_WORD64(sum.hi, hibits); } } return (sum.hi); } /* * Compute ldexp(a+b, scale) with a single rounding error. It is assumed * that the result will be subnormal, and care is taken to ensure that * double rounding does not occur. */ static inline double add_and_denormalize(double a, double b, int scale) { struct dd sum; u_int64_t hibits, lobits; int bits_lost; sum = dd_add(a, b); /* * If we are losing at least two bits of accuracy to denormalization, * then the first lost bit becomes a round bit, and we adjust the * lowest bit of sum.hi to make it a sticky bit summarizing all the * bits in sum.lo. With the sticky bit adjusted, the hardware will * break any ties in the correct direction. * * If we are losing only one bit to denormalization, however, we must * break the ties manually. */ if (sum.lo != 0) { EXTRACT_WORD64(hibits, sum.hi); bits_lost = -((int)(hibits >> 52) & 0x7ff) - scale + 1; if ((bits_lost != 1) ^ (int)(hibits & 1)) { /* hibits += (int)copysign(1.0, sum.hi * sum.lo) */ EXTRACT_WORD64(lobits, sum.lo); hibits += 1 - (((hibits ^ lobits) >> 62) & 2); INSERT_WORD64(sum.hi, hibits); } } return (ldexp(sum.hi, scale)); } /* * Compute a*b exactly, returning the exact result in a struct dd. We assume * that both a and b are normalized, so no underflow or overflow will occur. * The current rounding mode must be round-to-nearest. */ static inline struct dd dd_mul(double a, double b) { static const double split = 0x1p27 + 1.0; struct dd ret; double ha, hb, la, lb, p, q; p = a * split; ha = a - p; ha += p; la = a - ha; p = b * split; hb = b - p; hb += p; lb = b - hb; p = ha * hb; q = ha * lb + la * hb; ret.hi = p + q; ret.lo = p - ret.hi + q + la * lb; return (ret); } /* * Fused multiply-add: Compute x * y + z with a single rounding error. * * We use scaling to avoid overflow/underflow, along with the * canonical precision-doubling technique adapted from: * * Dekker, T. A Floating-Point Technique for Extending the * Available Precision. Numer. Math. 18, 224-242 (1971). * * This algorithm is sensitive to the rounding precision. FPUs such * as the i387 must be set in double-precision mode if variables are * to be stored in FP registers in order to avoid incorrect results. * This is the default on FreeBSD, but not on many other systems. * * Hardware instructions should be used on architectures that support it, * since this implementation will likely be several times slower. */ DLLEXPORT double fma(double x, double y, double z) { double xs, ys, zs, adj; struct dd xy, r; int oround; int ex, ey, ez; int spread; /* * Handle special cases. The order of operations and the particular * return values here are crucial in handling special cases involving * infinities, NaNs, overflows, and signed zeroes correctly. */ if (x == 0.0 || y == 0.0) return (x * y + z); if (z == 0.0) return (x * y); if (!isfinite(x) || !isfinite(y)) return (x * y + z); if (!isfinite(z)) return (z); xs = frexp(x, &ex); ys = frexp(y, &ey); zs = frexp(z, &ez); oround = fegetround(); spread = ex + ey - ez; /* * If x * y and z are many orders of magnitude apart, the scaling * will overflow, so we handle these cases specially. Rounding * modes other than FE_TONEAREST are painful. */ if (spread < -DBL_MANT_DIG) { feraiseexcept(FE_INEXACT); if (!isnormal(z)) feraiseexcept(FE_UNDERFLOW); switch (oround) { case FE_TONEAREST: return (z); case FE_TOWARDZERO: if ((x > 0.0) ^ (y < 0.0) ^ (z < 0.0)) return (z); else return (nextafter(z, 0)); case FE_DOWNWARD: if ((x > 0.0) ^ (y < 0.0)) return (z); else return (nextafter(z, -INFINITY)); default: /* FE_UPWARD */ if ((x > 0.0) ^ (y < 0.0)) return (nextafter(z, INFINITY)); else return (z); } } if (spread <= DBL_MANT_DIG * 2) zs = ldexp(zs, -spread); else zs = copysign(DBL_MIN, zs); fesetround(FE_TONEAREST); /* * Basic approach for round-to-nearest: * * (xy.hi, xy.lo) = x * y (exact) * (r.hi, r.lo) = xy.hi + z (exact) * adj = xy.lo + r.lo (inexact; low bit is sticky) * result = r.hi + adj (correctly rounded) */ xy = dd_mul(xs, ys); r = dd_add(xy.hi, zs); spread = ex + ey; if (r.hi == 0.0) { /* * When the addends cancel to 0, ensure that the result has * the correct sign. */ fesetround(oround); volatile double vzs = zs; /* XXX gcc CSE bug workaround */ return (xy.hi + vzs + ldexp(xy.lo, spread)); } if (oround != FE_TONEAREST) { /* * There is no need to worry about double rounding in directed * rounding modes. */ fesetround(oround); adj = r.lo + xy.lo; return (ldexp(r.hi + adj, spread)); } adj = add_adjusted(r.lo, xy.lo); if (spread + ilogb(r.hi) > -1023) return (ldexp(r.hi + adj, spread)); else return (add_and_denormalize(r.hi, adj, spread)); } #if (LDBL_MANT_DIG == 53) __weak_reference(fma, fmal); #endif openlibm-0.5.0/src/s_fmaf.c000066400000000000000000000051571266752446200155350ustar00rootroot00000000000000/*- * Copyright (c) 2005-2011 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_fmaf.c,v 1.3 2011/10/15 04:16:58 das Exp $"); #include #include #include "math_private.h" /* * Fused multiply-add: Compute x * y + z with a single rounding error. * * A double has more than twice as much precision than a float, so * direct double-precision arithmetic suffices, except where double * rounding occurs. */ DLLEXPORT float fmaf(float x, float y, float z) { double xy, result; u_int32_t hr, lr; xy = (double)x * y; result = xy + z; EXTRACT_WORDS(hr, lr, result); /* Common case: The double precision result is fine. */ if ((lr & 0x1fffffff) != 0x10000000 || /* not a halfway case */ (hr & 0x7ff00000) == 0x7ff00000 || /* NaN */ result - xy == z || /* exact */ fegetround() != FE_TONEAREST) /* not round-to-nearest */ return (result); /* * If result is inexact, and exactly halfway between two float values, * we need to adjust the low-order bit in the direction of the error. */ fesetround(FE_TOWARDZERO); volatile double vxy = xy; /* XXX work around gcc CSE bug */ double adjusted_result = vxy + z; fesetround(FE_TONEAREST); if (result == adjusted_result) SET_LOW_WORD(adjusted_result, lr + 1); return (adjusted_result); } openlibm-0.5.0/src/s_fmal.c000066400000000000000000000165161266752446200155440ustar00rootroot00000000000000/*- * Copyright (c) 2005-2011 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_fmal.c,v 1.7 2011/10/21 06:30:43 das Exp $"); #include #include #include #include "fpmath.h" #include "math_private.h" /* * A struct dd represents a floating-point number with twice the precision * of a long double. We maintain the invariant that "hi" stores the high-order * bits of the result. */ struct dd { long double hi; long double lo; }; /* * Compute a+b exactly, returning the exact result in a struct dd. We assume * that both a and b are finite, but make no assumptions about their relative * magnitudes. */ static inline struct dd dd_add(long double a, long double b) { struct dd ret; long double s; ret.hi = a + b; s = ret.hi - a; ret.lo = (a - (ret.hi - s)) + (b - s); return (ret); } /* * Compute a+b, with a small tweak: The least significant bit of the * result is adjusted into a sticky bit summarizing all the bits that * were lost to rounding. This adjustment negates the effects of double * rounding when the result is added to another number with a higher * exponent. For an explanation of round and sticky bits, see any reference * on FPU design, e.g., * * J. Coonen. An Implementation Guide to a Proposed Standard for * Floating-Point Arithmetic. Computer, vol. 13, no. 1, Jan 1980. */ static inline long double add_adjusted(long double a, long double b) { struct dd sum; union IEEEl2bits u; sum = dd_add(a, b); if (sum.lo != 0) { u.e = sum.hi; if ((u.bits.manl & 1) == 0) sum.hi = nextafterl(sum.hi, INFINITY * sum.lo); } return (sum.hi); } /* * Compute ldexp(a+b, scale) with a single rounding error. It is assumed * that the result will be subnormal, and care is taken to ensure that * double rounding does not occur. */ static inline long double add_and_denormalize(long double a, long double b, int scale) { struct dd sum; int bits_lost; union IEEEl2bits u; sum = dd_add(a, b); /* * If we are losing at least two bits of accuracy to denormalization, * then the first lost bit becomes a round bit, and we adjust the * lowest bit of sum.hi to make it a sticky bit summarizing all the * bits in sum.lo. With the sticky bit adjusted, the hardware will * break any ties in the correct direction. * * If we are losing only one bit to denormalization, however, we must * break the ties manually. */ if (sum.lo != 0) { u.e = sum.hi; bits_lost = -u.bits.exp - scale + 1; if ((bits_lost != 1) ^ (int)(u.bits.manl & 1)) sum.hi = nextafterl(sum.hi, INFINITY * sum.lo); } return (ldexp(sum.hi, scale)); } /* * Compute a*b exactly, returning the exact result in a struct dd. We assume * that both a and b are normalized, so no underflow or overflow will occur. * The current rounding mode must be round-to-nearest. */ static inline struct dd dd_mul(long double a, long double b) { #if LDBL_MANT_DIG == 64 static const long double split = 0x1p32L + 1.0; #elif LDBL_MANT_DIG == 113 static const long double split = 0x1p57L + 1.0; #endif struct dd ret; long double ha, hb, la, lb, p, q; p = a * split; ha = a - p; ha += p; la = a - ha; p = b * split; hb = b - p; hb += p; lb = b - hb; p = ha * hb; q = ha * lb + la * hb; ret.hi = p + q; ret.lo = p - ret.hi + q + la * lb; return (ret); } /* * Fused multiply-add: Compute x * y + z with a single rounding error. * * We use scaling to avoid overflow/underflow, along with the * canonical precision-doubling technique adapted from: * * Dekker, T. A Floating-Point Technique for Extending the * Available Precision. Numer. Math. 18, 224-242 (1971). */ DLLEXPORT long double fmal(long double x, long double y, long double z) { long double xs, ys, zs, adj; struct dd xy, r; int oround; int ex, ey, ez; int spread; /* * Handle special cases. The order of operations and the particular * return values here are crucial in handling special cases involving * infinities, NaNs, overflows, and signed zeroes correctly. */ if (x == 0.0 || y == 0.0) return (x * y + z); if (z == 0.0) return (x * y); if (!isfinite(x) || !isfinite(y)) return (x * y + z); if (!isfinite(z)) return (z); xs = frexpl(x, &ex); ys = frexpl(y, &ey); zs = frexpl(z, &ez); oround = fegetround(); spread = ex + ey - ez; /* * If x * y and z are many orders of magnitude apart, the scaling * will overflow, so we handle these cases specially. Rounding * modes other than FE_TONEAREST are painful. */ if (spread < -LDBL_MANT_DIG) { feraiseexcept(FE_INEXACT); if (!isnormal(z)) feraiseexcept(FE_UNDERFLOW); switch (oround) { case FE_TONEAREST: return (z); case FE_TOWARDZERO: if ((x > 0.0) ^ (y < 0.0) ^ (z < 0.0)) return (z); else return (nextafterl(z, 0)); case FE_DOWNWARD: if ((x > 0.0) ^ (y < 0.0)) return (z); else return (nextafterl(z, -INFINITY)); default: /* FE_UPWARD */ if ((x > 0.0) ^ (y < 0.0)) return (nextafterl(z, INFINITY)); else return (z); } } if (spread <= LDBL_MANT_DIG * 2) zs = ldexpl(zs, -spread); else zs = copysignl(LDBL_MIN, zs); fesetround(FE_TONEAREST); /* * Basic approach for round-to-nearest: * * (xy.hi, xy.lo) = x * y (exact) * (r.hi, r.lo) = xy.hi + z (exact) * adj = xy.lo + r.lo (inexact; low bit is sticky) * result = r.hi + adj (correctly rounded) */ xy = dd_mul(xs, ys); r = dd_add(xy.hi, zs); spread = ex + ey; if (r.hi == 0.0) { /* * When the addends cancel to 0, ensure that the result has * the correct sign. */ fesetround(oround); volatile long double vzs = zs; /* XXX gcc CSE bug workaround */ return (xy.hi + vzs + ldexpl(xy.lo, spread)); } if (oround != FE_TONEAREST) { /* * There is no need to worry about double rounding in directed * rounding modes. */ fesetround(oround); adj = r.lo + xy.lo; return (ldexpl(r.hi + adj, spread)); } adj = add_adjusted(r.lo, xy.lo); if (spread + ilogbl(r.hi) > -16383) return (ldexpl(r.hi + adj, spread)); else return (add_and_denormalize(r.hi, adj, spread)); } openlibm-0.5.0/src/s_fmax.c000066400000000000000000000037571266752446200155630ustar00rootroot00000000000000/*- * Copyright (c) 2004 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_fmax.c,v 1.1 2004/06/30 07:04:01 das Exp $"); #include #include "fpmath.h" #include "math_private.h" DLLEXPORT double fmax(double x, double y) { union IEEEd2bits u[2]; u[0].d = x; u[1].d = y; /* Check for NaNs to avoid raising spurious exceptions. */ if (u[0].bits.exp == 2047 && (u[0].bits.manh | u[0].bits.manl) != 0) return (y); if (u[1].bits.exp == 2047 && (u[1].bits.manh | u[1].bits.manl) != 0) return (x); /* Handle comparisons of signed zeroes. */ if (u[0].bits.sign != u[1].bits.sign) return (u[u[0].bits.sign].d); return (x > y ? x : y); } openlibm-0.5.0/src/s_fmaxf.c000066400000000000000000000037041266752446200157210ustar00rootroot00000000000000/*- * Copyright (c) 2004 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_fmaxf.c,v 1.1 2004/06/30 07:04:01 das Exp $"); #include #include "fpmath.h" #include "math_private.h" DLLEXPORT float fmaxf(float x, float y) { union IEEEf2bits u[2]; u[0].f = x; u[1].f = y; /* Check for NaNs to avoid raising spurious exceptions. */ if (u[0].bits.exp == 255 && u[0].bits.man != 0) return (y); if (u[1].bits.exp == 255 && u[1].bits.man != 0) return (x); /* Handle comparisons of signed zeroes. */ if (u[0].bits.sign != u[1].bits.sign) return (u[u[0].bits.sign].f); return (x > y ? x : y); } openlibm-0.5.0/src/s_fmaxl.c000066400000000000000000000040551266752446200157270ustar00rootroot00000000000000/*- * Copyright (c) 2004 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_fmaxl.c,v 1.1 2004/06/30 07:04:01 das Exp $"); #include #include "fpmath.h" #include "math_private.h" DLLEXPORT long double fmaxl(long double x, long double y) { union IEEEl2bits u[2]; u[0].e = x; mask_nbit_l(u[0]); u[1].e = y; mask_nbit_l(u[1]); /* Check for NaNs to avoid raising spurious exceptions. */ if (u[0].bits.exp == 32767 && (u[0].bits.manh | u[0].bits.manl) != 0) return (y); if (u[1].bits.exp == 32767 && (u[1].bits.manh | u[1].bits.manl) != 0) return (x); /* Handle comparisons of signed zeroes. */ if (u[0].bits.sign != u[1].bits.sign) return (u[0].bits.sign ? y : x); return (x > y ? x : y); } openlibm-0.5.0/src/s_fmin.c000066400000000000000000000037571266752446200155610ustar00rootroot00000000000000/*- * Copyright (c) 2004 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_fmin.c,v 1.1 2004/06/30 07:04:01 das Exp $"); #include #include "fpmath.h" #include "math_private.h" DLLEXPORT double fmin(double x, double y) { union IEEEd2bits u[2]; u[0].d = x; u[1].d = y; /* Check for NaNs to avoid raising spurious exceptions. */ if (u[0].bits.exp == 2047 && (u[0].bits.manh | u[0].bits.manl) != 0) return (y); if (u[1].bits.exp == 2047 && (u[1].bits.manh | u[1].bits.manl) != 0) return (x); /* Handle comparisons of signed zeroes. */ if (u[0].bits.sign != u[1].bits.sign) return (u[u[1].bits.sign].d); return (x < y ? x : y); } openlibm-0.5.0/src/s_fminf.c000066400000000000000000000037041266752446200157170ustar00rootroot00000000000000/*- * Copyright (c) 2004 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_fminf.c,v 1.1 2004/06/30 07:04:01 das Exp $"); #include #include "fpmath.h" #include "math_private.h" DLLEXPORT float fminf(float x, float y) { union IEEEf2bits u[2]; u[0].f = x; u[1].f = y; /* Check for NaNs to avoid raising spurious exceptions. */ if (u[0].bits.exp == 255 && u[0].bits.man != 0) return (y); if (u[1].bits.exp == 255 && u[1].bits.man != 0) return (x); /* Handle comparisons of signed zeroes. */ if (u[0].bits.sign != u[1].bits.sign) return (u[u[1].bits.sign].f); return (x < y ? x : y); } openlibm-0.5.0/src/s_fminl.c000066400000000000000000000040551266752446200157250ustar00rootroot00000000000000/*- * Copyright (c) 2004 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_fminl.c,v 1.1 2004/06/30 07:04:01 das Exp $"); #include #include "fpmath.h" #include "math_private.h" DLLEXPORT long double fminl(long double x, long double y) { union IEEEl2bits u[2]; u[0].e = x; mask_nbit_l(u[0]); u[1].e = y; mask_nbit_l(u[1]); /* Check for NaNs to avoid raising spurious exceptions. */ if (u[0].bits.exp == 32767 && (u[0].bits.manh | u[0].bits.manl) != 0) return (y); if (u[1].bits.exp == 32767 && (u[1].bits.manh | u[1].bits.manl) != 0) return (x); /* Handle comparisons of signed zeroes. */ if (u[0].bits.sign != u[1].bits.sign) return (u[1].bits.sign ? y : x); return (x < y ? x : y); } openlibm-0.5.0/src/s_fpclassify.c000066400000000000000000000047701266752446200167670ustar00rootroot00000000000000/*- * Copyright (c) 2004 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include #include "math_private.h" #include "fpmath.h" DLLEXPORT int __fpclassifyd(double d) { union IEEEd2bits u; u.d = d; if (u.bits.exp == 2047) { if (u.bits.manl == 0 && u.bits.manh == 0) { return FP_INFINITE; } else { return FP_NAN; } } else if (u.bits.exp != 0) { return FP_NORMAL; } else if (u.bits.manl == 0 && u.bits.manh == 0) { return FP_ZERO; } else { return FP_SUBNORMAL; } } DLLEXPORT int __fpclassifyf(float f) { union IEEEf2bits u; u.f = f; if (u.bits.exp == 255) { if (u.bits.man == 0) { return FP_INFINITE; } else { return FP_NAN; } } else if (u.bits.exp != 0) { return FP_NORMAL; } else if (u.bits.man == 0) { return FP_ZERO; } else { return FP_SUBNORMAL; } } #ifdef LONG_DOUBLE DLLEXPORT int __fpclassifyl(long double e) { union IEEEl2bits u; u.e = e; mask_nbit_l(u); if (u.bits.exp == 32767) { if (u.bits.manl == 0 && u.bits.manh == 0) { return FP_INFINITE; } else { return FP_NAN; } } else if (u.bits.exp != 0) { return FP_NORMAL; } else if (u.bits.manl == 0 && u.bits.manh == 0) { return FP_ZERO; } else { return FP_SUBNORMAL; } } #endif openlibm-0.5.0/src/s_frexp.c000066400000000000000000000026241266752446200157440ustar00rootroot00000000000000/* @(#)s_frexp.c 5.1 93/09/24 */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_frexp.c,v 1.11 2008/02/22 02:30:35 das Exp $"); /* * for non-zero x * x = frexp(arg,&exp); * return a double fp quantity x such that 0.5 <= |x| <1.0 * and the corresponding binary exponent "exp". That is * arg = x*2^exp. * If arg is inf, 0.0, or NaN, then frexp(arg,&exp) returns arg * with *exp=0. */ #include #include #include "math_private.h" static const double two54 = 1.80143985094819840000e+16; /* 0x43500000, 0x00000000 */ DLLEXPORT double frexp(double x, int *eptr) { int32_t hx, ix, lx; EXTRACT_WORDS(hx,lx,x); ix = 0x7fffffff&hx; *eptr = 0; if(ix>=0x7ff00000||((ix|lx)==0)) return x; /* 0,inf,nan */ if (ix<0x00100000) { /* subnormal */ x *= two54; GET_HIGH_WORD(hx,x); ix = hx&0x7fffffff; *eptr = -54; } *eptr += (ix>>20)-1022; hx = (hx&0x800fffff)|0x3fe00000; SET_HIGH_WORD(x,hx); return x; } #if (LDBL_MANT_DIG == 53) __weak_reference(frexp, frexpl); #endif openlibm-0.5.0/src/s_frexpf.c000066400000000000000000000021621266752446200161070ustar00rootroot00000000000000/* s_frexpf.c -- float version of s_frexp.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_frexpf.c,v 1.10 2008/02/22 02:30:35 das Exp $"); #include #include "math_private.h" static const float two25 = 3.3554432000e+07; /* 0x4c000000 */ DLLEXPORT float frexpf(float x, int *eptr) { int32_t hx,ix; GET_FLOAT_WORD(hx,x); ix = 0x7fffffff&hx; *eptr = 0; if(ix>=0x7f800000||(ix==0)) return x; /* 0,inf,nan */ if (ix<0x00800000) { /* subnormal */ x *= two25; GET_FLOAT_WORD(hx,x); ix = hx&0x7fffffff; *eptr = -25; } *eptr += (ix>>23)-126; hx = (hx&0x807fffff)|0x3f000000; SET_FLOAT_WORD(x,hx); return x; } openlibm-0.5.0/src/s_frexpl.c000066400000000000000000000040641266752446200161200ustar00rootroot00000000000000/*- * Copyright (c) 2004-2005 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/lib/msun/src/s_frexpl.c,v 1.1 2005/03/07 04:54:51 das Exp $ */ #include #include #include "fpmath.h" #include "math_private.h" #if LDBL_MAX_EXP != 0x4000 #error "Unsupported long double format" #endif DLLEXPORT long double frexpl(long double x, int *ex) { union IEEEl2bits u; u.e = x; switch (u.bits.exp) { case 0: /* 0 or subnormal */ if ((u.bits.manl | u.bits.manh) == 0) { *ex = 0; } else { u.e *= 0x1.0p514; *ex = u.bits.exp - 0x4200; u.bits.exp = 0x3ffe; } break; case 0x7fff: /* infinity or NaN; value of *ex is unspecified */ break; default: /* normal */ *ex = u.bits.exp - 0x3ffe; u.bits.exp = 0x3ffe; break; } return (u.e); } openlibm-0.5.0/src/s_ilogb.c000066400000000000000000000023431266752446200157120ustar00rootroot00000000000000/* @(#)s_ilogb.c 5.1 93/09/24 */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_ilogb.c,v 1.10 2008/02/22 02:30:35 das Exp $"); /* ilogb(double x) * return the binary exponent of non-zero x * ilogb(0) = FP_ILOGB0 * ilogb(NaN) = FP_ILOGBNAN (no signal is raised) * ilogb(inf) = INT_MAX (no signal is raised) */ #include #include #include "math_private.h" DLLEXPORT int ilogb(double x) { int32_t hx,lx,ix; EXTRACT_WORDS(hx,lx,x); hx &= 0x7fffffff; if(hx<0x00100000) { if((hx|lx)==0) return FP_ILOGB0; else /* subnormal x */ if(hx==0) { for (ix = -1043; lx>0; lx<<=1) ix -=1; } else { for (ix = -1022,hx<<=11; hx>0; hx<<=1) ix -=1; } return ix; } else if (hx<0x7ff00000) return (hx>>20)-1023; else if (hx>0x7ff00000 || lx!=0) return FP_ILOGBNAN; else return INT_MAX; } openlibm-0.5.0/src/s_ilogbf.c000066400000000000000000000020471266752446200160610ustar00rootroot00000000000000/* s_ilogbf.c -- float version of s_ilogb.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_ilogbf.c,v 1.8 2008/02/22 02:30:35 das Exp $"); #include #include #include "math_private.h" DLLEXPORT int ilogbf(float x) { int32_t hx,ix; GET_FLOAT_WORD(hx,x); hx &= 0x7fffffff; if(hx<0x00800000) { if(hx==0) return FP_ILOGB0; else /* subnormal x */ for (ix = -126,hx<<=8; hx>0; hx<<=1) ix -=1; return ix; } else if (hx<0x7f800000) return (hx>>23)-127; else if (hx>0x7f800000) return FP_ILOGBNAN; else return INT_MAX; } openlibm-0.5.0/src/s_ilogbl.c000066400000000000000000000025041266752446200160650ustar00rootroot00000000000000/* * From: @(#)s_ilogb.c 5.1 93/09/24 * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_ilogbl.c,v 1.2 2008/02/22 02:30:35 das Exp $"); #include #include #include #include "fpmath.h" #include "math_private.h" DLLEXPORT int ilogbl(long double x) { union IEEEl2bits u; unsigned long m; int b; u.e = x; if (u.bits.exp == 0) { if ((u.bits.manl | u.bits.manh) == 0) return (FP_ILOGB0); /* denormalized */ if (u.bits.manh == 0) { m = 1lu << (LDBL_MANL_SIZE - 1); for (b = LDBL_MANH_SIZE; !(u.bits.manl & m); m >>= 1) b++; } else { m = 1lu << (LDBL_MANH_SIZE - 1); for (b = 0; !(u.bits.manh & m); m >>= 1) b++; } #ifdef LDBL_IMPLICIT_NBIT b++; #endif return (LDBL_MIN_EXP - b - 1); } else if (u.bits.exp < (LDBL_MAX_EXP << 1) - 1) return (u.bits.exp - LDBL_MAX_EXP + 1); else if (u.bits.manl != 0 || u.bits.manh != 0) return (FP_ILOGBNAN); else return (INT_MAX); } openlibm-0.5.0/src/s_isfinite.c000066400000000000000000000035141266752446200164310ustar00rootroot00000000000000/*- * Copyright (c) 2004 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/lib/msun/src/s_isfinite.c,v 1.1 2004/07/09 03:32:39 das Exp $ */ #include #include "fpmath.h" #include "math_private.h" DLLEXPORT int __isfinite(double d) { union IEEEd2bits u; u.d = d; return (u.bits.exp != 2047); } DLLEXPORT int __isfinitef(float f) { union IEEEf2bits u; u.f = f; return (u.bits.exp != 255); } #ifdef LONG_DOUBLE DLLEXPORT int __isfinitel(long double e) { union IEEEl2bits u; u.e = e; return (u.bits.exp != 32767); } #endif openlibm-0.5.0/src/s_isinf.c000066400000000000000000000036621266752446200157330ustar00rootroot00000000000000/*- * Copyright (c) 2004 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include #include "fpmath.h" #include "math_private.h" /* Provided by libc */ #if 1 DLLEXPORT int (isinf) (double d) { union IEEEd2bits u; u.d = d; return (u.bits.exp == 2047 && u.bits.manl == 0 && u.bits.manh == 0); } #endif DLLEXPORT int __isinff(float f) { union IEEEf2bits u; u.f = f; return (u.bits.exp == 255 && u.bits.man == 0); } #ifdef LONG_DOUBLE DLLEXPORT int __isinfl(long double e) { union IEEEl2bits u; u.e = e; mask_nbit_l(u); return (u.bits.exp == 32767 && u.bits.manl == 0 && u.bits.manh == 0); } #endif __weak_reference(__isinff, isinff); openlibm-0.5.0/src/s_isnan.c000066400000000000000000000040021266752446200157200ustar00rootroot00000000000000/*- * Copyright (c) 2004 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/lib/msun/src/s_isnan.c,v 1.9 2010/06/12 17:32:05 das Exp $ */ #include #include "fpmath.h" #include "math_private.h" /* Provided by libc */ #if 1 DLLEXPORT int (isnan) (double d) { union IEEEd2bits u; u.d = d; return (u.bits.exp == 2047 && (u.bits.manl != 0 || u.bits.manh != 0)); } #endif DLLEXPORT int __isnanf(float f) { union IEEEf2bits u; u.f = f; return (u.bits.exp == 255 && u.bits.man != 0); } #ifdef LONG_DOUBLE DLLEXPORT int __isnanl(long double e) { union IEEEl2bits u; u.e = e; mask_nbit_l(u); return (u.bits.exp == 32767 && (u.bits.manl != 0 || u.bits.manh != 0)); } #endif __weak_reference(__isnanf, isnanf); openlibm-0.5.0/src/s_isnormal.c000066400000000000000000000036051266752446200164440ustar00rootroot00000000000000/*- * Copyright (c) 2004 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/lib/msun/src/s_isnormal.c,v 1.1 2004/07/09 03:32:39 das Exp $ */ #include #include "fpmath.h" #include "math_private.h" DLLEXPORT int __isnormal(double d) { union IEEEd2bits u; u.d = d; return (u.bits.exp != 0 && u.bits.exp != 2047); } DLLEXPORT int __isnormalf(float f) { union IEEEf2bits u; u.f = f; return (u.bits.exp != 0 && u.bits.exp != 255); } #ifdef LONG_DOUBLE DLLEXPORT int __isnormall(long double e) { union IEEEl2bits u; u.e = e; return (u.bits.exp != 0 && u.bits.exp != 32767); } #endif openlibm-0.5.0/src/s_llrint.c000066400000000000000000000003411266752446200161160ustar00rootroot00000000000000#include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_llrint.c,v 1.1 2005/01/11 23:12:55 das Exp $"); #define type double #define roundit rint #define dtype long long #define fn llrint #include "s_lrint.c" openlibm-0.5.0/src/s_llrintf.c000066400000000000000000000003431266752446200162660ustar00rootroot00000000000000#include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_llrintf.c,v 1.1 2005/01/11 23:12:55 das Exp $"); #define type float #define roundit rintf #define dtype long long #define fn llrintf #include "s_lrint.c" openlibm-0.5.0/src/s_llrintl.c000066400000000000000000000003511266752446200162730ustar00rootroot00000000000000#include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_llrintl.c,v 1.1 2008/01/14 02:12:06 das Exp $"); #define type long double #define roundit rintl #define dtype long long #define fn llrintl #include "s_lrint.c" openlibm-0.5.0/src/s_llround.c000066400000000000000000000004351266752446200162750ustar00rootroot00000000000000#include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_llround.c,v 1.2 2005/04/08 00:52:27 das Exp $"); #define type double #define roundit round #define dtype long long #define DTYPE_MIN LLONG_MIN #define DTYPE_MAX LLONG_MAX #define fn llround #include "s_lround.c" openlibm-0.5.0/src/s_llroundf.c000066400000000000000000000004371266752446200164450ustar00rootroot00000000000000#include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_llroundf.c,v 1.2 2005/04/08 00:52:27 das Exp $"); #define type float #define roundit roundf #define dtype long long #define DTYPE_MIN LLONG_MIN #define DTYPE_MAX LLONG_MAX #define fn llroundf #include "s_lround.c" openlibm-0.5.0/src/s_llroundl.c000066400000000000000000000004451266752446200164520ustar00rootroot00000000000000#include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_llroundl.c,v 1.1 2005/04/08 01:24:08 das Exp $"); #define type long double #define roundit roundl #define dtype long long #define DTYPE_MIN LLONG_MIN #define DTYPE_MAX LLONG_MAX #define fn llroundl #include "s_lround.c" openlibm-0.5.0/src/s_log1p.c000066400000000000000000000131301266752446200156340ustar00rootroot00000000000000/* @(#)s_log1p.c 5.1 93/09/24 */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_log1p.c,v 1.10 2008/03/29 16:37:59 das Exp $"); /* double log1p(double x) * * Method : * 1. Argument Reduction: find k and f such that * 1+x = 2^k * (1+f), * where sqrt(2)/2 < 1+f < sqrt(2) . * * Note. If k=0, then f=x is exact. However, if k!=0, then f * may not be representable exactly. In that case, a correction * term is need. Let u=1+x rounded. Let c = (1+x)-u, then * log(1+x) - log(u) ~ c/u. Thus, we proceed to compute log(u), * and add back the correction term c/u. * (Note: when x > 2**53, one can simply return log(x)) * * 2. Approximation of log1p(f). * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s) * = 2s + 2/3 s**3 + 2/5 s**5 + ....., * = 2s + s*R * We use a special Reme algorithm on [0,0.1716] to generate * a polynomial of degree 14 to approximate R The maximum error * of this polynomial approximation is bounded by 2**-58.45. In * other words, * 2 4 6 8 10 12 14 * R(z) ~ Lp1*s +Lp2*s +Lp3*s +Lp4*s +Lp5*s +Lp6*s +Lp7*s * (the values of Lp1 to Lp7 are listed in the program) * and * | 2 14 | -58.45 * | Lp1*s +...+Lp7*s - R(z) | <= 2 * | | * Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2. * In order to guarantee error in log below 1ulp, we compute log * by * log1p(f) = f - (hfsq - s*(hfsq+R)). * * 3. Finally, log1p(x) = k*ln2 + log1p(f). * = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo))) * Here ln2 is split into two floating point number: * ln2_hi + ln2_lo, * where n*ln2_hi is always exact for |n| < 2000. * * Special cases: * log1p(x) is NaN with signal if x < -1 (including -INF) ; * log1p(+INF) is +INF; log1p(-1) is -INF with signal; * log1p(NaN) is that NaN with no signal. * * Accuracy: * according to an error analysis, the error is always less than * 1 ulp (unit in the last place). * * Constants: * The hexadecimal values are the intended ones for the following * constants. The decimal values may be used, provided that the * compiler will convert from decimal to binary accurately enough * to produce the hexadecimal values shown. * * Note: Assuming log() return accurate answer, the following * algorithm can be used to compute log1p(x) to within a few ULP: * * u = 1+x; * if(u==1.0) return x ; else * return log(u)*(x/(u-1.0)); * * See HP-15C Advanced Functions Handbook, p.193. */ #include #include #include "math_private.h" static const double ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */ ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */ two54 = 1.80143985094819840000e+16, /* 43500000 00000000 */ Lp1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ Lp2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ Lp3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ Lp4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ Lp5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ Lp6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ Lp7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ static const double zero = 0.0; DLLEXPORT double log1p(double x) { double hfsq,f,c,s,z,R,u; int32_t k,hx,hu,ax; GET_HIGH_WORD(hx,x); ax = hx&0x7fffffff; k = 1; if (hx < 0x3FDA827A) { /* 1+x < sqrt(2)+ */ if(ax>=0x3ff00000) { /* x <= -1.0 */ if(x==-1.0) return -two54/zero; /* log1p(-1)=+inf */ else return (x-x)/(x-x); /* log1p(x<-1)=NaN */ } if(ax<0x3e200000) { /* |x| < 2**-29 */ if(two54+x>zero /* raise inexact */ &&ax<0x3c900000) /* |x| < 2**-54 */ return x; else return x - x*x*0.5; } if(hx>0||hx<=((int32_t)0xbfd2bec4)) { k=0;f=x;hu=1;} /* sqrt(2)/2- <= 1+x < sqrt(2)+ */ } if (hx >= 0x7ff00000) return x+x; if(k!=0) { if(hx<0x43400000) { STRICT_ASSIGN(double,u,1.0+x); GET_HIGH_WORD(hu,u); k = (hu>>20)-1023; c = (k>0)? 1.0-(u-x):x-(u-1.0);/* correction term */ c /= u; } else { u = x; GET_HIGH_WORD(hu,u); k = (hu>>20)-1023; c = 0; } hu &= 0x000fffff; /* * The approximation to sqrt(2) used in thresholds is not * critical. However, the ones used above must give less * strict bounds than the one here so that the k==0 case is * never reached from here, since here we have committed to * using the correction term but don't use it if k==0. */ if(hu<0x6a09e) { /* u ~< sqrt(2) */ SET_HIGH_WORD(u,hu|0x3ff00000); /* normalize u */ } else { k += 1; SET_HIGH_WORD(u,hu|0x3fe00000); /* normalize u/2 */ hu = (0x00100000-hu)>>2; } f = u-1.0; } hfsq=0.5*f*f; if(hu==0) { /* |f| < 2**-20 */ if(f==zero) { if(k==0) { return zero; } else { c += k*ln2_lo; return k*ln2_hi+c; } } R = hfsq*(1.0-0.66666666666666666*f); if(k==0) return f-R; else return k*ln2_hi-((R-(k*ln2_lo+c))-f); } s = f/(2.0+f); z = s*s; R = z*(Lp1+z*(Lp2+z*(Lp3+z*(Lp4+z*(Lp5+z*(Lp6+z*Lp7)))))); if(k==0) return f-(hfsq-s*(hfsq+R)); else return k*ln2_hi-((hfsq-(s*(hfsq+R)+(k*ln2_lo+c)))-f); } openlibm-0.5.0/src/s_log1pf.c000066400000000000000000000063041266752446200160070ustar00rootroot00000000000000/* s_log1pf.c -- float version of s_log1p.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_log1pf.c,v 1.12 2008/03/29 16:37:59 das Exp $"); #include #include #include "math_private.h" static const float ln2_hi = 6.9313812256e-01, /* 0x3f317180 */ ln2_lo = 9.0580006145e-06, /* 0x3717f7d1 */ two25 = 3.355443200e+07, /* 0x4c000000 */ Lp1 = 6.6666668653e-01, /* 3F2AAAAB */ Lp2 = 4.0000000596e-01, /* 3ECCCCCD */ Lp3 = 2.8571429849e-01, /* 3E924925 */ Lp4 = 2.2222198546e-01, /* 3E638E29 */ Lp5 = 1.8183572590e-01, /* 3E3A3325 */ Lp6 = 1.5313838422e-01, /* 3E1CD04F */ Lp7 = 1.4798198640e-01; /* 3E178897 */ static const float zero = 0.0; DLLEXPORT float log1pf(float x) { float hfsq,f,c,s,z,R,u; int32_t k,hx,hu,ax; GET_FLOAT_WORD(hx,x); ax = hx&0x7fffffff; k = 1; if (hx < 0x3ed413d0) { /* 1+x < sqrt(2)+ */ if(ax>=0x3f800000) { /* x <= -1.0 */ if(x==(float)-1.0) return -two25/zero; /* log1p(-1)=+inf */ else return (x-x)/(x-x); /* log1p(x<-1)=NaN */ } if(ax<0x38000000) { /* |x| < 2**-15 */ if(two25+x>zero /* raise inexact */ &&ax<0x33800000) /* |x| < 2**-24 */ return x; else return x - x*x*(float)0.5; } if(hx>0||hx<=((int32_t)0xbe95f619)) { k=0;f=x;hu=1;} /* sqrt(2)/2- <= 1+x < sqrt(2)+ */ } if (hx >= 0x7f800000) return x+x; if(k!=0) { if(hx<0x5a000000) { STRICT_ASSIGN(float,u,(float)1.0+x); GET_FLOAT_WORD(hu,u); k = (hu>>23)-127; /* correction term */ c = (k>0)? (float)1.0-(u-x):x-(u-(float)1.0); c /= u; } else { u = x; GET_FLOAT_WORD(hu,u); k = (hu>>23)-127; c = 0; } hu &= 0x007fffff; /* * The approximation to sqrt(2) used in thresholds is not * critical. However, the ones used above must give less * strict bounds than the one here so that the k==0 case is * never reached from here, since here we have committed to * using the correction term but don't use it if k==0. */ if(hu<0x3504f4) { /* u < sqrt(2) */ SET_FLOAT_WORD(u,hu|0x3f800000);/* normalize u */ } else { k += 1; SET_FLOAT_WORD(u,hu|0x3f000000); /* normalize u/2 */ hu = (0x00800000-hu)>>2; } f = u-(float)1.0; } hfsq=(float)0.5*f*f; if(hu==0) { /* |f| < 2**-20 */ if(f==zero) { if(k==0) { return zero; } else { c += k*ln2_lo; return k*ln2_hi+c; } } R = hfsq*((float)1.0-(float)0.66666666666666666*f); if(k==0) return f-R; else return k*ln2_hi-((R-(k*ln2_lo+c))-f); } s = f/((float)2.0+f); z = s*s; R = z*(Lp1+z*(Lp2+z*(Lp3+z*(Lp4+z*(Lp5+z*(Lp6+z*Lp7)))))); if(k==0) return f-(hfsq-s*(hfsq+R)); else return k*ln2_hi-((hfsq-(s*(hfsq+R)+(k*ln2_lo+c)))-f); } openlibm-0.5.0/src/s_logb.c000066400000000000000000000023321266752446200155370ustar00rootroot00000000000000/* @(#)s_logb.c 5.1 93/09/24 */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_logb.c,v 1.12 2008/02/08 01:22:13 bde Exp $"); /* * double logb(x) * IEEE 754 logb. Included to pass IEEE test suite. Not recommend. * Use ilogb instead. */ #include #include #include "math_private.h" static const double two54 = 1.80143985094819840000e+16; /* 43500000 00000000 */ DLLEXPORT double logb(double x) { int32_t lx,ix; EXTRACT_WORDS(ix,lx,x); ix &= 0x7fffffff; /* high |x| */ if((ix|lx)==0) return -1.0/fabs(x); if(ix>=0x7ff00000) return x*x; if(ix<0x00100000) { x *= two54; /* convert subnormal x to normal */ GET_HIGH_WORD(ix,x); ix &= 0x7fffffff; return (double) ((ix>>20)-1023-54); } else return (double) ((ix>>20)-1023); } #if (LDBL_MANT_DIG == 53) __weak_reference(logb, logbl); #endif openlibm-0.5.0/src/s_logbf.c000066400000000000000000000021271266752446200157070ustar00rootroot00000000000000/* s_logbf.c -- float version of s_logb.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_logbf.c,v 1.9 2008/02/22 02:30:35 das Exp $"); #include #include "math_private.h" static const float two25 = 3.355443200e+07; /* 0x4c000000 */ DLLEXPORT float logbf(float x) { int32_t ix; GET_FLOAT_WORD(ix,x); ix &= 0x7fffffff; /* high |x| */ if(ix==0) return (float)-1.0/fabsf(x); if(ix>=0x7f800000) return x*x; if(ix<0x00800000) { x *= two25; /* convert subnormal x to normal */ GET_FLOAT_WORD(ix,x); ix &= 0x7fffffff; return (float) ((ix>>23)-127-25); } else return (float) ((ix>>23)-127); } openlibm-0.5.0/src/s_logbl.c000066400000000000000000000023661266752446200157220ustar00rootroot00000000000000/* * From: @(#)s_ilogb.c 5.1 93/09/24 * ==================================================== * 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 #include #include #include "fpmath.h" #include "math_private.h" DLLEXPORT long double logbl(long double x) { union IEEEl2bits u; unsigned long m; int b; u.e = x; if (u.bits.exp == 0) { if ((u.bits.manl | u.bits.manh) == 0) { /* x == 0 */ u.bits.sign = 1; return (1.0L / u.e); } /* denormalized */ if (u.bits.manh == 0) { m = 1lu << (LDBL_MANL_SIZE - 1); for (b = LDBL_MANH_SIZE; !(u.bits.manl & m); m >>= 1) b++; } else { m = 1lu << (LDBL_MANH_SIZE - 1); for (b = 0; !(u.bits.manh & m); m >>= 1) b++; } #ifdef LDBL_IMPLICIT_NBIT b++; #endif return ((long double)(LDBL_MIN_EXP - b - 1)); } if (u.bits.exp < (LDBL_MAX_EXP << 1) - 1) /* normal */ return ((long double)(u.bits.exp - LDBL_MAX_EXP + 1)); else /* +/- inf or nan */ return (x * x); } openlibm-0.5.0/src/s_lrint.c000066400000000000000000000042531266752446200157500ustar00rootroot00000000000000/*- * Copyright (c) 2005 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" #include #include #include "math_private.h" #ifndef type //__FBSDID("$FreeBSD: src/lib/msun/src/s_lrint.c,v 1.1 2005/01/11 23:12:55 das Exp $"); #define type double #define roundit rint #define dtype long #define fn lrint #endif /* * C99 says we should not raise a spurious inexact exception when an * invalid exception is raised. Unfortunately, the set of inputs * that overflows depends on the rounding mode when 'dtype' has more * significant bits than 'type'. Hence, we bend over backwards for the * sake of correctness; an MD implementation could be more efficient. */ DLLEXPORT dtype fn(type x) { fenv_t env; dtype d; feholdexcept(&env); d = (dtype)roundit(x); if (fetestexcept(FE_INVALID)) feclearexcept(FE_INEXACT); feupdateenv(&env); return (d); } openlibm-0.5.0/src/s_lrintf.c000066400000000000000000000003341266752446200161120ustar00rootroot00000000000000#include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_lrintf.c,v 1.1 2005/01/11 23:12:55 das Exp $"); #define type float #define roundit rintf #define dtype long #define fn lrintf #include "s_lrint.c" openlibm-0.5.0/src/s_lrintl.c000066400000000000000000000003421266752446200161170ustar00rootroot00000000000000#include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_lrintl.c,v 1.1 2008/01/14 02:12:06 das Exp $"); #define type long double #define roundit rintl #define dtype long #define fn lrintl #include "s_lrint.c" openlibm-0.5.0/src/s_lround.c000066400000000000000000000047741266752446200161330ustar00rootroot00000000000000/*- * Copyright (c) 2005 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" #include #include #include #include "math_private.h" #ifndef type //__FBSDID("$FreeBSD: src/lib/msun/src/s_lround.c,v 1.2 2005/04/08 00:52:16 das Exp $"); #define type double #define roundit round #define dtype long #define DTYPE_MIN LONG_MIN #define DTYPE_MAX LONG_MAX #define fn lround #endif /* * If type has more precision than dtype, the endpoints dtype_(min|max) are * of the form xxx.5; they are "out of range" because lround() rounds away * from 0. On the other hand, if type has less precision than dtype, then * all values that are out of range are integral, so we might as well assume * that everything is in range. At compile time, INRANGE(x) should reduce to * two floating-point comparisons in the former case, or TRUE otherwise. */ static const type dtype_min = DTYPE_MIN - 0.5; static const type dtype_max = DTYPE_MAX + 0.5; #define INRANGE(x) (dtype_max - DTYPE_MAX != 0.5 || \ ((x) > dtype_min && (x) < dtype_max)) DLLEXPORT dtype fn(type x) { if (INRANGE(x)) { x = roundit(x); return ((dtype)x); } else { feraiseexcept(FE_INVALID); return (DTYPE_MAX); } } openlibm-0.5.0/src/s_lroundf.c000066400000000000000000000004261266752446200162670ustar00rootroot00000000000000#include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_lroundf.c,v 1.2 2005/04/08 00:52:27 das Exp $"); #define type float #define roundit roundf #define dtype long #define DTYPE_MIN LONG_MIN #define DTYPE_MAX LONG_MAX #define fn lroundf #include "s_lround.c" openlibm-0.5.0/src/s_lroundl.c000066400000000000000000000004341266752446200162740ustar00rootroot00000000000000#include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_lroundl.c,v 1.1 2005/04/08 01:24:08 das Exp $"); #define type long double #define roundit roundl #define dtype long #define DTYPE_MIN LONG_MIN #define DTYPE_MAX LONG_MAX #define fn lroundl #include "s_lround.c" openlibm-0.5.0/src/s_modf.c000066400000000000000000000035451266752446200155500ustar00rootroot00000000000000/* @(#)s_modf.c 5.1 93/09/24 */ /* * ==================================================== * 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. * ==================================================== */ /* * modf(double x, double *iptr) * return fraction part of x, and return x's integral part in *iptr. * Method: * Bit twiddling. * * Exception: * No exception. */ #include #include "math_private.h" static const double one = 1.0; DLLEXPORT double modf(double x, double *iptr) { int32_t i0,i1,j0; u_int32_t i; EXTRACT_WORDS(i0,i1,x); j0 = ((i0>>20)&0x7ff)-0x3ff; /* exponent of x */ if(j0<20) { /* integer part in high x */ if(j0<0) { /* |x|<1 */ INSERT_WORDS(*iptr,i0&0x80000000,0); /* *iptr = +-0 */ return x; } else { i = (0x000fffff)>>j0; if(((i0&i)|i1)==0) { /* x is integral */ u_int32_t high; *iptr = x; GET_HIGH_WORD(high,x); INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ return x; } else { INSERT_WORDS(*iptr,i0&(~i),0); return x - *iptr; } } } else if (j0>51) { /* no fraction part */ u_int32_t high; if (j0 == 0x400) { /* inf/NaN */ *iptr = x; return 0.0 / x; } *iptr = x*one; GET_HIGH_WORD(high,x); INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ return x; } else { /* fraction part in low x */ i = ((u_int32_t)(0xffffffff))>>(j0-20); if((i1&i)==0) { /* x is integral */ u_int32_t high; *iptr = x; GET_HIGH_WORD(high,x); INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ return x; } else { INSERT_WORDS(*iptr,i0,i1&(~i)); return x - *iptr; } } } openlibm-0.5.0/src/s_modff.c000066400000000000000000000027511266752446200157140ustar00rootroot00000000000000/* s_modff.c -- float version of s_modf.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_modff.c,v 1.9 2008/02/22 02:30:35 das Exp $"); #include #include "math_private.h" static const float one = 1.0; DLLEXPORT float modff(float x, float *iptr) { int32_t i0,j0; u_int32_t i; GET_FLOAT_WORD(i0,x); j0 = ((i0>>23)&0xff)-0x7f; /* exponent of x */ if(j0<23) { /* integer part in x */ if(j0<0) { /* |x|<1 */ SET_FLOAT_WORD(*iptr,i0&0x80000000); /* *iptr = +-0 */ return x; } else { i = (0x007fffff)>>j0; if((i0&i)==0) { /* x is integral */ u_int32_t ix; *iptr = x; GET_FLOAT_WORD(ix,x); SET_FLOAT_WORD(x,ix&0x80000000); /* return +-0 */ return x; } else { SET_FLOAT_WORD(*iptr,i0&(~i)); return x - *iptr; } } } else { /* no fraction part */ u_int32_t ix; *iptr = x*one; if (x != x) /* NaN */ return x; GET_FLOAT_WORD(ix,x); SET_FLOAT_WORD(x,ix&0x80000000); /* return +-0 */ return x; } } openlibm-0.5.0/src/s_modfl.c000066400000000000000000000067111266752446200157220ustar00rootroot00000000000000/*- * Copyright (c) 2007 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * Derived from s_modf.c, which has 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. * ==================================================== * * $FreeBSD: src/lib/msun/src/s_modfl.c,v 1.1 2007/01/07 07:54:21 das Exp $ */ #include #include #include "fpmath.h" #include "math_private.h" #if LDBL_MANL_SIZE > 32 #define MASK ((u_int64_t)-1) #else #define MASK ((u_int32_t)-1) #endif /* Return the last n bits of a word, representing the fractional part. */ #define GETFRAC(bits, n) ((bits) & ~(MASK << (n))) /* The number of fraction bits in manh, not counting the integer bit */ #define HIBITS (LDBL_MANT_DIG - LDBL_MANL_SIZE) static const long double zero[] = { 0.0L, -0.0L }; DLLEXPORT long double modfl(long double x, long double *iptr) { union IEEEl2bits ux; int e; ux.e = x; e = ux.bits.exp - LDBL_MAX_EXP + 1; if (e < HIBITS) { /* Integer part is in manh. */ if (e < 0) { /* |x|<1 */ *iptr = zero[ux.bits.sign]; return (x); } else { if ((GETFRAC(ux.bits.manh, HIBITS - 1 - e) | ux.bits.manl) == 0) { /* X is an integer. */ *iptr = x; return (zero[ux.bits.sign]); } else { /* Clear all but the top e+1 bits. */ ux.bits.manh >>= HIBITS - 1 - e; ux.bits.manh <<= HIBITS - 1 - e; ux.bits.manl = 0; *iptr = ux.e; return (x - ux.e); } } } else if (e >= LDBL_MANT_DIG - 1) { /* x has no fraction part. */ *iptr = x; if (x != x) /* Handle NaNs. */ return (x); return (zero[ux.bits.sign]); } else { /* Fraction part is in manl. */ if (GETFRAC(ux.bits.manl, LDBL_MANT_DIG - 1 - e) == 0) { /* x is integral. */ *iptr = x; return (zero[ux.bits.sign]); } else { /* Clear all but the top e+1 bits. */ ux.bits.manl >>= LDBL_MANT_DIG - 1 - e; ux.bits.manl <<= LDBL_MANT_DIG - 1 - e; *iptr = ux.e; return (x - ux.e); } } } openlibm-0.5.0/src/s_nan.c000066400000000000000000000072571266752446200154030ustar00rootroot00000000000000/*- * Copyright (c) 2007 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/lib/msun/src/s_nan.c,v 1.2 2007/12/18 23:46:32 das Exp $ */ //VBS //#include #include #include #include #include #include //for memset #include "math_private.h" #if !defined(__APPLE__) && !defined(__FreeBSD__) static __inline int digittoint(int c) { if ('0' <= c && c <= '9') return (c - '0'); else if ('A' <= c && c <= 'F') return (c - 'A' + 10); else if ('a' <= c && c <= 'f') return (c - 'a' + 10); return 0; } #endif /* * Scan a string of hexadecimal digits (the format nan(3) expects) and * make a bit array (using the local endianness). We stop when we * encounter an invalid character, NUL, etc. If we overflow, we do * the same as gcc's __builtin_nan(), namely, discard the high order bits. * * The format this routine accepts needs to be compatible with what is used * in contrib/gdtoa/hexnan.c (for strtod/scanf) and what is used in * __builtin_nan(). In fact, we're only 100% compatible for strings we * consider valid, so we might be violating the C standard. But it's * impossible to use nan(3) portably anyway, so this seems good enough. */ DLLEXPORT void __scan_nan(u_int32_t *words, int num_words, const char *s) { int si; /* index into s */ int bitpos; /* index into words (in bits) */ memset(words, 0, num_words * sizeof(u_int32_t)); /* Allow a leading '0x'. (It's expected, but redundant.) */ if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) s += 2; /* Scan forwards in the string, looking for the end of the sequence. */ for (si = 0; isxdigit(s[si]); si++) ; /* Scan backwards, filling in the bits in words[] as we go. */ #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ for (bitpos = 0; bitpos < 32 * num_words; bitpos += 4) { #else for (bitpos = 32 * num_words - 4; bitpos >= 0; bitpos -= 4) { #endif if (--si < 0) break; words[bitpos / 32] |= digittoint(s[si]) << (bitpos % 32); } } DLLEXPORT double nan(const char *s) { union { double d; u_int32_t bits[2]; } u; __scan_nan(u.bits, 2, s); #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ u.bits[1] |= 0x7ff80000; #else u.bits[0] |= 0x7ff80000; #endif return (u.d); } DLLEXPORT float nanf(const char *s) { union { float f; u_int32_t bits[1]; } u; __scan_nan(u.bits, 1, s); u.bits[0] |= 0x7fc00000; return (u.f); } #if (LDBL_MANT_DIG == 53) __weak_reference(nan, nanl); #endif openlibm-0.5.0/src/s_nearbyint.c000066400000000000000000000041511266752446200166100ustar00rootroot00000000000000/*- * Copyright (c) 2004 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_nearbyint.c,v 1.2 2008/01/14 02:12:06 das Exp $"); #include #include #include "math_private.h" /* * We save and restore the floating-point environment to avoid raising * an inexact exception. We can get away with using fesetenv() * instead of feclearexcept()/feupdateenv() to restore the environment * because the only exception defined for rint() is overflow, and * rounding can't overflow as long as emax >= p. */ #define DECL(type, fn, rint) \ DLLEXPORT type \ fn(type x) \ { \ type ret; \ fenv_t env; \ \ fegetenv(&env); \ ret = rint(x); \ fesetenv(&env); \ return (ret); \ } DECL(double, nearbyint, rint) DECL(float, nearbyintf, rintf) openlibm-0.5.0/src/s_nextafter.c000066400000000000000000000041741266752446200166220ustar00rootroot00000000000000/* @(#)s_nextafter.c 5.1 93/09/24 */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_nextafter.c,v 1.12 2008/02/22 02:30:35 das Exp $"); /* IEEE functions * nextafter(x,y) * return the next machine floating-point number of x in the * direction toward y. * Special cases: */ #include #include #include "math_private.h" DLLEXPORT double nextafter(double x, double y) { volatile double t; int32_t hx,hy,ix,iy; u_int32_t lx,ly; EXTRACT_WORDS(hx,lx,x); EXTRACT_WORDS(hy,ly,y); ix = hx&0x7fffffff; /* |x| */ iy = hy&0x7fffffff; /* |y| */ if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) || /* x is nan */ ((iy>=0x7ff00000)&&((iy-0x7ff00000)|ly)!=0)) /* y is nan */ return x+y; if(x==y) return y; /* x=y, return y */ if((ix|lx)==0) { /* x == 0 */ INSERT_WORDS(x,hy&0x80000000,1); /* return +-minsubnormal */ t = x*x; if(t==x) return t; else return x; /* raise underflow flag */ } if(hx>=0) { /* x > 0 */ if(hx>hy||((hx==hy)&&(lx>ly))) { /* x > y, x -= ulp */ if(lx==0) hx -= 1; lx -= 1; } else { /* x < y, x += ulp */ lx += 1; if(lx==0) hx += 1; } } else { /* x < 0 */ if(hy>=0||hx>hy||((hx==hy)&&(lx>ly))){/* x < y, x -= ulp */ if(lx==0) hx -= 1; lx -= 1; } else { /* x > y, x += ulp */ lx += 1; if(lx==0) hx += 1; } } hy = hx&0x7ff00000; if(hy>=0x7ff00000) return x+x; /* overflow */ if(hy<0x00100000) { /* underflow */ t = x*x; if(t!=x) { /* raise underflow flag */ INSERT_WORDS(y,hx,lx); return y; } } INSERT_WORDS(x,hx,lx); return x; } #if (LDBL_MANT_DIG == 53) __weak_reference(nextafter, nexttoward); __weak_reference(nextafter, nexttowardl); __weak_reference(nextafter, nextafterl); #endif openlibm-0.5.0/src/s_nextafterf.c000066400000000000000000000033201266752446200167600ustar00rootroot00000000000000/* s_nextafterf.c -- float version of s_nextafter.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_nextafterf.c,v 1.11 2008/02/22 02:30:35 das Exp $"); #include #include "math_private.h" DLLEXPORT float nextafterf(float x, float y) { volatile float t; int32_t hx,hy,ix,iy; GET_FLOAT_WORD(hx,x); GET_FLOAT_WORD(hy,y); ix = hx&0x7fffffff; /* |x| */ iy = hy&0x7fffffff; /* |y| */ if((ix>0x7f800000) || /* x is nan */ (iy>0x7f800000)) /* y is nan */ return x+y; if(x==y) return y; /* x=y, return y */ if(ix==0) { /* x == 0 */ SET_FLOAT_WORD(x,(hy&0x80000000)|1);/* return +-minsubnormal */ t = x*x; if(t==x) return t; else return x; /* raise underflow flag */ } if(hx>=0) { /* x > 0 */ if(hx>hy) { /* x > y, x -= ulp */ hx -= 1; } else { /* x < y, x += ulp */ hx += 1; } } else { /* x < 0 */ if(hy>=0||hx>hy){ /* x < y, x -= ulp */ hx -= 1; } else { /* x > y, x += ulp */ hx += 1; } } hy = hx&0x7f800000; if(hy>=0x7f800000) return x+x; /* overflow */ if(hy<0x00800000) { /* underflow */ t = x*x; if(t!=x) { /* raise underflow flag */ SET_FLOAT_WORD(y,hx); return y; } } SET_FLOAT_WORD(x,hx); return x; } openlibm-0.5.0/src/s_nextafterl.c000066400000000000000000000041621266752446200167730ustar00rootroot00000000000000/* @(#)s_nextafter.c 5.1 93/09/24 */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_nextafterl.c,v 1.2 2008/02/22 02:30:36 das Exp $"); /* IEEE functions * nextafter(x,y) * return the next machine floating-point number of x in the * direction toward y. * Special cases: */ #include #include #include "fpmath.h" #include "math_private.h" #if LDBL_MAX_EXP != 0x4000 #error "Unsupported long double format" #endif DLLEXPORT long double nextafterl(long double x, long double y) { volatile long double t; union IEEEl2bits ux, uy; ux.e = x; uy.e = y; if ((ux.bits.exp == 0x7fff && ((ux.bits.manh&~LDBL_NBIT)|ux.bits.manl) != 0) || (uy.bits.exp == 0x7fff && ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl) != 0)) return x+y; /* x or y is nan */ if(x==y) return y; /* x=y, return y */ if(x==0.0) { ux.bits.manh = 0; /* return +-minsubnormal */ ux.bits.manl = 1; ux.bits.sign = uy.bits.sign; t = ux.e*ux.e; if(t==ux.e) return t; else return ux.e; /* raise underflow flag */ } if((x>0.0) ^ (x #include #include "fpmath.h" #include "math_private.h" #if LDBL_MAX_EXP != 0x4000 #error "Unsupported long double format" #endif DLLEXPORT double nexttoward(double x, long double y) { union IEEEl2bits uy; volatile double t; int32_t hx,ix; u_int32_t lx; EXTRACT_WORDS(hx,lx,x); ix = hx&0x7fffffff; /* |x| */ uy.e = y; if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) || (uy.bits.exp == 0x7fff && ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl) != 0)) return x+y; /* x or y is nan */ if(x==y) return (double)y; /* x=y, return y */ if(x==0.0) { INSERT_WORDS(x,uy.bits.sign<<31,1); /* return +-minsubnormal */ t = x*x; if(t==x) return t; else return x; /* raise underflow flag */ } if((hx>0.0) ^ (x < y)) { /* x -= ulp */ if(lx==0) hx -= 1; lx -= 1; } else { /* x += ulp */ lx += 1; if(lx==0) hx += 1; } ix = hx&0x7ff00000; if(ix>=0x7ff00000) return x+x; /* overflow */ if(ix<0x00100000) { /* underflow */ t = x*x; if(t!=x) { /* raise underflow flag */ INSERT_WORDS(x,hx,lx); return x; } } INSERT_WORDS(x,hx,lx); return x; } openlibm-0.5.0/src/s_nexttowardf.c000066400000000000000000000030531266752446200171620ustar00rootroot00000000000000/* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_nexttowardf.c,v 1.3 2011/02/10 07:38:38 das Exp $"); #include #include #include "fpmath.h" #include "math_private.h" #define LDBL_INFNAN_EXP (LDBL_MAX_EXP * 2 - 1) #ifdef LONG_DOUBLE DLLEXPORT float nexttowardf(float x, long double y) { union IEEEl2bits uy; volatile float t; int32_t hx,ix; GET_FLOAT_WORD(hx,x); ix = hx&0x7fffffff; /* |x| */ uy.e = y; if((ix>0x7f800000) || (uy.bits.exp == LDBL_INFNAN_EXP && ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl) != 0)) return x+y; /* x or y is nan */ if(x==y) return (float)y; /* x=y, return y */ if(ix==0) { /* x == 0 */ SET_FLOAT_WORD(x,(uy.bits.sign<<31)|1);/* return +-minsubnormal */ t = x*x; if(t==x) return t; else return x; /* raise underflow flag */ } if((hx>=0) ^ (x < y)) /* x -= ulp */ hx -= 1; else /* x += ulp */ hx += 1; ix = hx&0x7f800000; if(ix>=0x7f800000) return x+x; /* overflow */ if(ix<0x00800000) { /* underflow */ t = x*x; if(t!=x) { /* raise underflow flag */ SET_FLOAT_WORD(x,hx); return x; } } SET_FLOAT_WORD(x,hx); return x; } #endif openlibm-0.5.0/src/s_remquo.c000066400000000000000000000076071266752446200161360ustar00rootroot00000000000000/* @(#)e_fmod.c 1.3 95/01/18 */ /*- * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_remquo.c,v 1.2 2008/03/30 20:47:26 das Exp $"); #include #include #include "math_private.h" static const double Zero[] = {0.0, -0.0,}; /* * Return the IEEE remainder and set *quo to the last n bits of the * quotient, rounded to the nearest integer. We choose n=31 because * we wind up computing all the integer bits of the quotient anyway as * a side-effect of computing the remainder by the shift and subtract * method. In practice, this is far more bits than are needed to use * remquo in reduction algorithms. */ DLLEXPORT double remquo(double x, double y, int *quo) { int32_t n,hx,hy,hz,ix,iy,sx,i; u_int32_t lx,ly,lz,q,sxy; EXTRACT_WORDS(hx,lx,x); EXTRACT_WORDS(hy,ly,y); sxy = (hx ^ hy) & 0x80000000; sx = hx&0x80000000; /* sign of x */ hx ^=sx; /* |x| */ hy &= 0x7fffffff; /* |y| */ /* purge off exception values */ if((hy|ly)==0||(hx>=0x7ff00000)|| /* y=0,or x not finite */ ((hy|((ly|-ly)>>31))>0x7ff00000)) /* or y is NaN */ return (x*y)/(x*y); if(hx<=hy) { if((hx>31]; /* |x|=|y| return x*0*/ } } /* determine ix = ilogb(x) */ if(hx<0x00100000) { /* subnormal x */ if(hx==0) { for (ix = -1043, i=lx; i>0; i<<=1) ix -=1; } else { for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1; } } else ix = (hx>>20)-1023; /* determine iy = ilogb(y) */ if(hy<0x00100000) { /* subnormal y */ if(hy==0) { for (iy = -1043, i=ly; i>0; i<<=1) iy -=1; } else { for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1; } } else iy = (hy>>20)-1023; /* set up {hx,lx}, {hy,ly} and align y to x */ if(ix >= -1022) hx = 0x00100000|(0x000fffff&hx); else { /* subnormal x, shift x to normal */ n = -1022-ix; if(n<=31) { hx = (hx<>(32-n)); lx <<= n; } else { hx = lx<<(n-32); lx = 0; } } if(iy >= -1022) hy = 0x00100000|(0x000fffff&hy); else { /* subnormal y, shift y to normal */ n = -1022-iy; if(n<=31) { hy = (hy<>(32-n)); ly <<= n; } else { hy = ly<<(n-32); ly = 0; } } /* fix point fmod */ n = ix - iy; q = 0; while(n--) { hz=hx-hy;lz=lx-ly; if(lx>31); lx = lx+lx;} else {hx = hz+hz+(lz>>31); lx = lz+lz; q++;} q <<= 1; } hz=hx-hy;lz=lx-ly; if(lx=0) {hx=hz;lx=lz;q++;} /* convert back to floating value and restore the sign */ if((hx|lx)==0) { /* return sign(x)*0 */ *quo = (sxy ? -q : q); return Zero[(u_int32_t)sx>>31]; } while(hx<0x00100000) { /* normalize x */ hx = hx+hx+(lx>>31); lx = lx+lx; iy -= 1; } if(iy>= -1022) { /* normalize output */ hx = ((hx-0x00100000)|((iy+1023)<<20)); } else { /* subnormal output */ n = -1022 - iy; if(n<=20) { lx = (lx>>n)|((u_int32_t)hx<<(32-n)); hx >>= n; } else if (n<=31) { lx = (hx<<(32-n))|(lx>>n); hx = sx; } else { lx = hx>>(n-32); hx = sx; } } fixup: INSERT_WORDS(x,hx,lx); y = fabs(y); if (y < 0x1p-1021) { if (x+x>y || (x+x==y && (q & 1))) { q++; x-=y; } } else if (x>0.5*y || (x==0.5*y && (q & 1))) { q++; x-=y; } GET_HIGH_WORD(hx,x); SET_HIGH_WORD(x,hx^sx); q &= 0x7fffffff; *quo = (sxy ? -q : q); return x; } #if LDBL_MANT_DIG == 53 __weak_reference(remquo, remquol); #endif openlibm-0.5.0/src/s_remquof.c000066400000000000000000000060641266752446200163000ustar00rootroot00000000000000/* @(#)e_fmod.c 1.3 95/01/18 */ /*- * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_remquof.c,v 1.1 2005/03/25 04:40:44 das Exp $"); #include #include "math_private.h" static const float Zero[] = {0.0, -0.0,}; /* * Return the IEEE remainder and set *quo to the last n bits of the * quotient, rounded to the nearest integer. We choose n=31 because * we wind up computing all the integer bits of the quotient anyway as * a side-effect of computing the remainder by the shift and subtract * method. In practice, this is far more bits than are needed to use * remquo in reduction algorithms. */ DLLEXPORT float remquof(float x, float y, int *quo) { int32_t n,hx,hy,hz,ix,iy,sx,i; u_int32_t q,sxy; GET_FLOAT_WORD(hx,x); GET_FLOAT_WORD(hy,y); sxy = (hx ^ hy) & 0x80000000; sx = hx&0x80000000; /* sign of x */ hx ^=sx; /* |x| */ hy &= 0x7fffffff; /* |y| */ /* purge off exception values */ if(hy==0||hx>=0x7f800000||hy>0x7f800000) /* y=0,NaN;or x not finite */ return (x*y)/(x*y); if(hx>31]; /* |x|=|y| return x*0*/ } /* determine ix = ilogb(x) */ if(hx<0x00800000) { /* subnormal x */ for (ix = -126,i=(hx<<8); i>0; i<<=1) ix -=1; } else ix = (hx>>23)-127; /* determine iy = ilogb(y) */ if(hy<0x00800000) { /* subnormal y */ for (iy = -126,i=(hy<<8); i>0; i<<=1) iy -=1; } else iy = (hy>>23)-127; /* set up {hx,lx}, {hy,ly} and align y to x */ if(ix >= -126) hx = 0x00800000|(0x007fffff&hx); else { /* subnormal x, shift x to normal */ n = -126-ix; hx <<= n; } if(iy >= -126) hy = 0x00800000|(0x007fffff&hy); else { /* subnormal y, shift y to normal */ n = -126-iy; hy <<= n; } /* fix point fmod */ n = ix - iy; q = 0; while(n--) { hz=hx-hy; if(hz<0) hx = hx << 1; else {hx = hz << 1; q++;} q <<= 1; } hz=hx-hy; if(hz>=0) {hx=hz;q++;} /* convert back to floating value and restore the sign */ if(hx==0) { /* return sign(x)*0 */ *quo = (sxy ? -q : q); return Zero[(u_int32_t)sx>>31]; } while(hx<0x00800000) { /* normalize x */ hx <<= 1; iy -= 1; } if(iy>= -126) { /* normalize output */ hx = ((hx-0x00800000)|((iy+127)<<23)); } else { /* subnormal output */ n = -126 - iy; hx >>= n; } fixup: SET_FLOAT_WORD(x,hx); y = fabsf(y); if (y < 0x1p-125f) { if (x+x>y || (x+x==y && (q & 1))) { q++; x-=y; } } else if (x>0.5f*y || (x==0.5f*y && (q & 1))) { q++; x-=y; } GET_FLOAT_WORD(hx,x); SET_FLOAT_WORD(x,hx^sx); q &= 0x7fffffff; *quo = (sxy ? -q : q); return x; } openlibm-0.5.0/src/s_remquol.c000066400000000000000000000107421266752446200163040ustar00rootroot00000000000000/* @(#)e_fmod.c 1.3 95/01/18 */ /*- * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunSoft, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_remquol.c,v 1.2 2008/07/31 20:09:47 das Exp $"); #include #include #include #include "fpmath.h" #include "math_private.h" #define BIAS (LDBL_MAX_EXP - 1) #if LDBL_MANL_SIZE > 32 typedef u_int64_t manl_t; #else typedef u_int32_t manl_t; #endif #if LDBL_MANH_SIZE > 32 typedef u_int64_t manh_t; #else typedef u_int32_t manh_t; #endif /* * These macros add and remove an explicit integer bit in front of the * fractional mantissa, if the architecture doesn't have such a bit by * default already. */ #ifdef LDBL_IMPLICIT_NBIT #define SET_NBIT(hx) ((hx) | (1ULL << LDBL_MANH_SIZE)) #define HFRAC_BITS LDBL_MANH_SIZE #else #define SET_NBIT(hx) (hx) #define HFRAC_BITS (LDBL_MANH_SIZE - 1) #endif #define MANL_SHIFT (LDBL_MANL_SIZE - 1) static const long double Zero[] = {0.0L, -0.0L}; /* * Return the IEEE remainder and set *quo to the last n bits of the * quotient, rounded to the nearest integer. We choose n=31 because * we wind up computing all the integer bits of the quotient anyway as * a side-effect of computing the remainder by the shift and subtract * method. In practice, this is far more bits than are needed to use * remquo in reduction algorithms. * * Assumptions: * - The low part of the mantissa fits in a manl_t exactly. * - The high part of the mantissa fits in an int64_t with enough room * for an explicit integer bit in front of the fractional bits. */ DLLEXPORT long double remquol(long double x, long double y, int *quo) { union IEEEl2bits ux, uy; int64_t hx,hz; /* We need a carry bit even if LDBL_MANH_SIZE is 32. */ manh_t hy; manl_t lx,ly,lz; int ix,iy,n,q,sx,sxy; ux.e = x; uy.e = y; sx = ux.bits.sign; sxy = sx ^ uy.bits.sign; ux.bits.sign = 0; /* |x| */ uy.bits.sign = 0; /* |y| */ x = ux.e; /* purge off exception values */ if((uy.bits.exp|uy.bits.manh|uy.bits.manl)==0 || /* y=0 */ (ux.bits.exp == BIAS + LDBL_MAX_EXP) || /* or x not finite */ (uy.bits.exp == BIAS + LDBL_MAX_EXP && ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl)!=0)) /* or y is NaN */ return (x*y)/(x*y); if(ux.bits.exp<=uy.bits.exp) { if((ux.bits.exp>MANL_SHIFT); lx = lx+lx;} else {hx = hz+hz+(lz>>MANL_SHIFT); lx = lz+lz; q++;} q <<= 1; } hz=hx-hy;lz=lx-ly; if(lx=0) {hx=hz;lx=lz;q++;} /* convert back to floating value and restore the sign */ if((hx|lx)==0) { /* return sign(x)*0 */ *quo = (sxy ? -q : q); return Zero[sx]; } while(hx<(1ULL<>MANL_SHIFT); lx = lx+lx; iy -= 1; } ux.bits.manh = hx; /* The integer bit is truncated here if needed. */ ux.bits.manl = lx; if (iy < LDBL_MIN_EXP) { ux.bits.exp = iy + (BIAS + 512); ux.e *= 0x1p-512; } else { ux.bits.exp = iy + BIAS; } ux.bits.sign = 0; x = ux.e; fixup: y = fabsl(y); if (y < LDBL_MIN * 2) { if (x+x>y || (x+x==y && (q & 1))) { q++; x-=y; } } else if (x>0.5*y || (x==0.5*y && (q & 1))) { q++; x-=y; } ux.e = x; ux.bits.sign ^= sx; x = ux.e; q &= 0x7fffffff; *quo = (sxy ? -q : q); return x; } openlibm-0.5.0/src/s_rint.c000066400000000000000000000046531266752446200156000ustar00rootroot00000000000000/* @(#)s_rint.c 5.1 93/09/24 */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_rint.c,v 1.16 2008/02/22 02:30:35 das Exp $"); /* * rint(x) * Return x rounded to integral value according to the prevailing * rounding mode. * Method: * Using floating addition. * Exception: * Inexact flag raised if x not equal to rint(x). */ #include #include #include "math_private.h" static const double TWO52[2]={ 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ }; DLLEXPORT double rint(double x) { int32_t i0,j0,sx; u_int32_t i,i1; double w,t; EXTRACT_WORDS(i0,i1,x); sx = (i0>>31)&1; j0 = ((i0>>20)&0x7ff)-0x3ff; if(j0<20) { if(j0<0) { if(((i0&0x7fffffff)|i1)==0) return x; i1 |= (i0&0x0fffff); i0 &= 0xfffe0000; i0 |= ((i1|-i1)>>12)&0x80000; SET_HIGH_WORD(x,i0); STRICT_ASSIGN(double,w,TWO52[sx]+x); t = w-TWO52[sx]; GET_HIGH_WORD(i0,t); SET_HIGH_WORD(t,(i0&0x7fffffff)|(sx<<31)); return t; } else { i = (0x000fffff)>>j0; if(((i0&i)|i1)==0) return x; /* x is integral */ i>>=1; if(((i0&i)|i1)!=0) { /* * Some bit is set after the 0.5 bit. To avoid the * possibility of errors from double rounding in * w = TWO52[sx]+x, adjust the 0.25 bit to a lower * guard bit. We do this for all j0<=51. The * adjustment is trickiest for j0==18 and j0==19 * since then it spans the word boundary. */ if(j0==19) i1 = 0x40000000; else if(j0==18) i1 = 0x80000000; else i0 = (i0&(~i))|((0x20000)>>j0); } } } else if (j0>51) { if(j0==0x400) return x+x; /* inf or NaN */ else return x; /* x is integral */ } else { i = ((u_int32_t)(0xffffffff))>>(j0-20); if((i1&i)==0) return x; /* x is integral */ i>>=1; if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-20)); } INSERT_WORDS(x,i0,i1); STRICT_ASSIGN(double,w,TWO52[sx]+x); return w-TWO52[sx]; } #if (LDBL_MANT_DIG == 53) __weak_reference(rint, rintl); #endif openlibm-0.5.0/src/s_rintf.c000066400000000000000000000024651266752446200157450ustar00rootroot00000000000000/* s_rintf.c -- float version of s_rint.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_rintf.c,v 1.12 2008/02/22 02:30:35 das Exp $"); #include #include #include #include "math_private.h" static const float TWO23[2]={ 8.3886080000e+06, /* 0x4b000000 */ -8.3886080000e+06, /* 0xcb000000 */ }; DLLEXPORT float rintf(float x) { int32_t i0,j0,sx; float w,t; GET_FLOAT_WORD(i0,x); sx = (i0>>31)&1; j0 = ((i0>>23)&0xff)-0x7f; if(j0<23) { if(j0<0) { if((i0&0x7fffffff)==0) return x; STRICT_ASSIGN(float,w,TWO23[sx]+x); t = w-TWO23[sx]; GET_FLOAT_WORD(i0,t); SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31)); return t; } STRICT_ASSIGN(float,w,TWO23[sx]+x); return w-TWO23[sx]; } if(j0==0x80) return x+x; /* inf or NaN */ else return x; /* x is integral */ } openlibm-0.5.0/src/s_rintl.c000066400000000000000000000066361266752446200157570ustar00rootroot00000000000000/*- * Copyright (c) 2008 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_rintl.c,v 1.5 2008/02/22 11:59:05 bde Exp $"); #include #include #include #include "fpmath.h" //VBS #include "math_private.h" #if LDBL_MAX_EXP != 0x4000 /* We also require the usual bias, min exp and expsign packing. */ #error "Unsupported long double format" #endif #define BIAS (LDBL_MAX_EXP - 1) static const float shift[2] = { #if LDBL_MANT_DIG == 64 0x1.0p63, -0x1.0p63 #elif LDBL_MANT_DIG == 113 0x1.0p112, -0x1.0p112 #else #error "Unsupported long double format" #endif }; static const float zero[2] = { 0.0, -0.0 }; DLLEXPORT long double rintl(long double x) { union IEEEl2bits u; u_int32_t expsign; int ex, sign; u.e = x; expsign = u.xbits.expsign; ex = expsign & 0x7fff; if (ex >= BIAS + LDBL_MANT_DIG - 1) { if (ex == BIAS + LDBL_MAX_EXP) return (x + x); /* Inf, NaN, or unsupported format */ return (x); /* finite and already an integer */ } sign = expsign >> 15; /* * The following code assumes that intermediate results are * evaluated in long double precision. If they are evaluated in * greater precision, double rounding may occur, and if they are * evaluated in less precision (as on i386), results will be * wildly incorrect. */ x += shift[sign]; x -= shift[sign]; /* * If the result is +-0, then it must have the same sign as x, but * the above calculation doesn't always give this. Fix up the sign. */ if (ex < BIAS && x == 0.0L) return (zero[sign]); return (x); } /* * We save and restore the floating-point environment to avoid raising * an inexact exception. We can get away with using fesetenv() * instead of feclearexcept()/feupdateenv() to restore the environment * because the only exception defined for rint() is overflow, and * rounding can't overflow as long as emax >= p. */ #define DECL(type, fn, rint) \ DLLEXPORT type \ fn(type x) \ { \ type ret; \ fenv_t env; \ \ fegetenv(&env); \ ret = rint(x); \ fesetenv(&env); \ return (ret); \ } DECL(long double, nearbyintl, rintl) openlibm-0.5.0/src/s_round.c000066400000000000000000000034331266752446200157460ustar00rootroot00000000000000/*- * Copyright (c) 2003, Steven G. Kargl * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice unmodified, this list of conditions, and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_round.c,v 1.4 2005/12/02 13:45:06 bde Exp $"); #include #include "math_private.h" DLLEXPORT double round(double x) { double t; uint32_t hx; GET_HIGH_WORD(hx, x); if ((hx & 0x7fffffff) == 0x7ff00000) return (x + x); if (!(hx & 0x80000000)) { t = floor(x); if (t - x <= -0.5) t += 1; return (t); } else { t = floor(-x); if (t + x <= -0.5) t += 1; return (-t); } } openlibm-0.5.0/src/s_roundf.c000066400000000000000000000033321266752446200161120ustar00rootroot00000000000000/*- * Copyright (c) 2003, Steven G. Kargl * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice unmodified, this list of conditions, and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_roundf.c,v 1.4 2005/12/02 13:45:06 bde Exp $"); #include #include "math_private.h" DLLEXPORT float roundf(float x) { float t; if (!isfinite(x)) return (x); if (x >= 0.0) { t = floorf(x); if (t - x <= -0.5) t += 1.0; return (t); } else { t = floorf(-x); if (t + x <= -0.5) t += 1.0; return (-t); } } openlibm-0.5.0/src/s_roundl.c000066400000000000000000000033541266752446200161240ustar00rootroot00000000000000/*- * Copyright (c) 2003, Steven G. Kargl * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice unmodified, this list of conditions, and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_roundl.c,v 1.2 2005/12/02 13:45:06 bde Exp $"); #include #include "math_private.h" DLLEXPORT long double roundl(long double x) { long double t; if (!isfinite(x)) return (x); if (x >= 0.0) { t = floorl(x); if (t - x <= -0.5) t += 1.0; return (t); } else { t = floorl(-x); if (t + x <= -0.5) t += 1.0; return (-t); } } openlibm-0.5.0/src/s_scalbln.c000066400000000000000000000040561266752446200162370ustar00rootroot00000000000000/*- * Copyright (c) 2004 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_scalbln.c,v 1.2 2005/03/07 04:57:50 das Exp $"); #include #include #include "math_private.h" DLLEXPORT double scalbln (double x, long n) { int in; in = (int)n; if (in != n) { if (n > 0) in = INT_MAX; else in = INT_MIN; } return (scalbn(x, in)); } DLLEXPORT float scalblnf (float x, long n) { int in; in = (int)n; if (in != n) { if (n > 0) in = INT_MAX; else in = INT_MIN; } return (scalbnf(x, in)); } DLLEXPORT long double scalblnl (long double x, long n) { int in; in = (int)n; if (in != n) { if (n > 0) in = INT_MAX; else in = INT_MIN; } return (scalbnl(x, (int)n)); } openlibm-0.5.0/src/s_scalbn.c000066400000000000000000000036701266752446200160640ustar00rootroot00000000000000/* @(#)s_scalbn.c 5.1 93/09/24 */ /* * ==================================================== * 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. * ==================================================== */ /* * scalbn (double x, int n) * scalbn(x,n) returns x* 2**n computed by exponent * manipulation rather than by actually performing an * exponentiation or a multiplication. */ #include "cdefs-compat.h" #include #include #include "math_private.h" static const double two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */ huge = 1.0e+300, tiny = 1.0e-300; DLLEXPORT double scalbn (double x, int n) { int32_t k,hx,lx; EXTRACT_WORDS(hx,lx,x); k = (hx&0x7ff00000)>>20; /* extract exponent */ if (k==0) { /* 0 or subnormal x */ if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */ x *= two54; GET_HIGH_WORD(hx,x); k = ((hx&0x7ff00000)>>20) - 54; if (n< -50000) return tiny*x; /*underflow*/ } if (k==0x7ff) return x+x; /* NaN or Inf */ k = k+n; if (k > 0x7fe) return huge*copysign(huge,x); /* overflow */ if (k > 0) /* normal result */ {SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); return x;} if (k <= -54) { if (n > 50000) /* in case integer overflow in n+k */ return huge*copysign(huge,x); /*overflow*/ else return tiny*copysign(tiny,x); /*underflow*/ } k += 54; /* subnormal result */ SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); return x*twom54; } #if (LDBL_MANT_DIG == 53) __weak_reference(scalbn, ldexpl); __weak_reference(scalbn, scalbnl); #endif __strong_reference(scalbn, ldexp); openlibm-0.5.0/src/s_scalbnf.c000066400000000000000000000032571266752446200162330ustar00rootroot00000000000000/* s_scalbnf.c -- float version of s_scalbn.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 "cdefs-compat.h" #include #include "math_private.h" static const float two25 = 3.355443200e+07, /* 0x4c000000 */ twom25 = 2.9802322388e-08, /* 0x33000000 */ huge = 1.0e+30, tiny = 1.0e-30; DLLEXPORT float scalbnf (float x, int n) { int32_t k,ix; GET_FLOAT_WORD(ix,x); k = (ix&0x7f800000)>>23; /* extract exponent */ if (k==0) { /* 0 or subnormal x */ if ((ix&0x7fffffff)==0) return x; /* +-0 */ x *= two25; GET_FLOAT_WORD(ix,x); k = ((ix&0x7f800000)>>23) - 25; if (n< -50000) return tiny*x; /*underflow*/ } if (k==0xff) return x+x; /* NaN or Inf */ k = k+n; if (k > 0xfe) return huge*copysignf(huge,x); /* overflow */ if (k > 0) /* normal result */ {SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); return x;} if (k <= -25) { if (n > 50000) /* in case integer overflow in n+k */ return huge*copysignf(huge,x); /*overflow*/ else return tiny*copysignf(tiny,x); /*underflow*/ } k += 25; /* subnormal result */ SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); return x*twom25; } __strong_reference(scalbnf, ldexpf); openlibm-0.5.0/src/s_scalbnl.c000066400000000000000000000036571266752446200162450ustar00rootroot00000000000000/* @(#)s_scalbn.c 5.1 93/09/24 */ /* * ==================================================== * 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. * ==================================================== */ /* * scalbnl (long double x, int n) * scalbnl(x,n) returns x* 2**n computed by exponent * manipulation rather than by actually performing an * exponentiation or a multiplication. */ /* * We assume that a long double has a 15-bit exponent. On systems * where long double is the same as double, scalbnl() is an alias * for scalbn(), so we don't use this routine. */ #include "cdefs-compat.h" #include #include #include "fpmath.h" #include "math_private.h" #if LDBL_MAX_EXP != 0x4000 #error "Unsupported long double format" #endif static const long double huge = 0x1p16000L, tiny = 0x1p-16000L; DLLEXPORT long double scalbnl (long double x, int n) { union IEEEl2bits u; int k; u.e = x; k = u.bits.exp; /* extract exponent */ if (k==0) { /* 0 or subnormal x */ if ((u.bits.manh|u.bits.manl)==0) return x; /* +-0 */ u.e *= 0x1p+128; k = u.bits.exp - 128; if (n< -50000) return tiny*x; /*underflow*/ } if (k==0x7fff) return x+x; /* NaN or Inf */ k = k+n; if (k >= 0x7fff) return huge*copysignl(huge,x); /* overflow */ if (k > 0) /* normal result */ {u.bits.exp = k; return u.e;} if (k <= -128) { if (n > 50000) /* in case integer overflow in n+k */ return huge*copysign(huge,x); /*overflow*/ else return tiny*copysign(tiny,x); /*underflow*/ } k += 128; /* subnormal result */ u.bits.exp = k; return u.e*0x1p-128; } __strong_reference(scalbnl, ldexpl); openlibm-0.5.0/src/s_signbit.c000066400000000000000000000034641266752446200162620ustar00rootroot00000000000000/*- * Copyright (c) 2003 Mike Barcroft * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/lib/msun/src/s_signbit.c,v 1.1 2004/07/19 08:16:10 das Exp $ */ #include #include "fpmath.h" #include "math_private.h" DLLEXPORT int __signbit(double d) { union IEEEd2bits u; u.d = d; return (u.bits.sign); } DLLEXPORT int __signbitf(float f) { union IEEEf2bits u; u.f = f; return (u.bits.sign); } #ifdef LONG_DOUBLE DLLEXPORT int __signbitl(long double e) { union IEEEl2bits u; u.e = e; return (u.bits.sign); } #endif openlibm-0.5.0/src/s_signgam.c000066400000000000000000000001611266752446200162370ustar00rootroot00000000000000#include #include "math_private.h" #ifndef OPENLIBM_ONLY_THREAD_SAFE int signgam = 0; #endif openlibm-0.5.0/src/s_sin.c000066400000000000000000000044171266752446200154130ustar00rootroot00000000000000/* @(#)s_sin.c 5.1 93/09/24 */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_sin.c,v 1.13 2011/02/10 07:37:50 das Exp $"); /* sin(x) * Return sine function of x. * * kernel function: * __kernel_sin ... sine function on [-pi/4,pi/4] * __kernel_cos ... cose function on [-pi/4,pi/4] * __ieee754_rem_pio2 ... argument reduction routine * * Method. * Let S,C and T denote the sin, cos and tan respectively on * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 * in [-pi/4 , +pi/4], and let n = k mod 4. * We have * * n sin(x) cos(x) tan(x) * ---------------------------------------------------------- * 0 S C T * 1 C -S -1/T * 2 -S -C T * 3 -C S -1/T * ---------------------------------------------------------- * * Special cases: * Let trig be any of sin, cos, or tan. * trig(+-INF) is NaN, with signals; * trig(NaN) is that NaN; * * Accuracy: * TRIG(x) returns trig(x) nearly rounded */ #include #include //#define INLINE_REM_PIO2 #include "math_private.h" //#include "e_rem_pio2.c" DLLEXPORT double sin(double x) { double y[2],z=0.0; int32_t n, ix; /* High word of x. */ GET_HIGH_WORD(ix,x); /* |x| ~< pi/4 */ ix &= 0x7fffffff; if(ix <= 0x3fe921fb) { if(ix<0x3e500000) /* |x| < 2**-26 */ {if((int)x==0) return x;} /* generate inexact */ return __kernel_sin(x,z,0); } /* sin(Inf or NaN) is NaN */ else if (ix>=0x7ff00000) return x-x; /* argument reduction needed */ else { n = __ieee754_rem_pio2(x,y); switch(n&3) { case 0: return __kernel_sin(y[0],y[1],1); case 1: return __kernel_cos(y[0],y[1]); case 2: return -__kernel_sin(y[0],y[1],1); default: return -__kernel_cos(y[0],y[1]); } } } #if (LDBL_MANT_DIG == 53) __weak_reference(sin, sinl); #endif openlibm-0.5.0/src/s_sincos.c000066400000000000000000000107231266752446200161150ustar00rootroot00000000000000/* @(#)s_sincos.c 5.1 13/07/15 */ /* * ==================================================== * Copyright (C) 2013 Elliot Saba. All rights reserved. * * Developed at the University of Washington. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" /* sincos(x, s, c) * Several applications need sine and cosine of the same * angle x. This function computes both at the same time, * and stores the results in *sin and *cos. * * kernel function: * __kernel_sin ... sine function on [-pi/4,pi/4] * __kernel_cos ... cose function on [-pi/4,pi/4] * __ieee754_rem_pio2 ... argument reduction routine * * Method. * Borrow liberally from s_sin.c and s_cos.c, merging * efforts where applicable and returning their values in * appropriate variables, thereby slightly reducing the * amount of work relative to just calling sin/cos(x) * separately * * Special cases: * Let trig be any of sin, cos, or tan. * sincos(+-INF, s, c) is NaN, with signals; * sincos(NaN, s, c) is that NaN; */ #include #include //#define INLINE_REM_PIO2 #include "math_private.h" //#include "e_rem_pio2.c" /* Constants used in polynomial approximation of sin/cos */ static const double one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */ S1 = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */ S2 = 8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */ S3 = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */ S4 = 2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */ S5 = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */ S6 = 1.58969099521155010221e-10, /* 0x3DE5D93A, 0x5ACFD57C */ C1 = 4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */ C2 = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */ C3 = 2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */ C4 = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */ C5 = 2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */ C6 = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */ static void __kernel_sincos( double x, double y, int iy, double * k_s, double * k_c ) { /* Inline calculation of sin/cos, as we can save some work, and we will always need to calculate both values, no matter the result of switch */ double z, w, r, v, hz; z = x*x; w = z*z; /* cos-specific computation; equivalent to calling __kernel_cos(x,y) and storing in k_c*/ r = z*(C1+z*(C2+z*C3)) + w*w*(C4+z*(C5+z*C6)); hz = 0.5*z; v = one-hz; *k_c = v + (((one-v)-hz) + (z*r-x*y)); /* sin-specific computation; equivalent to calling __kernel_sin(x,y,1) and storing in k_s*/ r = S2+z*(S3+z*S4) + z*w*(S5+z*S6); v = z*x; if(iy == 0) *k_s = x+v*(S1+z*r); else *k_s = x-((z*(half*y-v*r)-y)-v*S1); } DLLEXPORT void sincos(double x, double * s, double * c) { double y[2]; int32_t ix; /* Store high word of x in ix */ GET_HIGH_WORD(ix,x); /* |x| ~< pi/4 */ ix &= 0x7fffffff; if(ix <= 0x3fe921fb) { /* Check for small x for sin and cos */ if(ix<0x3e46a09e) { /* Check for exact zero */ if( (int)x==0 ) { *s = x; *c = 1.0; return; } } /* Call kernel function with 0 extra */ __kernel_sincos(x,0.0,0, s, c); } else if( ix >= 0x7ff00000 ) { /* sincos(Inf or NaN) is NaN */ *s = x-x; *c = x-x; } /*argument reduction needed*/ else { double k_c, k_s; /* Calculate remainer, then sub out to kernel */ int32_t n = __ieee754_rem_pio2(x,y); __kernel_sincos( y[0], y[1], 1, &k_s, &k_c ); /* Figure out permutation of sin/cos outputs to true outputs */ switch(n&3) { case 0: *c = k_c; *s = k_s; break; case 1: *c = -k_s; *s = k_c; break; case 2: *c = -k_c; *s = -k_s; break; default: *c = k_s; *s = -k_c; break; } } } #if (LDBL_MANT_DIG == 53) __weak_reference(sincos, sincosl); #endif openlibm-0.5.0/src/s_sincosf.c000066400000000000000000000071071266752446200162650ustar00rootroot00000000000000/* s_sincosf.c -- float version of s_sincos.c * * Copyright (C) 2013 Elliot Saba * Developed at the University of Washington * * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" #include #include //#define INLINE_KERNEL_COSDF //#define INLINE_KERNEL_SINDF //#define INLINE_REM_PIO2F #include "math_private.h" //#include "e_rem_pio2f.c" //#include "k_cosf.c" //#include "k_sinf.c" /* Constants used in shortcircuits in sincosf */ static const double sc1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */ sc2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */ sc3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */ sc4pio2 = 4*M_PI_2, /* 0x401921FB, 0x54442D18 */ /* Constants used in polynomial approximation of sin/cos */ one = 1.0, S1 = -0x15555554cbac77.0p-55, /* -0.166666666416265235595 */ S2 = 0x111110896efbb2.0p-59, /* 0.0083333293858894631756 */ S3 = -0x1a00f9e2cae774.0p-65, /* -0.000198393348360966317347 */ S4 = 0x16cd878c3b46a7.0p-71, /* 0.0000027183114939898219064 */ C0 = -0x1ffffffd0c5e81.0p-54, /* -0.499999997251031003120 */ C1 = 0x155553e1053a42.0p-57, /* 0.0416666233237390631894 */ C2 = -0x16c087e80f1e27.0p-62, /* -0.00138867637746099294692 */ C3 = 0x199342e0ee5069.0p-68; /* 0.0000243904487962774090654 */ static void __kernel_sincosdf( double x, float * s, float * c ) { double r, w, z, v; z = x*x; w = z*z; /* cos-specific computation; equivalent to calling __kernel_cos(x,y) and storing in k_c*/ r = C2+z*C3; double k_c = ((one+z*C0) + w*C1) + (w*z)*r; /* sin-specific computation; equivalent to calling __kernel_sin(x,y,1) and storing in k_s*/ r = S3+z*S4; v = z*x; double k_s = (x + v*(S1+z*S2)) + v*w*r; *c = k_c; *s = k_s; } DLLEXPORT void sincosf(float x, float * s, float * c) { // Worst approximation of sin and cos NA *s = x; *c = x; double y; float k_c, k_s; int32_t n, hx, ix; GET_FLOAT_WORD(hx,x); ix = hx & 0x7fffffff; if(ix <= 0x3f490fda) { /* |x| ~<= pi/4 */ if(ix<0x39800000) { /* |x| < 2**-12 */ /* Check if x is exactly zero */ if(((int)x)==0) { *s = x; *c = 1.0f; return; } } __kernel_sincosdf(x, s, c); return; } /* |x| ~<= 5*pi/4 */ if (ix<=0x407b53d1) { /* |x| ~<= 3pi/4 */ if(ix<=0x4016cbe3) { if(hx>0) { __kernel_sincosdf( sc1pio2 - x, c, s ); } else { __kernel_sincosdf( sc1pio2 + x, c, &k_s ); *s = -k_s; } } else { if(hx>0) { __kernel_sincosdf( sc2pio2 - x, s, &k_c ); *c = -k_c; } else { __kernel_sincosdf( -sc2pio2 - x, s, &k_c ); *c = -k_c; } } return; } /* |x| ~<= 9*pi/4 */ if(ix<=0x40e231d5) { /* |x| ~> 7*pi/4 */ if(ix<=0x40afeddf) { if(hx>0) { __kernel_sincosdf( x - sc3pio2, c, &k_s ); *s = -k_s; } else { __kernel_sincosdf( x + sc3pio2, &k_c, s ); *c = -k_c; } } else { if( hx > 0 ) { __kernel_sincosdf( x - sc4pio2, s, c ); } else { __kernel_sincosdf( x + sc4pio2, s, c ); } } return; } /* cos(Inf or NaN) is NaN */ else if(ix>=0x7f800000) { *c = *s = x-x; } else { /* general argument reduction needed */ n = __ieee754_rem_pio2f(x,&y); switch(n&3) { case 0: __kernel_sincosdf( y, s, c ); break; case 1: __kernel_sincosdf( -y, c, s ); break; case 2: __kernel_sincosdf( -y, s, &k_c); *c = -k_c; break; default: __kernel_sincosdf( -y, &k_c, &k_s ); *c = -k_c; *s = -k_s; break; } } } openlibm-0.5.0/src/s_sincosl.c000066400000000000000000000013151266752446200162660ustar00rootroot00000000000000/* s_sincosl.c -- long double version of s_sincos.c * * Copyright (C) 2013 Elliot Saba * Developed at the University of Washington * * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #include "cdefs-compat.h" #include #include #include "math_private.h" #if LDBL_MANT_DIG == 64 #include "../ld80/e_rem_pio2l.h" #elif LDBL_MANT_DIG == 113 #include "../ld128/e_rem_pio2l.h" #else #error "Unsupported long double format" #endif DLLEXPORT void sincosl( long double x, long double * s, long double * c ) { *s = cosl( x ); *c = sinl( x ); } openlibm-0.5.0/src/s_sinf.c000066400000000000000000000044321266752446200155560ustar00rootroot00000000000000/* s_sinf.c -- float version of s_sin.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. * Optimized by Bruce D. Evans. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_sinf.c,v 1.17 2008/02/25 22:19:17 bde Exp $"); #include #include //#define INLINE_KERNEL_COSDF //#define INLINE_KERNEL_SINDF //#define INLINE_REM_PIO2F #include "math_private.h" //#include "e_rem_pio2f.c" //#include "k_cosf.c" //#include "k_sinf.c" /* Small multiples of pi/2 rounded to double precision. */ static const double s1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */ s2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */ s3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */ s4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */ DLLEXPORT float sinf(float x) { double y; int32_t n, hx, ix; GET_FLOAT_WORD(hx,x); ix = hx & 0x7fffffff; if(ix <= 0x3f490fda) { /* |x| ~<= pi/4 */ if(ix<0x39800000) /* |x| < 2**-12 */ if(((int)x)==0) return x; /* x with inexact if x != 0 */ return __kernel_sindf(x); } if(ix<=0x407b53d1) { /* |x| ~<= 5*pi/4 */ if(ix<=0x4016cbe3) { /* |x| ~<= 3pi/4 */ if(hx>0) return __kernel_cosdf(x - s1pio2); else return -__kernel_cosdf(x + s1pio2); } else return __kernel_sindf((hx > 0 ? s2pio2 : -s2pio2) - x); } if(ix<=0x40e231d5) { /* |x| ~<= 9*pi/4 */ if(ix<=0x40afeddf) { /* |x| ~<= 7*pi/4 */ if(hx>0) return -__kernel_cosdf(x - s3pio2); else return __kernel_cosdf(x + s3pio2); } else return __kernel_sindf(x + (hx > 0 ? -s4pio2 : s4pio2)); } /* sin(Inf or NaN) is NaN */ else if (ix>=0x7f800000) return x-x; /* general argument reduction needed */ else { n = __ieee754_rem_pio2f(x,&y); switch(n&3) { case 0: return __kernel_sindf(y); case 1: return __kernel_cosdf(y); case 2: return __kernel_sindf(-y); default: return -__kernel_cosdf(y); } } } openlibm-0.5.0/src/s_sinl.c000066400000000000000000000047441266752446200155720ustar00rootroot00000000000000/*- * Copyright (c) 2007 Steven G. Kargl * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice unmodified, this list of conditions, and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_sinl.c,v 1.3 2011/05/30 19:41:28 kargl Exp $"); #include #include #include "math_private.h" #if LDBL_MANT_DIG == 64 #include "../ld80/e_rem_pio2l.h" #elif LDBL_MANT_DIG == 113 #include "../ld128/e_rem_pio2l.h" #else #error "Unsupported long double format" #endif DLLEXPORT long double sinl(long double x) { union IEEEl2bits z; int e0, s; long double y[2]; long double hi, lo; z.e = x; s = z.bits.sign; z.bits.sign = 0; /* If x = +-0 or x is a subnormal number, then sin(x) = x */ if (z.bits.exp == 0) return (x); /* If x = NaN or Inf, then sin(x) = NaN. */ if (z.bits.exp == 32767) return ((x - x) / (x - x)); /* Optimize the case where x is already within range. */ if (z.e < M_PI_4) { hi = __kernel_sinl(z.e, 0, 0); return (s ? -hi : hi); } e0 = __ieee754_rem_pio2l(x, y); hi = y[0]; lo = y[1]; switch (e0 & 3) { case 0: hi = __kernel_sinl(hi, lo, 1); break; case 1: hi = __kernel_cosl(hi, lo); break; case 2: hi = - __kernel_sinl(hi, lo, 1); break; case 3: hi = - __kernel_cosl(hi, lo); break; } return (hi); } openlibm-0.5.0/src/s_tan.c000066400000000000000000000041571266752446200154050ustar00rootroot00000000000000/* @(#)s_tan.c 5.1 93/09/24 */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_tan.c,v 1.13 2011/02/10 07:37:50 das Exp $"); /* tan(x) * Return tangent function of x. * * kernel function: * __kernel_tan ... tangent function on [-pi/4,pi/4] * __ieee754_rem_pio2 ... argument reduction routine * * Method. * Let S,C and T denote the sin, cos and tan respectively on * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 * in [-pi/4 , +pi/4], and let n = k mod 4. * We have * * n sin(x) cos(x) tan(x) * ---------------------------------------------------------- * 0 S C T * 1 C -S -1/T * 2 -S -C T * 3 -C S -1/T * ---------------------------------------------------------- * * Special cases: * Let trig be any of sin, cos, or tan. * trig(+-INF) is NaN, with signals; * trig(NaN) is that NaN; * * Accuracy: * TRIG(x) returns trig(x) nearly rounded */ #include #include //#define INLINE_REM_PIO2 #include "math_private.h" //#include "e_rem_pio2.c" DLLEXPORT double tan(double x) { double y[2],z=0.0; int32_t n, ix; /* High word of x. */ GET_HIGH_WORD(ix,x); /* |x| ~< pi/4 */ ix &= 0x7fffffff; if(ix <= 0x3fe921fb) { if(ix<0x3e400000) /* x < 2**-27 */ if((int)x==0) return x; /* generate inexact */ return __kernel_tan(x,z,1); } /* tan(Inf or NaN) is NaN */ else if (ix>=0x7ff00000) return x-x; /* NaN */ /* argument reduction needed */ else { n = __ieee754_rem_pio2(x,y); return __kernel_tan(y[0],y[1],1-((n&1)<<1)); /* 1 -- n even -1 -- n odd */ } } #if (LDBL_MANT_DIG == 53) __weak_reference(tan, tanl); #endif openlibm-0.5.0/src/s_tanf.c000066400000000000000000000040771266752446200155540ustar00rootroot00000000000000/* s_tanf.c -- float version of s_tan.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. * Optimized by Bruce D. Evans. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_tanf.c,v 1.17 2008/02/25 22:19:17 bde Exp $"); #include #include //#define INLINE_KERNEL_TANDF //#define INLINE_REM_PIO2F #include "math_private.h" //#include "e_rem_pio2f.c" //#include "k_tanf.c" /* Small multiples of pi/2 rounded to double precision. */ static const double t1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */ t2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */ t3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */ t4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */ DLLEXPORT float tanf(float x) { double y; int32_t n, hx, ix; GET_FLOAT_WORD(hx,x); ix = hx & 0x7fffffff; if(ix <= 0x3f490fda) { /* |x| ~<= pi/4 */ if(ix<0x39800000) /* |x| < 2**-12 */ if(((int)x)==0) return x; /* x with inexact if x != 0 */ return __kernel_tandf(x,1); } if(ix<=0x407b53d1) { /* |x| ~<= 5*pi/4 */ if(ix<=0x4016cbe3) /* |x| ~<= 3pi/4 */ return __kernel_tandf(x + (hx>0 ? -t1pio2 : t1pio2), -1); else return __kernel_tandf(x + (hx>0 ? -t2pio2 : t2pio2), 1); } if(ix<=0x40e231d5) { /* |x| ~<= 9*pi/4 */ if(ix<=0x40afeddf) /* |x| ~<= 7*pi/4 */ return __kernel_tandf(x + (hx>0 ? -t3pio2 : t3pio2), -1); else return __kernel_tandf(x + (hx>0 ? -t4pio2 : t4pio2), 1); } /* tan(Inf or NaN) is NaN */ else if (ix>=0x7f800000) return x-x; /* general argument reduction needed */ else { n = __ieee754_rem_pio2f(x,&y); /* integer parameter: 1 -- n even; -1 -- n odd */ return __kernel_tandf(y,1-((n&1)<<1)); } } openlibm-0.5.0/src/s_tanh.c000066400000000000000000000037761266752446200155630ustar00rootroot00000000000000/* @(#)s_tanh.c 5.1 93/09/24 */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_tanh.c,v 1.9 2008/02/22 02:30:36 das Exp $"); /* Tanh(x) * Return the Hyperbolic Tangent of x * * Method : * x -x * e - e * 0. tanh(x) is defined to be ----------- * x -x * e + e * 1. reduce x to non-negative by tanh(-x) = -tanh(x). * 2. 0 <= x < 2**-28 : tanh(x) := x with inexact if x != 0 * -t * 2**-28 <= x < 1 : tanh(x) := -----; t = expm1(-2x) * t + 2 * 2 * 1 <= x < 22 : tanh(x) := 1 - -----; t = expm1(2x) * t + 2 * 22 <= x <= INF : tanh(x) := 1. * * Special cases: * tanh(NaN) is NaN; * only tanh(0)=0 is exact for finite argument. */ #include #include "math_private.h" static const double one = 1.0, two = 2.0, tiny = 1.0e-300, huge = 1.0e300; DLLEXPORT double tanh(double x) { double t,z; int32_t jx,ix; GET_HIGH_WORD(jx,x); ix = jx&0x7fffffff; /* x is INF or NaN */ if(ix>=0x7ff00000) { if (jx>=0) return one/x+one; /* tanh(+-inf)=+-1 */ else return one/x-one; /* tanh(NaN) = NaN */ } /* |x| < 22 */ if (ix < 0x40360000) { /* |x|<22 */ if (ix<0x3e300000) { /* |x|<2**-28 */ if(huge+x>one) return x; /* tanh(tiny) = tiny with inexact */ } if (ix>=0x3ff00000) { /* |x|>=1 */ t = expm1(two*fabs(x)); z = one - two/(t+two); } else { t = expm1(-two*fabs(x)); z= -t/(t+two); } /* |x| >= 22, return +-1 */ } else { z = one - tiny; /* raise inexact flag */ } return (jx>=0)? z: -z; } openlibm-0.5.0/src/s_tanhf.c000066400000000000000000000027111266752446200157150ustar00rootroot00000000000000/* s_tanhf.c -- float version of s_tanh.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_tanhf.c,v 1.9 2008/02/22 02:30:36 das Exp $"); #include #include "math_private.h" static const float one=1.0, two=2.0, tiny = 1.0e-30, huge = 1.0e30; DLLEXPORT float tanhf(float x) { float t,z; int32_t jx,ix; GET_FLOAT_WORD(jx,x); ix = jx&0x7fffffff; /* x is INF or NaN */ if(ix>=0x7f800000) { if (jx>=0) return one/x+one; /* tanh(+-inf)=+-1 */ else return one/x-one; /* tanh(NaN) = NaN */ } /* |x| < 9 */ if (ix < 0x41100000) { /* |x|<9 */ if (ix<0x39800000) { /* |x|<2**-12 */ if(huge+x>one) return x; /* tanh(tiny) = tiny with inexact */ } if (ix>=0x3f800000) { /* |x|>=1 */ t = expm1f(two*fabsf(x)); z = one - two/(t+two); } else { t = expm1f(-two*fabsf(x)); z= -t/(t+two); } /* |x| >= 9, return +-1 */ } else { z = one - tiny; /* raise inexact flag */ } return (jx>=0)? z: -z; } openlibm-0.5.0/src/s_tanl.c000066400000000000000000000051251266752446200155550ustar00rootroot00000000000000/*- * Copyright (c) 2007 Steven G. Kargl * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice unmodified, this list of conditions, and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_tanl.c,v 1.3 2011/05/30 19:41:28 kargl Exp $"); /* * Limited testing on pseudorandom numbers drawn within [0:4e8] shows * an accuracy of <= 1.5 ULP where 247024 values of x out of 40 million * possibles resulted in tan(x) that exceeded 0.5 ULP (ie., 0.6%). */ #include #include #include "math_private.h" #if LDBL_MANT_DIG == 64 #include "../ld80/e_rem_pio2l.h" #elif LDBL_MANT_DIG == 113 #include "../ld128/e_rem_pio2l.h" #else #error "Unsupported long double format" #endif DLLEXPORT long double tanl(long double x) { union IEEEl2bits z; int e0, s; long double y[2]; long double hi, lo; z.e = x; s = z.bits.sign; z.bits.sign = 0; /* If x = +-0 or x is subnormal, then tan(x) = x. */ if (z.bits.exp == 0) return (x); /* If x = NaN or Inf, then tan(x) = NaN. */ if (z.bits.exp == 32767) return ((x - x) / (x - x)); /* Optimize the case where x is already within range. */ if (z.e < M_PI_4) { hi = __kernel_tanl(z.e, 0, 0); return (s ? -hi : hi); } e0 = __ieee754_rem_pio2l(x, y); hi = y[0]; lo = y[1]; switch (e0 & 3) { case 0: case 2: hi = __kernel_tanl(hi, lo, 0); break; case 1: case 3: hi = __kernel_tanl(hi, lo, 1); break; } return (hi); } openlibm-0.5.0/src/s_tgammaf.c000066400000000000000000000034741266752446200162400ustar00rootroot00000000000000/*- * Copyright (c) 2008 David Schultz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_tgammaf.c,v 1.1 2008/02/18 17:27:10 das Exp $"); #include #include "math_private.h" /* * We simply call tgamma() rather than bloating the math library with * a float-optimized version of it. The reason is that tgammaf() is * essentially useless, since the function is superexponential and * floats have very limited range. */ DLLEXPORT float tgammaf(float x) { return (tgamma(x)); } openlibm-0.5.0/src/s_trunc.c000066400000000000000000000031311266752446200157450ustar00rootroot00000000000000/* @(#)s_floor.c 5.1 93/09/24 */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_trunc.c,v 1.4 2008/02/22 02:27:34 das Exp $"); /* * trunc(x) * Return x rounded toward 0 to integral value * Method: * Bit twiddling. * Exception: * Inexact flag raised if x not equal to trunc(x). */ #include #include #include "math_private.h" static const double huge = 1.0e300; DLLEXPORT double trunc(double x) { int32_t i0,i1,j0; u_int32_t i; EXTRACT_WORDS(i0,i1,x); j0 = ((i0>>20)&0x7ff)-0x3ff; if(j0<20) { if(j0<0) { /* raise inexact if x != 0 */ if(huge+x>0.0) {/* |x|<1, so return 0*sign(x) */ i0 &= 0x80000000U; i1 = 0; } } else { i = (0x000fffff)>>j0; if(((i0&i)|i1)==0) return x; /* x is integral */ if(huge+x>0.0) { /* raise inexact flag */ i0 &= (~i); i1=0; } } } else if (j0>51) { if(j0==0x400) return x+x; /* inf or NaN */ else return x; /* x is integral */ } else { i = ((u_int32_t)(0xffffffff))>>(j0-20); if((i1&i)==0) return x; /* x is integral */ if(huge+x>0.0) /* raise inexact flag */ i1 &= (~i); } INSERT_WORDS(x,i0,i1); return x; } #if LDBL_MANT_DIG == 53 __weak_reference(trunc, truncl); #endif openlibm-0.5.0/src/s_truncf.c000066400000000000000000000024551266752446200161230ustar00rootroot00000000000000/* @(#)s_floor.c 5.1 93/09/24 */ /* * ==================================================== * 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 "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_truncf.c,v 1.1 2004/06/20 09:25:43 das Exp $"); /* * truncf(x) * Return x rounded toward 0 to integral value * Method: * Bit twiddling. * Exception: * Inexact flag raised if x not equal to truncf(x). */ #include #include "math_private.h" static const float huge = 1.0e30F; DLLEXPORT float truncf(float x) { int32_t i0,j0; u_int32_t i; GET_FLOAT_WORD(i0,x); j0 = ((i0>>23)&0xff)-0x7f; if(j0<23) { if(j0<0) { /* raise inexact if x != 0 */ if(huge+x>0.0F) /* |x|<1, so return 0*sign(x) */ i0 &= 0x80000000; } else { i = (0x007fffff)>>j0; if((i0&i)==0) return x; /* x is integral */ if(huge+x>0.0F) /* raise inexact flag */ i0 &= (~i); } } else { if(j0==0x80) return x+x; /* inf or NaN */ else return x; /* x is integral */ } SET_FLOAT_WORD(x,i0); return x; } openlibm-0.5.0/src/s_truncl.c000066400000000000000000000033401266752446200161230ustar00rootroot00000000000000/* * ==================================================== * 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. * ==================================================== * * From: @(#)s_floor.c 5.1 93/09/24 */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/s_truncl.c,v 1.9 2008/02/14 15:10:34 bde Exp $"); /* * truncl(x) * Return x rounded toward 0 to integral value * Method: * Bit twiddling. * Exception: * Inexact flag raised if x not equal to truncl(x). */ #include #include #include #include "fpmath.h" #include "math_private.h" #ifdef LDBL_IMPLICIT_NBIT #define MANH_SIZE (LDBL_MANH_SIZE + 1) #else #define MANH_SIZE LDBL_MANH_SIZE #endif static const long double huge = 1.0e300; static const float zero[] = { 0.0, -0.0 }; DLLEXPORT long double truncl(long double x) { union IEEEl2bits u = { .e = x }; int e = u.bits.exp - LDBL_MAX_EXP + 1; if (e < MANH_SIZE - 1) { if (e < 0) { /* raise inexact if x != 0 */ if (huge + x > 0.0) u.e = zero[u.bits.sign]; } else { uint64_t m = ((1llu << MANH_SIZE) - 1) >> (e + 1); if (((u.bits.manh & m) | u.bits.manl) == 0) return (x); /* x is integral */ if (huge + x > 0.0) { /* raise inexact flag */ u.bits.manh &= ~m; u.bits.manl = 0; } } } else if (e < LDBL_MANT_DIG - 1) { uint64_t m = (uint64_t)-1 >> (64 - LDBL_MANT_DIG + e + 1); if ((u.bits.manl & m) == 0) return (x); /* x is integral */ if (huge + x > 0.0) /* raise inexact flag */ u.bits.manl &= ~m; } return (u.e); } openlibm-0.5.0/src/types-compat.h000066400000000000000000000004101266752446200167170ustar00rootroot00000000000000#ifndef _TYPES_COMPAT_H_ #define _TYPES_COMPAT_H_ #include #include typedef uint8_t u_int8_t; typedef uint16_t u_int16_t; typedef uint32_t u_int32_t; typedef uint64_t u_int64_t; #endif openlibm-0.5.0/src/w_cabs.c000066400000000000000000000007471266752446200155400ustar00rootroot00000000000000/* * cabs() wrapper for hypot(). * * Written by J.T. Conklin, * Placed into the Public Domain, 1994. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/w_cabs.c,v 1.7 2008/03/30 20:03:06 das Exp $"); #include #include #include #include "math_private.h" DLLEXPORT double cabs(double complex z) { return hypot(creal(z), cimag(z)); } #if LDBL_MANT_DIG == 53 __weak_reference(cabs, cabsl); #endif openlibm-0.5.0/src/w_cabsf.c000066400000000000000000000004541266752446200157010ustar00rootroot00000000000000/* * cabsf() wrapper for hypotf(). * * Written by J.T. Conklin, * Placed into the Public Domain, 1994. */ #include #include #include "math_private.h" DLLEXPORT float cabsf(z) float complex z; { return hypotf(crealf(z), cimagf(z)); } openlibm-0.5.0/src/w_cabsl.c000066400000000000000000000007401266752446200157050ustar00rootroot00000000000000/* * cabs() wrapper for hypot(). * * Written by J.T. Conklin, * Placed into the Public Domain, 1994. * * Modified by Steven G. Kargl for the long double type. */ #include "cdefs-compat.h" //__FBSDID("$FreeBSD: src/lib/msun/src/w_cabsl.c,v 1.1 2008/03/30 20:02:03 das Exp $"); #include #include #include "math_private.h" DLLEXPORT long double cabsl(long double complex z) { return hypotl(creall(z), cimagl(z)); } openlibm-0.5.0/test/000077500000000000000000000000001266752446200143165ustar00rootroot00000000000000openlibm-0.5.0/test/.gitignore000066400000000000000000000002111266752446200163000ustar00rootroot00000000000000/test-float /test-float-system /test-float.dSYM /test-double /test-double-system /test-double.dSYM /bench-openlibm /bench-syslibm /*.exe openlibm-0.5.0/test/Makefile000066400000000000000000000024171266752446200157620ustar00rootroot00000000000000OPENLIBM_HOME=$(abspath ..) include ../Make.inc # Set rpath of tests to builddir for loading shared library OPENLIBM_LIB = -L.. -lopenlibm ifeq ($(OS),Linux) OPENLIBM_LIB += -Wl,-rpath=$(OPENLIBM_HOME) endif all: test-double test-float # test-double-system test-float-system bench: bench-syslibm bench-openlibm test-double: test-double.c libm-test.c $(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_add_TARGET_$(ARCH)) $(LDFLAGS) $@.c -D__BSD_VISIBLE -I ../include -I../src $(OPENLIBM_LIB) -o $@ test-float: test-float.c libm-test.c $(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_add_TARGET_$(ARCH)) $(LDFLAGS) $@.c -D__BSD_VISIBLE -I ../include -I../src $(OPENLIBM_LIB) -o $@ test-double-system: test-double.c libm-test.c $(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_add_TARGET_$(ARCH)) $(LDFLAGS) $< -DSYS_MATH_H -lm -o $@ test-float-system: test-float.c libm-test.c $(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_add_TARGET_$(ARCH)) $(LDFLAGS) $< -DSYS_MATH_H -lm -o $@ bench-openlibm: libm-bench.cpp $(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_add_TARGET_$(ARCH)) $(LDFLAGS) $< $(OPENLIBM_LIB) -o $@ bench-syslibm: libm-bench.cpp $(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_add_TARGET_$(ARCH)) $(LDFLAGS) $< -lm -o $@ clean: rm -fr test-double test-float test-double-system test-float-system bench-openlibm bench-syslibm *.dSYM openlibm-0.5.0/test/inf_torture.c000066400000000000000000000107531266752446200170300ustar00rootroot00000000000000#include #include int main(); int main2(); int main3(); int main4(); int main() { printf("+inf:\n"); float fx = (float)INFINITY; unsigned int *fxi = (unsigned int*)&fx; double dx = (double)INFINITY; long unsigned long int *dxi = (long unsigned long int*)&dx; long double ldx = (long double)INFINITY; long unsigned long int *ldxi1 = (long unsigned long int*)&ldx; long unsigned long int *ldxi2 = &(ldxi1[1]); printf("\t\tf d ld\n"); printf("correct:\t%x %x %x\n", isinf(fx), isinf(dx), isinf(ldx)); printf("as floats:\t%x %x %x\n", isinf(*(float*)fxi), isinf(*(float*)dxi), isinf(*(float*)ldxi1)); printf("as double:\t%x %x %x\n", isinf(*(double*)fxi), isinf(*(double*)dxi), isinf(*(double*)ldxi1)); printf("as long double:\t%x %x %x\n", isinf(*(long double*)fxi), isinf(*(long double*)dxi), isinf(*(long double*)ldxi1)); printf("sizes ?4 8 12?:\t%d %d %d\n", (int)sizeof(fx), (int)sizeof(dx), (int)sizeof(ldx)); printf("sizes:\t%d %d %d\n", (int)sizeof(*fxi), (int)sizeof(*dxi), (int)sizeof(*ldxi1)*2); printf("bit repr:\n f: %x\n d: %llx\n ld: %llx%llx\n", *fxi, *dxi, (0xFFFF)&*ldxi2, *ldxi1); printf("\n"); main2(); return 0; } int main2() { printf("-inf:\n"); float fx = (float)-INFINITY; unsigned int *fxi = (unsigned int*)&fx; double dx = (double)-INFINITY; long unsigned long int *dxi = (long unsigned long int*)&dx; long double ldx = (long double)-INFINITY; long unsigned long int *ldxi1 = (long unsigned long int*)&ldx; long unsigned long int *ldxi2 = &(ldxi1[1]); printf("\t\tf d ld\n"); printf("correct:\t%x %x %x\n", isinf(fx), isinf(dx), isinf(ldx)); printf("as floats:\t%x %x %x\n", isinf(*(float*)fxi), isinf(*(float*)dxi), isinf(*(float*)ldxi1)); printf("as double:\t%x %x %x\n", isinf(*(double*)fxi), isinf(*(double*)dxi), isinf(*(double*)ldxi1)); printf("as long double:\t%x %x %x\n", isinf(*(long double*)fxi), isinf(*(long double*)dxi), isinf(*(long double*)ldxi1)); printf("sizes ?4 8 12?:\t%d %d %d\n", (int)sizeof(fx), (int)sizeof(dx), (int)sizeof(ldx)); printf("bit repr:\n f: %x\n d: %llx\n ld: %llx%llx\n", *fxi, *dxi, (0xFFFF)&*ldxi2, *ldxi1); printf("\n"); main3(); return 0; } int main3() { printf("+NaN:\n"); float fx = (float)NAN; unsigned int *fxi = (unsigned int*)&fx; double dx = (double)NAN; long unsigned long int *dxi = (long unsigned long int*)&dx; long double ldx = (long double)NAN; long unsigned long int *ldxi1 = (long unsigned long int*)&ldx; long unsigned long int *ldxi2 = &(ldxi1[1]); printf("\t\tf d ld\n"); printf("correct:\t%x %x %x\n", isnan(fx), isnan(dx), isnan(ldx)); printf("as floats:\t%x %x %x\n", isnan(*(float*)fxi), isnan(*(float*)dxi), isnan(*(float*)ldxi1)); printf("as double:\t%x %x %x\n", isnan(*(double*)fxi), isnan(*(double*)dxi), isnan(*(double*)ldxi1)); printf("as long double:\t%x %x %x\n", isnan(*(long double*)fxi), isnan(*(long double*)dxi), isnan(*(long double*)ldxi1)); printf("sizes ?4 8 12?:\t%d %d %d\n", (int)sizeof(fx), (int)sizeof(dx), (int)sizeof(ldx)); printf("sizes:\t%d %d %d\n", (int)sizeof(*fxi), (int)sizeof(*dxi), (int)sizeof(*ldxi1)*2); printf("bit repr:\n f: %x\n d: %llx\n ld: %llx%llx\n", *fxi, *dxi, (0xFFFF)&*ldxi2, *ldxi1); printf("\n"); main4(); return 0; } int main4() { printf("-NaN:\n"); float fx = (float)-NAN; unsigned int *fxi = (unsigned int*)&fx; double dx = (double)-NAN; long unsigned long int *dxi = (long unsigned long int*)&dx; long double ldx = (long double)-NAN; long unsigned long int *ldxi1 = (long unsigned long int*)&ldx; long unsigned long int *ldxi2 = &(ldxi1[1]); printf("\t\tf d ld\n"); printf("correct:\t%x %x %x\n", isnan(fx), isnan(dx), isnan(ldx)); printf("as floats:\t%x %x %x\n", isnan(*(float*)fxi), isnan(*(float*)dxi), isnan(*(float*)ldxi1)); printf("as double:\t%x %x %x\n", isnan(*(double*)fxi), isnan(*(double*)dxi), isnan(*(double*)ldxi1)); printf("as long double:\t%x %x %x\n", isnan(*(long double*)fxi), isnan(*(long double*)dxi), isnan(*(long double*)ldxi1)); printf("sizes ?4 8 12?:\t%d %d %d\n", (int)sizeof(fx), (int)sizeof(dx), (int)sizeof(ldx)); printf("bit repr:\n f: %x\n d: %llx\n ld: %llx%llx\n", *fxi, *dxi, (0xFFFF)&*ldxi2, *ldxi1); printf("\n"); return 0; } openlibm-0.5.0/test/libm-bench.cpp000066400000000000000000000053701266752446200170270ustar00rootroot00000000000000// Copyright (C) Dahua Lin, 2014. Provided under the MIT license. // Benchmark on libm functions #include #include #include #include // Timing facilities #ifdef __MACH__ #include class stimer { public: typedef uint64_t time_type; stimer() { ::mach_timebase_info(&m_baseinfo); } time_type current() const { return ::mach_absolute_time(); } double span(const time_type& t0, const time_type& t1) const { uint64_t d = (m_baseinfo.numer * (t1 - t0)) / m_baseinfo.denom; return static_cast(d) / 1.0e9; } private: mach_timebase_info_data_t m_baseinfo; }; #else class stimer { public: typedef timespec time_type; time_type current() const { time_type t; ::clock_gettime(CLOCK_REALTIME, &t); return t; } double span(const time_type& t0, const time_type& t1) const { return double(t1.tv_sec - t0.tv_sec) + double(t1.tv_nsec - t0.tv_nsec) * 1.0e-9; } }; #endif inline double sec2mps(double s, long n) { return n / (s * 1e6); } const long ARR_LEN = 1024; double a[ARR_LEN]; double b[ARR_LEN]; double r[ARR_LEN]; #define TFUN1(FNAME) \ void test_##FNAME(long n) { \ for (int j = 0; j < ARR_LEN; ++j) r[j] = FNAME(a[j]); \ stimer tm; \ stimer::time_type t0 = tm.current(); \ for(int i = 0; i < n; ++i) { \ for (int j = 0; j < ARR_LEN; ++j) r[j] = FNAME(a[j]); \ } \ double s = tm.span(t0, tm.current()); \ double mps = sec2mps(s, n * ARR_LEN); \ printf(" %-8s: %7.4f MPS\n", #FNAME, mps); } #define TFUN2(FNAME) \ void test_##FNAME(long n) { \ for (int j = 0; j < ARR_LEN; ++j) r[j] = FNAME(a[j], b[j]); \ stimer tm; \ stimer::time_type t0 = tm.current(); \ for(int i = 0; i < n; ++i) { \ for (int j = 0; j < ARR_LEN; ++j) r[j] = FNAME(a[j], b[j]); \ } \ double s = tm.span(t0, tm.current()); \ double mps = sec2mps(s, n * ARR_LEN); \ printf(" %-8s: %7.4f MPS\n", #FNAME, mps); } #define TCALL(FNAME) test_##FNAME(20000) // define benchmark functions TFUN2(pow) TFUN2(hypot) TFUN1(exp) TFUN1(log) TFUN1(log10) TFUN1(sin) TFUN1(cos) TFUN1(tan) TFUN1(asin) TFUN1(acos) TFUN1(atan) TFUN2(atan2) int main(int argc, char *argv[]) { // initialize array contents for (int i = 0; i < ARR_LEN; ++i) { a[i] = rand() / (double) RAND_MAX; b[i] = rand() / (double) RAND_MAX; } TCALL(pow); TCALL(hypot); TCALL(exp); TCALL(log); TCALL(log10); TCALL(sin); TCALL(cos); TCALL(tan); TCALL(asin); TCALL(acos); TCALL(atan); TCALL(atan2); return 0; } openlibm-0.5.0/test/libm-test-ulps.h000066400000000000000000000673311266752446200173620ustar00rootroot00000000000000/* This file is automatically generated from libm-test-ulps with gen-libm-test.pl. Don't change it - change instead the master files. */ /* Maximal error of functions. */ #define DELTAacos CHOOSE(1150, 0, 0, 1150, 0, 0) /* acos */ #define DELTAacosh CHOOSE(1, 0, 0, 1, 0, 0) /* acosh */ #define DELTAasin CHOOSE(1, 1, 0, 1, 0, 0) /* asin */ #define DELTAasinh CHOOSE(656, 0, 0, 656, 0, 0) /* asinh */ #define DELTAatan CHOOSE(549, 0, 0, 549, 0, 0) /* atan */ #define DELTAatanh CHOOSE(1605, 1, 0, 1605, 1, 0) /* atanh */ #define DELTAatan2 CHOOSE(549, 0, 0, 549, 0, 0) /* atan2 */ #define DELTAcabs CHOOSE(560, 1, 1, 560, 1, 1) /* cabs */ #define DELTAcacos CHOOSE(BUILD_COMPLEX (151, 329), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (1, 2), BUILD_COMPLEX (151, 329), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (1, 2)) /* cacos */ #define DELTAcacosh CHOOSE(BUILD_COMPLEX (328, 151), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (4, 4), BUILD_COMPLEX (328, 151), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (4, 4)) /* cacosh */ #define DELTAcasin CHOOSE(BUILD_COMPLEX (603, 329), BUILD_COMPLEX (3, 0), BUILD_COMPLEX (2, 2), BUILD_COMPLEX (603, 329), BUILD_COMPLEX (3, 0), BUILD_COMPLEX (2, 2)) /* casin */ #define DELTAcasinh CHOOSE(BUILD_COMPLEX (892, 12), BUILD_COMPLEX (5, 3), BUILD_COMPLEX (1, 6), BUILD_COMPLEX (892, 12), BUILD_COMPLEX (5, 3), BUILD_COMPLEX (1, 6)) /* casinh */ #define DELTAcatan CHOOSE(BUILD_COMPLEX (251, 474), BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), BUILD_COMPLEX (251, 474), BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* catan */ #define DELTAcatanh CHOOSE(BUILD_COMPLEX (66, 447), BUILD_COMPLEX (2, 0), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (66, 447), BUILD_COMPLEX (2, 0), BUILD_COMPLEX (1, 0)) /* catanh */ #define DELTAcbrt CHOOSE(716, 1, 0, 716, 1, 0) /* cbrt */ #define DELTAccos CHOOSE(BUILD_COMPLEX (5, 1901), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (5, 1901), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (1, 1)) /* ccos */ #define DELTAccosh CHOOSE(BUILD_COMPLEX (1467, 1183), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (1467, 1183), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (1, 1)) /* ccosh */ #define DELTAcexp CHOOSE(BUILD_COMPLEX (940, 1067), 0, BUILD_COMPLEX (1, 0), BUILD_COMPLEX (940, 1067), 0, BUILD_COMPLEX (1, 0)) /* cexp */ #define DELTAclog CHOOSE(BUILD_COMPLEX (0, 1), 0, 0, BUILD_COMPLEX (0, 1), 0, 0) /* clog */ #define DELTAclog10 CHOOSE(BUILD_COMPLEX (1403, 186), BUILD_COMPLEX (2, 1), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (1403, 186), BUILD_COMPLEX (2, 1), BUILD_COMPLEX (1, 1)) /* clog10 */ #define DELTAcos CHOOSE(529, 2, 1, 529, 2, 1) /* cos */ #define DELTAcosh CHOOSE(309, 0, 0, 309, 0, 0) /* cosh */ #define DELTAcpow CHOOSE(BUILD_COMPLEX (2, 9), BUILD_COMPLEX (1, 1.104), BUILD_COMPLEX (4, 2.5333), BUILD_COMPLEX (2, 9), BUILD_COMPLEX (1, 1.104), BUILD_COMPLEX (4, 2.5333)) /* cpow */ #define DELTAcsin CHOOSE(BUILD_COMPLEX (966, 168), 0, 0, BUILD_COMPLEX (966, 168), 0, 0) /* csin */ #define DELTAcsinh CHOOSE(BUILD_COMPLEX (413, 477), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (413, 477), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (1, 1)) /* csinh */ #define DELTAcsqrt CHOOSE(BUILD_COMPLEX (237, 128), BUILD_COMPLEX (1, 0), 0, BUILD_COMPLEX (237, 128), BUILD_COMPLEX (1, 0), 0) /* csqrt */ #define DELTActan CHOOSE(BUILD_COMPLEX (690, 367), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (690, 367), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (1, 1)) /* ctan */ #define DELTActanh CHOOSE(BUILD_COMPLEX (286, 3074), BUILD_COMPLEX (0, 1), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (286, 3074), BUILD_COMPLEX (0, 1), BUILD_COMPLEX (1, 1)) /* ctanh */ #define DELTAerfc CHOOSE(36, 24, 12, 36, 24, 12) /* erfc */ #define DELTAexp CHOOSE(754, 0, 0, 754, 0, 0) /* exp */ #define DELTAexp10 CHOOSE(1182, 1, 0, 1182, 1, 0) /* exp10 */ #define DELTAexp2 CHOOSE(462, 0, 0, 462, 0, 0) /* exp2 */ #define DELTAexpm1 CHOOSE(825, 0, 0, 825, 0, 0) /* expm1 */ #define DELTAfmod CHOOSE(4096, 2, 1, 4096, 2, 1) /* fmod */ #define DELTAgamma CHOOSE(1, 1, 0, 1, 1, 0) /* gamma */ #define DELTAhypot CHOOSE(560, 1, 1, 560, 0, 0) /* hypot */ #define DELTAj0 CHOOSE(0, 2, 1, 0, 2, 1) /* j0 */ #define DELTAj1 CHOOSE(2, 2, 1, 2, 2, 1) /* j1 */ #define DELTAjn CHOOSE(2, 5, 2, 2, 5, 2) /* jn */ #define DELTAlgamma CHOOSE(1, 1, 2, 1, 1, 2) /* lgamma */ #define DELTAlog CHOOSE(2341, 1, 1, 2341, 1, 1) /* log */ #define DELTAlog10 CHOOSE(2033, 1, 1, 2033, 1, 1) /* log10 */ #define DELTAlog1p CHOOSE(585, 1, 1, 585, 1, 1) /* log1p */ #define DELTAlog2 CHOOSE(1688, 1, 1, 1688, 1, 1) /* log2 */ #define DELTApow CHOOSE(725, 0, 0, 725, 0, 0) /* pow */ #define DELTAsin CHOOSE(627, 0, 0, 627, 0, 0) /* sin */ #define DELTAsincos CHOOSE(627, 1, 1, 627, 1, 1) /* sincos */ #define DELTAsinh CHOOSE(1029, 0, 1, 1028, 0, 1) /* sinh */ #define DELTAsqrt CHOOSE(489, 0, 0, 489, 0, 0) /* sqrt */ #define DELTAtan CHOOSE(1401, 0.5, 0, 1401, 0.5, 0) /* tan */ #define DELTAtanh CHOOSE(521, 0, 0, 521, 0, 0) /* tanh */ #define DELTAtgamma CHOOSE(2, 2, 1, 2, 2, 1) /* tgamma */ #define DELTAy0 CHOOSE(2, 3, 1, 2, 3, 1) /* y0 */ #define DELTAy1 CHOOSE(2, 3, 2, 2, 3, 2) /* y1 */ #define DELTAyn CHOOSE(7, 6, 3, 7, 6, 3) /* yn */ /* Error of single function calls. */ #define DELTA16 CHOOSE(1, 0, 0, 1, 0, 0) /* acosh (7) == 2.633915793849633417250092694615937 */ #define DELTA24 CHOOSE(1, 0, 0, 1, 0, 0) /* asin (0.5) == pi/6 */ #define DELTA25 CHOOSE(1, 0, 0, 1, 0, 0) /* asin (-0.5) == -pi/6 */ #define DELTA26 CHOOSE(1, 0, 0, 1, 0, 0) /* asin (1.0) == pi/2 */ #define DELTA27 CHOOSE(1, 0, 0, 1, 0, 0) /* asin (-1.0) == -pi/2 */ #define DELTA28 CHOOSE(1, 1, 0, 1, 0, 0) /* asin (0.7) == 0.77539749661075306374035335271498708 */ #define DELTA34 CHOOSE(656, 0, 0, 656, 0, 0) /* asinh (0.7) == 0.652666566082355786 */ #define DELTA42 CHOOSE(549, 0, 0, 549, 0, 0) /* atan (0.7) == 0.61072596438920861654375887649023613 */ #define DELTA50 CHOOSE(1605, 1, 0, 1605, 1, 0) /* atanh (0.7) == 0.8673005276940531944 */ #define DELTA74 CHOOSE(549, 0, 0, 549, 0, 0) /* atan2 (0.7, 1) == 0.61072596438920861654375887649023613 */ #define DELTA78 CHOOSE(1, 0, 0, 1, 0, 0) /* atan2 (0.4, 0.0003) == 1.5700463269355215717704032607580829 */ #define DELTA85 CHOOSE(0, 0, 1, 0, 0, 1) /* cabs (0.7 + 12.4 i) == 12.419742348374220601176836866763271 */ #define DELTA86 CHOOSE(0, 0, 1, 0, 0, 1) /* cabs (-12.4 + 0.7 i) == 12.419742348374220601176836866763271 */ #define DELTA87 CHOOSE(0, 0, 1, 0, 0, 1) /* cabs (-0.7 + 12.4 i) == 12.419742348374220601176836866763271 */ #define DELTA88 CHOOSE(0, 0, 1, 0, 0, 1) /* cabs (-12.4 - 0.7 i) == 12.419742348374220601176836866763271 */ #define DELTA89 CHOOSE(0, 0, 1, 0, 0, 1) /* cabs (-0.7 - 12.4 i) == 12.419742348374220601176836866763271 */ #define DELTA96 CHOOSE(560, 1, 0, 560, 1, 0) /* cabs (0.7 + 1.2 i) == 1.3892443989449804508432547041028554 */ #define DELTA130 CHOOSE(BUILD_COMPLEX (151, 329), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (1, 2), BUILD_COMPLEX (151, 329), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (1, 2)) /* cacos (0.7 + 1.2 i) == 1.1351827477151551088992008271819053 - 1.0927647857577371459105272080819308 i */ #define DELTA131 CHOOSE(BUILD_COMPLEX (0, 1), 0, 0, BUILD_COMPLEX (0, 1), 0, 0) /* cacos (-2 - 3 i) == 2.1414491111159960199416055713254211 + 1.9833870299165354323470769028940395 i */ #define DELTA165 CHOOSE(BUILD_COMPLEX (328, 151), BUILD_COMPLEX (1, 0), 0, BUILD_COMPLEX (328, 151), BUILD_COMPLEX (1, 0), 0) /* cacosh (0.7 + 1.2 i) == 1.0927647857577371459105272080819308 + 1.1351827477151551088992008271819053 i */ #define DELTA166 CHOOSE(BUILD_COMPLEX (6, 1), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (4, 4), BUILD_COMPLEX (6, 1), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (4, 4)) /* cacosh (-2 - 3 i) == -1.9833870299165354323470769028940395 + 2.1414491111159960199416055713254211 i */ #define DELTA225 CHOOSE(BUILD_COMPLEX (603, 329), BUILD_COMPLEX (3, 0), BUILD_COMPLEX (2, 2), BUILD_COMPLEX (603, 329), BUILD_COMPLEX (3, 0), BUILD_COMPLEX (2, 2)) /* casin (0.7 + 1.2 i) == 0.4356135790797415103321208644578462 + 1.0927647857577371459105272080819308 i */ #define DELTA226 CHOOSE(BUILD_COMPLEX (0, 1), 0, 0, BUILD_COMPLEX (0, 1), 0, 0) /* casin (-2 - 3 i) == -0.57065278432109940071028387968566963 - 1.9833870299165354323470769028940395 i */ #define DELTA262 CHOOSE(BUILD_COMPLEX (892, 12), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (892, 12), 0, BUILD_COMPLEX (0, 1)) /* casinh (0.7 + 1.2 i) == 0.97865459559367387689317593222160964 + 0.91135418953156011567903546856170941 i */ #define DELTA263 CHOOSE(BUILD_COMPLEX (6, 6), BUILD_COMPLEX (5, 3), BUILD_COMPLEX (1, 6), BUILD_COMPLEX (6, 6), BUILD_COMPLEX (5, 3), BUILD_COMPLEX (1, 6)) /* casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i */ #define DELTA301 CHOOSE(BUILD_COMPLEX (251, 474), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (251, 474), 0, BUILD_COMPLEX (0, 1)) /* catan (0.7 + 1.2 i) == 1.0785743834118921877443707996386368 + 0.57705737765343067644394541889341712 i */ #define DELTA302 CHOOSE(BUILD_COMPLEX (0, 7), BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 7), BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i */ #define DELTA340 CHOOSE(BUILD_COMPLEX (66, 447), BUILD_COMPLEX (1, 0), 0, BUILD_COMPLEX (66, 447), BUILD_COMPLEX (1, 0), 0) /* catanh (0.7 + 1.2 i) == 0.2600749516525135959200648705635915 + 0.97024030779509898497385130162655963 i */ #define DELTA341 CHOOSE(BUILD_COMPLEX (6, 0), BUILD_COMPLEX (2, 0), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (6, 0), BUILD_COMPLEX (2, 0), BUILD_COMPLEX (1, 0)) /* catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i */ #define DELTA347 CHOOSE(716, 0, 0, 716, 0, 0) /* cbrt (-0.001) == -0.1 */ #define DELTA349 CHOOSE(1, 0, 0, 1, 0, 0) /* cbrt (-27.0) == -3.0 */ #define DELTA350 CHOOSE(306, 0, 0, 306, 0, 0) /* cbrt (0.970299) == 0.99 */ #define DELTA351 CHOOSE(346, 1, 0, 346, 1, 0) /* cbrt (0.7) == 0.8879040017426007084 */ #define DELTA389 CHOOSE(BUILD_COMPLEX (5, 1901), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (5, 1901), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (1, 0)) /* ccos (0.7 + 1.2 i) == 1.3848657645312111080 - 0.97242170335830028619 i */ #define DELTA390 CHOOSE(BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1)) /* ccos (-2 - 3 i) == -4.1896256909688072301 - 9.1092278937553365979 i */ #define DELTA428 CHOOSE(BUILD_COMPLEX (1467, 1183), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (1467, 1183), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (1, 0)) /* ccosh (0.7 + 1.2 i) == 0.4548202223691477654 + 0.7070296600921537682 i */ #define DELTA429 CHOOSE(BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* ccosh (-2 - 3 i) == -3.7245455049153225654 + 0.5118225699873846088 i */ #define DELTA469 CHOOSE(BUILD_COMPLEX (940, 0), 0, BUILD_COMPLEX (1, 0), BUILD_COMPLEX (940, 0), 0, BUILD_COMPLEX (1, 0)) /* cexp (0.7 + 1.2 i) == 0.72969890915032360123451688642930727 + 1.8768962328348102821139467908203072 i */ #define DELTA470 CHOOSE(BUILD_COMPLEX (4, 18), 0, 0, BUILD_COMPLEX (4, 18), 0, 0) /* cexp (-2.0 - 3.0 i) == -0.13398091492954261346140525546115575 - 0.019098516261135196432576240858800925 i */ #define DELTA515 CHOOSE(BUILD_COMPLEX (0, 1), 0, 0, BUILD_COMPLEX (0, 1), 0, 0) /* clog (-2 - 3 i) == 1.2824746787307683680267437207826593 - 2.1587989303424641704769327722648368 i */ #define DELTA520 CHOOSE(0, BUILD_COMPLEX (0, 1), 0, 0, BUILD_COMPLEX (0, 1), 0) /* clog10 (-inf + inf i) == inf + 3/4 pi*log10(e) i */ #define DELTA521 CHOOSE(0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* clog10 (inf + inf i) == inf + pi/4*log10(e) i */ #define DELTA522 CHOOSE(0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* clog10 (inf - inf i) == inf - pi/4*log10(e) i */ #define DELTA523 CHOOSE(0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* clog10 (0 + inf i) == inf + pi/2*log10(e) i */ #define DELTA524 CHOOSE(0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* clog10 (3 + inf i) == inf + pi/2*log10(e) i */ #define DELTA525 CHOOSE(0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* clog10 (-0 + inf i) == inf + pi/2*log10(e) i */ #define DELTA526 CHOOSE(0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* clog10 (-3 + inf i) == inf + pi/2*log10(e) i */ #define DELTA527 CHOOSE(0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* clog10 (0 - inf i) == inf - pi/2*log10(e) i */ #define DELTA528 CHOOSE(0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* clog10 (3 - inf i) == inf - pi/2*log10(e) i */ #define DELTA529 CHOOSE(0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* clog10 (-0 - inf i) == inf - pi/2*log10(e) i */ #define DELTA530 CHOOSE(0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* clog10 (-3 - inf i) == inf - pi/2*log10(e) i */ #define DELTA531 CHOOSE(0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* clog10 (-inf + 0 i) == inf + pi*log10(e) i */ #define DELTA532 CHOOSE(0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* clog10 (-inf + 1 i) == inf + pi*log10(e) i */ #define DELTA533 CHOOSE(0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* clog10 (-inf - 0 i) == inf - pi*log10(e) i */ #define DELTA534 CHOOSE(0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* clog10 (-inf - 1 i) == inf - pi*log10(e) i */ #define DELTA552 CHOOSE(BUILD_COMPLEX (1403, 186), BUILD_COMPLEX (2, 1), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (1403, 186), BUILD_COMPLEX (2, 1), BUILD_COMPLEX (1, 0)) /* clog10 (0.7 + 1.2 i) == 0.1427786545038868803 + 0.4528483579352493248 i */ #define DELTA553 CHOOSE(BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0) /* clog10 (-2 - 3 i) == 0.5569716761534183846 - 0.9375544629863747085 i */ #define DELTA582 CHOOSE(0, 1, 0.5, 0, 1, 0.5) /* cos (M_PI_6l * 2.0) == 0.5 */ #define DELTA583 CHOOSE(0.5, 2, 1, 0.5, 2, 1) /* cos (M_PI_6l * 4.0) == -0.5 */ #define DELTA584 CHOOSE(0.25, 0.2758, 0.3667, 0.25, 0.2758, 0.3667) /* cos (pi/2) == 0 */ #define DELTA585 CHOOSE(529, 1, 0, 529, 1, 0) /* cos (0.7) == 0.76484218728448842625585999019186495 */ #define DELTA591 CHOOSE(309, 0, 0, 309, 0, 0) /* cosh (0.7) == 1.255169005630943018 */ #define DELTA594 CHOOSE(BUILD_COMPLEX (0, 9), BUILD_COMPLEX (0, 1.104), BUILD_COMPLEX (0, 2.5333), BUILD_COMPLEX (0, 9), BUILD_COMPLEX (0, 1.104), BUILD_COMPLEX (0, 2.5333)) /* cpow (e + 0 i, 0 + 2 * M_PIl i) == 1.0 + 0.0 i */ #define DELTA595 CHOOSE(BUILD_COMPLEX (2, 5), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (4, 1), BUILD_COMPLEX (2, 5), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (4, 1)) /* cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i */ #define DELTA652 CHOOSE(BUILD_COMPLEX (966, 168), 0, 0, BUILD_COMPLEX (966, 168), 0, 0) /* csin (0.7 + 1.2 i) == 1.1664563419657581376 + 1.1544997246948547371 i */ #define DELTA691 CHOOSE(BUILD_COMPLEX (413, 477), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (413, 477), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (1, 0)) /* csinh (0.7 + 1.2 i) == 0.27487868678117583582 + 1.1698665727426565139 i */ #define DELTA692 CHOOSE(BUILD_COMPLEX (0, 2), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 2), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (0, 1)) /* csinh (-2 - 3 i) == 3.5905645899857799520 - 0.5309210862485198052 i */ #define DELTA732 CHOOSE(BUILD_COMPLEX (237, 128), BUILD_COMPLEX (1, 0), 0, BUILD_COMPLEX (237, 128), BUILD_COMPLEX (1, 0), 0) /* csqrt (0.7 + 1.2 i) == 1.022067610030026450706487883081139 + 0.58704531296356521154977678719838035 i */ #define DELTA733 CHOOSE(BUILD_COMPLEX (1, 0), 0, 0, BUILD_COMPLEX (1, 0), 0, 0) /* csqrt (-2 - 3 i) == 0.89597747612983812471573375529004348 - 1.6741492280355400404480393008490519 i */ #define DELTA734 CHOOSE(BUILD_COMPLEX (1, 0), 0, 0, BUILD_COMPLEX (1, 0), 0, 0) /* csqrt (-2 + 3 i) == 0.89597747612983812471573375529004348 + 1.6741492280355400404480393008490519 i */ #define DELTA766 CHOOSE(BUILD_COMPLEX (690, 367), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (690, 367), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (1, 0)) /* ctan (0.7 + 1.2 i) == 0.1720734197630349001 + 0.9544807059989405538 i */ #define DELTA767 CHOOSE(BUILD_COMPLEX (439, 2), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (439, 2), 0, BUILD_COMPLEX (0, 1)) /* ctan (-2 - 3 i) == 0.0037640256415042482 - 1.0032386273536098014 i */ #define DELTA799 CHOOSE(0, BUILD_COMPLEX (0, 0.5), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 0.5), BUILD_COMPLEX (0, 1)) /* ctanh (0 + pi/4 i) == 0.0 + 1.0 i */ #define DELTA800 CHOOSE(BUILD_COMPLEX (286, 3074), BUILD_COMPLEX (0, 1), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (286, 3074), BUILD_COMPLEX (0, 1), BUILD_COMPLEX (1, 0)) /* ctanh (0.7 + 1.2 i) == 1.3472197399061191630 + 0.4778641038326365540 i */ #define DELTA801 CHOOSE(BUILD_COMPLEX (5, 25), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (5, 25), 0, BUILD_COMPLEX (0, 1)) /* ctanh (-2 - 3 i) == -0.9653858790221331242 + 0.0098843750383224937 i */ #define DELTA817 CHOOSE(1, 1, 0, 1, 1, 0) /* erfc (0.7) == 0.32219880616258152702 */ #define DELTA818 CHOOSE(3, 1, 2, 3, 1, 2) /* erfc (1.2) == 0.089686021770364619762 */ #define DELTA819 CHOOSE(0, 1, 0, 0, 1, 0) /* erfc (2.0) == 0.0046777349810472658379 */ #define DELTA820 CHOOSE(12, 24, 12, 12, 24, 12) /* erfc (4.1) == 0.67000276540848983727e-8 */ #define DELTA821 CHOOSE(36, 0, 0, 36, 0, 0) /* erfc (9) == 0.41370317465138102381e-36 */ #define DELTA830 CHOOSE(412, 0, 0, 412, 0, 0) /* exp (0.7) == 2.0137527074704765216 */ #define DELTA831 CHOOSE(16, 0, 0, 16, 0, 0) /* exp (50.0) == 5184705528587072464087.45332293348538 */ #define DELTA832 CHOOSE(754, 0, 0, 754, 0, 0) /* exp (1000.0) == 0.197007111401704699388887935224332313e435 */ #define DELTA838 CHOOSE(8, 0, 0, 8, 0, 0) /* exp10 (3) == 1000 */ #define DELTA839 CHOOSE(818, 0, 0, 818, 0, 0) /* exp10 (-1) == 0.1 */ #define DELTA842 CHOOSE(1182, 1, 0, 1182, 1, 0) /* exp10 (0.7) == 5.0118723362727228500155418688494574 */ #define DELTA852 CHOOSE(462, 0, 0, 462, 0, 0) /* exp2 (0.7) == 1.6245047927124710452 */ #define DELTA859 CHOOSE(825, 0, 0, 825, 0, 0) /* expm1 (0.7) == 1.0137527074704765216 */ #define DELTA972 CHOOSE(4096, 2, 1, 4096, 2, 1) /* fmod (6.5, 2.3) == 1.9 */ #define DELTA973 CHOOSE(4096, 2, 1, 4096, 2, 1) /* fmod (-6.5, 2.3) == -1.9 */ #define DELTA974 CHOOSE(4096, 2, 1, 4096, 2, 1) /* fmod (6.5, -2.3) == 1.9 */ #define DELTA975 CHOOSE(4096, 2, 1, 4096, 2, 1) /* fmod (-6.5, -2.3) == -1.9 */ #define DELTA1004 CHOOSE(1, 1, 0, 1, 1, 0) /* gamma (-0.5) == log(2*sqrt(pi)) */ #define DELTA1013 CHOOSE(406, 0, 1, 406, 0, 0) /* hypot (0.7, 12.4) == 12.419742348374220601176836866763271 */ #define DELTA1014 CHOOSE(406, 0, 1, 406, 0, 0) /* hypot (-0.7, 12.4) == 12.419742348374220601176836866763271 */ #define DELTA1015 CHOOSE(406, 0, 1, 406, 0, 0) /* hypot (0.7, -12.4) == 12.419742348374220601176836866763271 */ #define DELTA1016 CHOOSE(406, 0, 1, 406, 0, 0) /* hypot (-0.7, -12.4) == 12.419742348374220601176836866763271 */ #define DELTA1017 CHOOSE(406, 0, 1, 406, 0, 0) /* hypot (12.4, 0.7) == 12.419742348374220601176836866763271 */ #define DELTA1018 CHOOSE(406, 0, 1, 406, 0, 0) /* hypot (-12.4, 0.7) == 12.419742348374220601176836866763271 */ #define DELTA1019 CHOOSE(406, 0, 1, 406, 0, 0) /* hypot (12.4, -0.7) == 12.419742348374220601176836866763271 */ #define DELTA1020 CHOOSE(406, 0, 1, 406, 0, 0) /* hypot (-12.4, -0.7) == 12.419742348374220601176836866763271 */ #define DELTA1024 CHOOSE(560, 1, 0, 560, 0, 0) /* hypot (0.7, 1.2) == 1.3892443989449804508432547041028554 */ #define DELTA1053 CHOOSE(0, 1, 1, 0, 1, 1) /* j0 (2.0) == 0.22389077914123566805 */ #define DELTA1054 CHOOSE(0, 0, 1, 0, 0, 1) /* j0 (8.0) == 0.17165080713755390609 */ #define DELTA1055 CHOOSE(0, 2, 1, 0, 2, 1) /* j0 (10.0) == -0.24593576445134833520 */ #define DELTA1064 CHOOSE(0, 1, 0, 0, 1, 0) /* j1 (2.0) == 0.57672480775687338720 */ #define DELTA1065 CHOOSE(1, 0, 1, 1, 0, 1) /* j1 (8.0) == 0.23463634685391462438 */ #define DELTA1066 CHOOSE(2, 2, 1, 2, 2, 1) /* j1 (10.0) == 0.043472746168861436670 */ #define DELTA1075 CHOOSE(0, 1, 1, 0, 1, 1) /* jn (0, 2.0) == 0.22389077914123566805 */ #define DELTA1076 CHOOSE(1, 0, 1, 1, 0, 1) /* jn (0, 8.0) == 0.17165080713755390609 */ #define DELTA1077 CHOOSE(2, 2, 1, 2, 2, 1) /* jn (0, 10.0) == -0.24593576445134833520 */ #define DELTA1086 CHOOSE(0, 1, 0, 0, 1, 0) /* jn (1, 2.0) == 0.57672480775687338720 */ #define DELTA1087 CHOOSE(1, 0, 1, 1, 0, 1) /* jn (1, 8.0) == 0.23463634685391462438 */ #define DELTA1088 CHOOSE(2, 2, 1, 2, 2, 1) /* jn (1, 10.0) == 0.043472746168861436670 */ #define DELTA1091 CHOOSE(1, 0, 0, 1, 0, 0) /* jn (3, -1.0) == -0.019563353982668405919 */ #define DELTA1093 CHOOSE(1, 1, 0, 1, 1, 0) /* jn (3, 0.1) == 0.000020820315754756261429 */ #define DELTA1094 CHOOSE(0, 2, 0, 0, 2, 0) /* jn (3, 0.7) == 0.0069296548267508408077 */ #define DELTA1095 CHOOSE(1, 0, 0, 1, 0, 0) /* jn (3, 1.0) == 0.019563353982668405919 */ #define DELTA1096 CHOOSE(0, 1, 1, 0, 1, 1) /* jn (3, 2.0) == 0.12894324947440205110 */ #define DELTA1097 CHOOSE(1, 3, 1, 1, 3, 1) /* jn (3, 10.0) == 0.058379379305186812343 */ #define DELTA1100 CHOOSE(1, 1, 1, 1, 1, 1) /* jn (10, -1.0) == 0.26306151236874532070e-9 */ #define DELTA1102 CHOOSE(1, 5, 2, 1, 5, 2) /* jn (10, 0.1) == 0.26905328954342155795e-19 */ #define DELTA1103 CHOOSE(2, 4, 1, 2, 4, 1) /* jn (10, 0.7) == 0.75175911502153953928e-11 */ #define DELTA1104 CHOOSE(1, 1, 1, 1, 1, 1) /* jn (10, 1.0) == 0.26306151236874532070e-9 */ #define DELTA1105 CHOOSE(1, 2, 1, 1, 2, 1) /* jn (10, 2.0) == 0.25153862827167367096e-6 */ #define DELTA1106 CHOOSE(2, 4, 2, 2, 4, 2) /* jn (10, 10.0) == 0.20748610663335885770 */ #define DELTA1126 CHOOSE(1, 1, 0, 1, 1, 0) /* lgamma (-0.5) == log(2*sqrt(pi)) */ #define DELTA1128 CHOOSE(0, 1, 1, 0, 1, 1) /* lgamma (0.7) == 0.26086724653166651439 */ #define DELTA1130 CHOOSE(1, 1, 2, 1, 1, 2) /* lgamma (1.2) == -0.853740900033158497197e-1 */ #define DELTA1163 CHOOSE(1, 0, 0.5, 1, 0, 0.5) /* log (e) == 1 */ #define DELTA1164 CHOOSE(1, 0, 0, 1, 0, 0) /* log (1.0 / M_El) == -1 */ #define DELTA1167 CHOOSE(2341, 1, 1, 2341, 1, 1) /* log (0.7) == -0.35667494393873237891263871124118447 */ #define DELTA1178 CHOOSE(1, 0, 1, 1, 0, 1) /* log10 (e) == log10(e) */ #define DELTA1179 CHOOSE(2033, 1, 0, 2033, 1, 0) /* log10 (0.7) == -0.15490195998574316929 */ #define DELTA1186 CHOOSE(1, 0, 0, 1, 0, 0) /* log1p (M_El - 1.0) == 1 */ #define DELTA1187 CHOOSE(585, 1, 1, 585, 1, 1) /* log1p (-0.3) == -0.35667494393873237891263871124118447 */ #define DELTA1198 CHOOSE(1688, 1, 1, 1688, 1, 1) /* log2 (0.7) == -0.51457317282975824043 */ #define DELTA1398 CHOOSE(725, 0, 0, 725, 0, 0) /* pow (0.7, 1.2) == 0.65180494056638638188 */ #define DELTA1524 CHOOSE(627, 0, 0, 627, 0, 0) /* sin (0.7) == 0.64421768723769105367261435139872014 */ #define DELTA1536 CHOOSE(0.25, 0.2758, 0.3667, 0.25, 0.2758, 0.3667) /* sincos (pi/2, &sin_res, &cos_res) puts 0 in cos_res */ #define DELTA1539 CHOOSE(1, 1, 1, 1, 1, 1) /* sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in sin_res */ #define DELTA1540 CHOOSE(0, 1, 0.5, 0, 1, 0.5) /* sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res */ #define DELTA1541 CHOOSE(627, 0, 0, 627, 0, 0) /* sincos (0.7, &sin_res, &cos_res) puts 0.64421768723769105367261435139872014 in sin_res */ #define DELTA1542 CHOOSE(528, 1, 0, 528, 1, 0) /* sincos (0.7, &sin_res, &cos_res) puts 0.76484218728448842625585999019186495 in cos_res */ #define DELTA1548 CHOOSE(1029, 0, 1, 1028, 0, 1) /* sinh (0.7) == 0.75858370183953350346 */ #define DELTA1562 CHOOSE(325, 0, 0, 325, 0, 0) /* sqrt (15239.9025) == 123.45 */ #define DELTA1569 CHOOSE(0, 0.5, 0, 0, 0.5, 0) /* tan (pi/4) == 1 */ #define DELTA1570 CHOOSE(1401, 0, 0, 1401, 0, 0) /* tan (0.7) == 0.84228838046307944812813500221293775 */ #define DELTA1576 CHOOSE(521, 0, 0, 521, 0, 0) /* tanh (0.7) == 0.60436777711716349631 */ #define DELTA1577 CHOOSE(1, 0, 0, 1, 0, 0) /* tanh (-0.7) == -0.60436777711716349631 */ #define DELTA1587 CHOOSE(0, 0, 1, 0, 0, 1) /* tgamma (0.5) == sqrt (pi) */ #define DELTA1588 CHOOSE(2, 2, 1, 2, 2, 1) /* tgamma (-0.5) == -2 sqrt (pi) */ #define DELTA1590 CHOOSE(2, 0, 0, 2, 0, 0) /* tgamma (4) == 6 */ #define DELTA1591 CHOOSE(0, 1, 1, 0, 1, 1) /* tgamma (0.7) == 1.29805533264755778568 */ #define DELTA1614 CHOOSE(0, 1, 1, 0, 1, 1) /* y0 (0.1) == -1.5342386513503668441 */ #define DELTA1615 CHOOSE(2, 3, 1, 2, 3, 1) /* y0 (0.7) == -0.19066492933739506743 */ #define DELTA1616 CHOOSE(0, 2, 1, 0, 2, 1) /* y0 (1.0) == 0.088256964215676957983 */ #define DELTA1617 CHOOSE(0, 1, 1, 0, 1, 1) /* y0 (1.5) == 0.38244892379775884396 */ #define DELTA1618 CHOOSE(0, 1, 0, 0, 1, 0) /* y0 (2.0) == 0.51037567264974511960 */ #define DELTA1619 CHOOSE(1, 1, 1, 1, 1, 1) /* y0 (8.0) == 0.22352148938756622053 */ #define DELTA1620 CHOOSE(1, 2, 1, 2, 2, 1) /* y0 (10.0) == 0.055671167283599391424 */ #define DELTA1625 CHOOSE(1, 1, 1, 1, 1, 1) /* y1 (0.1) == -6.4589510947020269877 */ #define DELTA1626 CHOOSE(0, 1, 0, 0, 1, 0) /* y1 (0.7) == -1.1032498719076333697 */ #define DELTA1627 CHOOSE(0, 1, 0, 0, 1, 0) /* y1 (1.0) == -0.78121282130028871655 */ #define DELTA1628 CHOOSE(0, 0, 1, 0, 0, 1) /* y1 (1.5) == -0.41230862697391129595 */ #define DELTA1629 CHOOSE(1, 1, 2, 1, 1, 2) /* y1 (2.0) == -0.10703243154093754689 */ #define DELTA1630 CHOOSE(2, 0, 2, 2, 0, 2) /* y1 (8.0) == -0.15806046173124749426 */ #define DELTA1631 CHOOSE(0, 3, 2, 0, 3, 2) /* y1 (10.0) == 0.24901542420695388392 */ #define DELTA1636 CHOOSE(0, 1, 1, 0, 1, 1) /* yn (0, 0.1) == -1.5342386513503668441 */ #define DELTA1637 CHOOSE(2, 3, 1, 2, 3, 1) /* yn (0, 0.7) == -0.19066492933739506743 */ #define DELTA1638 CHOOSE(0, 2, 1, 0, 2, 1) /* yn (0, 1.0) == 0.088256964215676957983 */ #define DELTA1639 CHOOSE(0, 1, 1, 0, 1, 1) /* yn (0, 1.5) == 0.38244892379775884396 */ #define DELTA1640 CHOOSE(0, 1, 0, 0, 1, 0) /* yn (0, 2.0) == 0.51037567264974511960 */ #define DELTA1641 CHOOSE(1, 1, 1, 1, 1, 1) /* yn (0, 8.0) == 0.22352148938756622053 */ #define DELTA1642 CHOOSE(1, 2, 1, 1, 2, 1) /* yn (0, 10.0) == 0.055671167283599391424 */ #define DELTA1647 CHOOSE(1, 1, 1, 1, 1, 1) /* yn (1, 0.1) == -6.4589510947020269877 */ #define DELTA1648 CHOOSE(0, 1, 0, 0, 1, 0) /* yn (1, 0.7) == -1.1032498719076333697 */ #define DELTA1649 CHOOSE(0, 1, 0, 0, 1, 0) /* yn (1, 1.0) == -0.78121282130028871655 */ #define DELTA1650 CHOOSE(0, 0, 1, 0, 0, 1) /* yn (1, 1.5) == -0.41230862697391129595 */ #define DELTA1651 CHOOSE(1, 1, 2, 1, 1, 2) /* yn (1, 2.0) == -0.10703243154093754689 */ #define DELTA1652 CHOOSE(2, 0, 2, 2, 0, 2) /* yn (1, 8.0) == -0.15806046173124749426 */ #define DELTA1653 CHOOSE(0, 3, 2, 0, 3, 2) /* yn (1, 10.0) == 0.24901542420695388392 */ #define DELTA1656 CHOOSE(2, 1, 1, 2, 1, 1) /* yn (3, 0.1) == -5099.3323786129048894 */ #define DELTA1657 CHOOSE(2, 3, 1, 2, 3, 1) /* yn (3, 0.7) == -15.819479052819633505 */ #define DELTA1659 CHOOSE(0, 1, 1, 0, 1, 1) /* yn (3, 2.0) == -1.1277837768404277861 */ #define DELTA1660 CHOOSE(0, 1, 1, 0, 1, 1) /* yn (3, 10.0) == -0.25136265718383732978 */ #define DELTA1663 CHOOSE(2, 2, 1, 2, 2, 1) /* yn (10, 0.1) == -0.11831335132045197885e19 */ #define DELTA1664 CHOOSE(7, 6, 3, 7, 6, 3) /* yn (10, 0.7) == -0.42447194260703866924e10 */ #define DELTA1665 CHOOSE(0, 1, 1, 0, 1, 1) /* yn (10, 1.0) == -0.12161801427868918929e9 */ #define DELTA1666 CHOOSE(1, 2, 1, 1, 2, 1) /* yn (10, 2.0) == -129184.54220803928264 */ #define DELTA1667 CHOOSE(0, 2, 1, 0, 2, 1) /* yn (10, 10.0) == -0.35981415218340272205 */ openlibm-0.5.0/test/libm-test.c000066400000000000000000007647021266752446200164020ustar00rootroot00000000000000/* Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Andreas Jaeger , 1997. 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ /* Part of testsuite for libm. This file is processed by a perl script. The resulting file has to be included by a master file that defines: Makros: FUNC(function): converts general function name (like cos) to name with correct suffix (e.g. cosl or cosf) MATHCONST(x): like FUNC but for constants (e.g convert 0.0 to 0.0L) FLOAT: floating point type to test - TEST_MSG: informal message to be displayed CHOOSE(Clongdouble,Cdouble,Cfloat,Cinlinelongdouble,Cinlinedouble,Cinlinefloat): chooses one of the parameters as delta for testing equality PRINTF_EXPR Floating point conversion specification to print a variable of type FLOAT with printf. PRINTF_EXPR just contains the specifier, not the percent and width arguments, e.g. "f". PRINTF_XEXPR Like PRINTF_EXPR, but print in hexadecimal format. PRINTF_NEXPR Like PRINTF_EXPR, but print nice. */ /* This testsuite has currently tests for: acos, acosh, asin, asinh, atan, atan2, atanh, cbrt, ceil, copysign, cos, cosh, erf, erfc, exp, exp10, exp2, expm1, fabs, fdim, floor, fma, fmax, fmin, fmod, fpclassify, frexp, gamma, hypot, ilogb, isfinite, isinf, isnan, isnormal, isless, islessequal, isgreater, isgreaterequal, islessgreater, isunordered, j0, j1, jn, ldexp, lgamma, log, log10, log1p, log2, logb, modf, nearbyint, nextafter, pow, remainder, remquo, rint, lrint, llrint, round, lround, llround, scalb, scalbn, scalbln, signbit, sin, sincos, sinh, sqrt, tan, tanh, tgamma, trunc, y0, y1, yn and for the following complex math functions: cabs, cacos, cacosh, carg, casin, casinh, catan, catanh, ccos, ccosh, cexp, clog, cpow, cproj, csin, csinh, csqrt, ctan, ctanh. At the moment the following functions aren't tested: drem, significand, nan Parameter handling is primitive in the moment: --verbose=[0..3] for different levels of output: 0: only error count 1: basic report on failed tests (default) 2: full report on all tests -v for full output (equals --verbose=3) -u for generation of an ULPs file */ /* "Philosophy": This suite tests some aspects of the correct implementation of mathematical functions in libm. Some simple, specific parameters are tested for correctness but there's no exhaustive testing. Handling of specific inputs (e.g. infinity, not-a-number) is also tested. Correct handling of exceptions is checked against. These implemented tests should check all cases that are specified in ISO C99. Exception testing: At the moment only divide-by-zero and invalid exceptions are tested. Overflow/underflow and inexact exceptions aren't checked at the moment. NaN values: There exist signalling and quiet NaNs. This implementation only uses signalling NaN as parameter but does not differenciate between the two kinds of NaNs as result. Inline functions: Inlining functions should give an improvement in speed - but not in precission. The inlined functions return reasonable values for a reasonable range of input values. The result is not necessarily correct for all values and exceptions are not correctly raised in all cases. Problematic input and return values are infinity, not-a-number and minus zero. This suite therefore does not check these specific inputs and the exception handling for inlined mathematical functions - just the "reasonable" values are checked. Beware: The tests might fail for any of the following reasons: - Tests are wrong - Functions are wrong - Floating Point Unit not working properly - Compiler has errors With e.g. gcc 2.7.2.2 the test for cexp fails because of a compiler error. To Do: All parameter should be numbers that can be represented as exact floating point values. Currently some values cannot be represented exactly and therefore the result is not the expected result. */ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #include "libm-test-ulps.h" #include #ifdef SYS_MATH_H #include #include #else #include #endif #if 0 /* XXX scp XXX */ #define FE_INEXACT FE_INEXACT #define FE_DIVBYZERO FE_DIVBYZERO #define FE_UNDERFLOW FE_UNDERFLOW #define FE_OVERFLOW FE_OVERFLOW #define FE_INVALID FE_INVALID #endif #include #include #include #include #include #if 0 /* XXX scp XXX */ #include #endif // Some native libm implementations don't have sincos defined, so we have to do it ourselves void FUNC(sincos) (FLOAT x, FLOAT * s, FLOAT * c); #ifdef __APPLE__ #ifdef SYS_MATH_H void sincos(FLOAT x, FLOAT * s, FLOAT * c) { *s = sin(x); *c = cos(x); } #endif #endif /* Possible exceptions */ #define NO_EXCEPTION 0x0 #define INVALID_EXCEPTION 0x1 #define DIVIDE_BY_ZERO_EXCEPTION 0x2 /* The next flags signals that those exceptions are allowed but not required. */ #define INVALID_EXCEPTION_OK 0x4 #define DIVIDE_BY_ZERO_EXCEPTION_OK 0x8 #define EXCEPTIONS_OK INVALID_EXCEPTION_OK+DIVIDE_BY_ZERO_EXCEPTION_OK /* Some special test flags, passed togther with exceptions. */ #define IGNORE_ZERO_INF_SIGN 0x10 /* Various constants (we must supply them precalculated for accuracy). */ #define M_PI_6l .52359877559829887307710723054658383L #define M_E2l 7.389056098930650227230427460575008L #define M_E3l 20.085536923187667740928529654581719L #define M_2_SQRT_PIl 3.5449077018110320545963349666822903L /* 2 sqrt (M_PIl) */ #define M_SQRT_PIl 1.7724538509055160272981674833411451L /* sqrt (M_PIl) */ #define M_LOG_SQRT_PIl 0.57236494292470008707171367567652933L /* log(sqrt(M_PIl)) */ #define M_LOG_2_SQRT_PIl 1.265512123484645396488945797134706L /* log(2*sqrt(M_PIl)) */ #define M_PI_34l (M_PIl - M_PI_4l) /* 3*pi/4 */ #define M_PI_34_LOG10El (M_PIl - M_PI_4l) * M_LOG10El #define M_PI2_LOG10El M_PI_2l * M_LOG10El #define M_PI4_LOG10El M_PI_4l * M_LOG10El #define M_PI_LOG10El M_PIl * M_LOG10El #if 1 /* XXX scp XXX */ # define M_El 2.7182818284590452353602874713526625L /* e */ # define M_LOG2El 1.4426950408889634073599246810018922L /* log_2 e */ # define M_LOG10El 0.4342944819032518276511289189166051L /* log_10 e */ # define M_LN2l 0.6931471805599453094172321214581766L /* log_e 2 */ # define M_LN10l 2.3025850929940456840179914546843642L /* log_e 10 */ # define M_PIl 3.1415926535897932384626433832795029L /* pi */ # define M_PI_2l 1.5707963267948966192313216916397514L /* pi/2 */ # define M_PI_4l 0.7853981633974483096156608458198757L /* pi/4 */ # define M_1_PIl 0.3183098861837906715377675267450287L /* 1/pi */ # define M_2_PIl 0.6366197723675813430755350534900574L /* 2/pi */ # define M_2_SQRTPIl 1.1283791670955125738961589031215452L /* 2/sqrt(pi) */ # define M_SQRT2l 1.4142135623730950488016887242096981L /* sqrt(2) */ # define M_SQRT1_2l 0.7071067811865475244008443621048490L /* 1/sqrt(2) */ #endif static FILE *ulps_file; /* File to document difference. */ static int output_ulps; /* Should ulps printed? */ static int noErrors; /* number of errors */ static int noTests; /* number of tests (without testing exceptions) */ static int noExcTests; /* number of tests for exception flags */ static int noXFails; /* number of expected failures. */ static int noXPasses; /* number of unexpected passes. */ static int verbose; static int output_max_error; /* Should the maximal errors printed? */ static int output_points; /* Should the single function results printed? */ static int ignore_max_ulp; /* Should we ignore max_ulp? */ static FLOAT minus_zero, plus_zero; static FLOAT plus_infty, minus_infty, nan_value; static FLOAT max_error, real_max_error, imag_max_error; #if 0 /* XXX scp XXX */ #define BUILD_COMPLEX(real, imag) \ ({ __complex__ FLOAT __retval; \ __real__ __retval = (real); \ __imag__ __retval = (imag); \ __retval; }) #define BUILD_COMPLEX_INT(real, imag) \ ({ __complex__ int __retval; \ __real__ __retval = (real); \ __imag__ __retval = (imag); \ __retval; }) #endif #define MANT_DIG CHOOSE ((LDBL_MANT_DIG-1), (DBL_MANT_DIG-1), (FLT_MANT_DIG-1), \ (LDBL_MANT_DIG-1), (DBL_MANT_DIG-1), (FLT_MANT_DIG-1)) static void init_max_error (void) { max_error = 0; real_max_error = 0; imag_max_error = 0; feclearexcept (FE_ALL_EXCEPT); } static void set_max_error (FLOAT current, FLOAT *curr_max_error) { if (current > *curr_max_error) *curr_max_error = current; } /* Should the message print to screen? This depends on the verbose flag, and the test status. */ static int print_screen (int ok, int xfail) { if (output_points && (verbose > 1 || (verbose == 1 && ok == xfail))) return 1; return 0; } /* Should the message print to screen? This depends on the verbose flag, and the test status. */ static int print_screen_max_error (int ok, int xfail) { if (output_max_error && (verbose > 1 || ((verbose == 1) && (ok == xfail)))) return 1; return 0; } /* Update statistic counters. */ static void update_stats (int ok, int xfail) { ++noTests; if (ok && xfail) ++noXPasses; else if (!ok && xfail) ++noXFails; else if (!ok && !xfail) ++noErrors; } static void print_ulps (const char *test_name, FLOAT ulp) { if (output_ulps) { fprintf (ulps_file, "Test \"%s\":\n", test_name); fprintf (ulps_file, "%s: % .4" PRINTF_NEXPR "\n", CHOOSE("ldouble", "double", "float", "ildouble", "idouble", "ifloat"), ulp); } } static void print_function_ulps (const char *function_name, FLOAT ulp) { if (output_ulps) { fprintf (ulps_file, "Function: \"%s\":\n", function_name); fprintf (ulps_file, "%s: % .4" PRINTF_NEXPR "\n", CHOOSE("ldouble", "double", "float", "ildouble", "idouble", "ifloat"), ulp); } } #if 0 /* XXX scp XXX */ static void print_complex_function_ulps (const char *function_name, FLOAT real_ulp, FLOAT imag_ulp) { if (output_ulps) { if (real_ulp != 0.0) { fprintf (ulps_file, "Function: Real part of \"%s\":\n", function_name); fprintf (ulps_file, "%s: % .4" PRINTF_NEXPR "\n", CHOOSE("ldouble", "double", "float", "ildouble", "idouble", "ifloat"), real_ulp); } if (imag_ulp != 0.0) { fprintf (ulps_file, "Function: Imaginary part of \"%s\":\n", function_name); fprintf (ulps_file, "%s: % .4" PRINTF_NEXPR "\n", CHOOSE("ldouble", "double", "float", "ildouble", "idouble", "ifloat"), imag_ulp); } } } #endif static void print_max_error (const char *func_name, FLOAT allowed, int xfail) { int ok = 0; if (max_error == 0.0 || (max_error <= allowed && !ignore_max_ulp)) { ok = 1; } if (!ok) print_function_ulps (func_name, max_error); if (print_screen_max_error (ok, xfail)) { printf ("Maximal error of `%s'\n", func_name); printf (" is : % .4" PRINTF_NEXPR " ulp\n", max_error); printf (" accepted: % .4" PRINTF_NEXPR " ulp\n", allowed); } update_stats (ok, xfail); } #if 0 /* XXX scp XXX */ static void print_complex_max_error (const char *func_name, __complex__ FLOAT allowed, __complex__ int xfail) { int ok = 0; if ((real_max_error <= __real__ allowed) && (imag_max_error <= __imag__ allowed)) { ok = 1; } if (!ok) print_complex_function_ulps (func_name, real_max_error, imag_max_error); if (print_screen_max_error (ok, xfail)) { printf ("Maximal error of real part of: %s\n", func_name); printf (" is : % .4" PRINTF_NEXPR " ulp\n", real_max_error); printf (" accepted: % .4" PRINTF_NEXPR " ulp\n", __real__ allowed); printf ("Maximal error of imaginary part of: %s\n", func_name); printf (" is : % .4" PRINTF_NEXPR " ulp\n", imag_max_error); printf (" accepted: % .4" PRINTF_NEXPR " ulp\n", __imag__ allowed); } update_stats (ok, xfail); } #endif /* Test whether a given exception was raised. */ static void test_single_exception (const char *test_name, int exception, int exc_flag, int fe_flag, const char *flag_name) { #ifndef TEST_INLINE int ok = 1; if (exception & exc_flag) { if (fetestexcept (fe_flag)) { if (print_screen (1, 0)) printf ("Pass: %s: Exception \"%s\" set\n", test_name, flag_name); } else { ok = 0; if (print_screen (0, 0)) printf ("Failure: %s: Exception \"%s\" not set\n", test_name, flag_name); } } else { if (fetestexcept (fe_flag)) { ok = 0; if (print_screen (0, 0)) printf ("Failure: %s: Exception \"%s\" set\n", test_name, flag_name); } else { if (print_screen (1, 0)) printf ("%s: Exception \"%s\" not set\n", test_name, flag_name); } } if (!ok) ++noErrors; #endif } /* Test whether exceptions given by EXCEPTION are raised. Ignore thereby allowed but not required exceptions. */ static void test_exceptions (const char *test_name, int exception) { ++noExcTests; #ifdef FE_DIVBYZERO if ((exception & DIVIDE_BY_ZERO_EXCEPTION_OK) == 0) test_single_exception (test_name, exception, DIVIDE_BY_ZERO_EXCEPTION, FE_DIVBYZERO, "Divide by zero"); #endif #ifdef FE_INVALID if ((exception & INVALID_EXCEPTION_OK) == 0) test_single_exception (test_name, exception, INVALID_EXCEPTION, FE_INVALID, "Invalid operation"); #endif feclearexcept (FE_ALL_EXCEPT); } static void check_float_internal (const char *test_name, FLOAT computed, FLOAT expected, FLOAT max_ulp, int xfail, int exceptions, FLOAT *curr_max_error) { int ok = 0; int print_diff = 0; FLOAT diff = 0; FLOAT ulp = 0; test_exceptions (test_name, exceptions); if (isnan (computed) && isnan (expected)) ok = 1; else if (isinf (computed) && isinf (expected)) { /* Test for sign of infinities. */ if ((exceptions & IGNORE_ZERO_INF_SIGN) == 0 && signbit (computed) != signbit (expected)) { ok = 0; printf ("infinity has wrong sign.\n"); } else ok = 1; } /* Don't calc ulp for NaNs or infinities. */ else if (isinf (computed) || isnan (computed) || isinf (expected) || isnan (expected)) ok = 0; else { diff = FUNC(fabs) (computed - expected); /* ilogb (0) isn't allowed. */ if (expected == 0.0) ulp = diff / FUNC(ldexp) (1.0, - MANT_DIG); else ulp = diff / FUNC(ldexp) (1.0, FUNC(ilogb) (expected) - MANT_DIG); set_max_error (ulp, curr_max_error); print_diff = 1; if ((exceptions & IGNORE_ZERO_INF_SIGN) == 0 && computed == 0.0 && expected == 0.0 && signbit(computed) != signbit (expected)) ok = 0; else if (ulp == 0.0 || (ulp <= max_ulp && !ignore_max_ulp)) ok = 1; else { ok = 0; print_ulps (test_name, ulp); } } if (print_screen (ok, xfail)) { if (!ok) printf ("Failure: "); printf ("Test: %s\n", test_name); printf ("Result:\n"); printf (" is: % .20" PRINTF_EXPR " % .20" PRINTF_XEXPR "\n", computed, computed); printf (" should be: % .20" PRINTF_EXPR " % .20" PRINTF_XEXPR "\n", expected, expected); if (print_diff) { printf (" difference: % .20" PRINTF_EXPR " % .20" PRINTF_XEXPR "\n", diff, diff); printf (" ulp : % .4" PRINTF_NEXPR "\n", ulp); printf (" max.ulp : % .4" PRINTF_NEXPR "\n", max_ulp); } } update_stats (ok, xfail); } static void check_float (const char *test_name, FLOAT computed, FLOAT expected, FLOAT max_ulp, int xfail, int exceptions) { check_float_internal (test_name, computed, expected, max_ulp, xfail, exceptions, &max_error); } #if 0 /* XXX scp XXX */ static void check_complex (const char *test_name, __complex__ FLOAT computed, __complex__ FLOAT expected, __complex__ FLOAT max_ulp, __complex__ int xfail, int exception) { FLOAT part_comp, part_exp, part_max_ulp; int part_xfail; char str[200]; sprintf (str, "Real part of: %s", test_name); part_comp = __real__ computed; part_exp = __real__ expected; part_max_ulp = __real__ max_ulp; part_xfail = __real__ xfail; check_float_internal (str, part_comp, part_exp, part_max_ulp, part_xfail, exception, &real_max_error); sprintf (str, "Imaginary part of: %s", test_name); part_comp = __imag__ computed; part_exp = __imag__ expected; part_max_ulp = __imag__ max_ulp; part_xfail = __imag__ xfail; /* Don't check again for exceptions, just pass through the zero/inf sign test. */ check_float_internal (str, part_comp, part_exp, part_max_ulp, part_xfail, exception & IGNORE_ZERO_INF_SIGN, &imag_max_error); } #endif /* Check that computed and expected values are equal (int values). */ static void check_int (const char *test_name, int computed, int expected, int max_ulp, int xfail, int exceptions) { int diff = computed - expected; int ok = 0; test_exceptions (test_name, exceptions); noTests++; if (abs (diff) <= max_ulp) ok = 1; if (!ok) print_ulps (test_name, diff); if (print_screen (ok, xfail)) { if (!ok) printf ("Failure: "); printf ("Test: %s\n", test_name); printf ("Result:\n"); printf (" is: %d\n", computed); printf (" should be: %d\n", expected); } update_stats (ok, xfail); } /* Check that computed and expected values are equal (long int values). */ static void check_long (const char *test_name, long int computed, long int expected, long int max_ulp, int xfail, int exceptions) { long int diff = computed - expected; int ok = 0; test_exceptions (test_name, exceptions); noTests++; if (labs (diff) <= max_ulp) ok = 1; if (!ok) print_ulps (test_name, diff); if (print_screen (ok, xfail)) { if (!ok) printf ("Failure: "); printf ("Test: %s\n", test_name); printf ("Result:\n"); printf (" is: %ld\n", computed); printf (" should be: %ld\n", expected); } update_stats (ok, xfail); } /* Check that computed value is true/false. */ static void check_bool (const char *test_name, int computed, int expected, long int max_ulp, int xfail, int exceptions) { int ok = 0; test_exceptions (test_name, exceptions); noTests++; if ((computed == 0) == (expected == 0)) ok = 1; if (print_screen (ok, xfail)) { if (!ok) printf ("Failure: "); printf ("Test: %s\n", test_name); printf ("Result:\n"); printf (" is: %d\n", computed); printf (" should be: %d\n", expected); } update_stats (ok, xfail); } /* check that computed and expected values are equal (long int values) */ static void check_longlong (const char *test_name, long long int computed, long long int expected, long long int max_ulp, int xfail, int exceptions) { long long int diff = computed - expected; int ok = 0; test_exceptions (test_name, exceptions); noTests++; if (llabs (diff) <= max_ulp) ok = 1; if (!ok) print_ulps (test_name, diff); if (print_screen (ok, xfail)) { if (!ok) printf ("Failure:"); printf ("Test: %s\n", test_name); printf ("Result:\n"); printf (" is: %lld\n", computed); printf (" should be: %lld\n", expected); } update_stats (ok, xfail); } #if 0 /* XXX scp XXX */ /* This is to prevent messages from the SVID libm emulation. */ int matherr (struct exception *x __attribute__ ((unused))) { return 1; } #endif /**************************************************************************** Tests for single functions of libm. Please keep them alphabetically sorted! ****************************************************************************/ static void acos_test (void) { errno = 0; FUNC(acos) (0); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_float ("acos (inf) == NaN plus invalid exception", FUNC(acos) (plus_infty), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("acos (-inf) == NaN plus invalid exception", FUNC(acos) (minus_infty), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("acos (NaN) == NaN", FUNC(acos) (nan_value), nan_value, 0, 0, 0); /* |x| > 1: */ check_float ("acos (1.1) == NaN plus invalid exception", FUNC(acos) (1.1L), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("acos (-1.1) == NaN plus invalid exception", FUNC(acos) (-1.1L), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("acos (0) == pi/2", FUNC(acos) (0), M_PI_2l, 0, 0, 0); check_float ("acos (-0) == pi/2", FUNC(acos) (minus_zero), M_PI_2l, 0, 0, 0); check_float ("acos (1) == 0", FUNC(acos) (1), 0, 0, 0, 0); check_float ("acos (-1) == pi", FUNC(acos) (-1), M_PIl, 0, 0, 0); check_float ("acos (0.5) == M_PI_6l*2.0", FUNC(acos) (0.5), M_PI_6l*2.0, 0, 0, 0); check_float ("acos (-0.5) == M_PI_6l*4.0", FUNC(acos) (-0.5), M_PI_6l*4.0, 0, 0, 0); check_float ("acos (0.7) == 0.79539883018414355549096833892476432", FUNC(acos) (0.7L), 0.79539883018414355549096833892476432L, 0, 0, 0); print_max_error ("acos", DELTAacos, 0); } static void acosh_test (void) { errno = 0; FUNC(acosh) (7); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_float ("acosh (inf) == inf", FUNC(acosh) (plus_infty), plus_infty, 0, 0, 0); check_float ("acosh (-inf) == NaN plus invalid exception", FUNC(acosh) (minus_infty), nan_value, 0, 0, INVALID_EXCEPTION); /* x < 1: */ check_float ("acosh (-1.1) == NaN plus invalid exception", FUNC(acosh) (-1.1L), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("acosh (1) == 0", FUNC(acosh) (1), 0, 0, 0, 0); check_float ("acosh (7) == 2.633915793849633417250092694615937", FUNC(acosh) (7), 2.633915793849633417250092694615937L, DELTA16, 0, 0); print_max_error ("acosh", DELTAacosh, 0); } static void asin_test (void) { errno = 0; FUNC(asin) (0); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_float ("asin (inf) == NaN plus invalid exception", FUNC(asin) (plus_infty), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("asin (-inf) == NaN plus invalid exception", FUNC(asin) (minus_infty), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("asin (NaN) == NaN", FUNC(asin) (nan_value), nan_value, 0, 0, 0); /* asin x == NaN plus invalid exception for |x| > 1. */ check_float ("asin (1.1) == NaN plus invalid exception", FUNC(asin) (1.1L), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("asin (-1.1) == NaN plus invalid exception", FUNC(asin) (-1.1L), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("asin (0) == 0", FUNC(asin) (0), 0, 0, 0, 0); check_float ("asin (-0) == -0", FUNC(asin) (minus_zero), minus_zero, 0, 0, 0); check_float ("asin (0.5) == pi/6", FUNC(asin) (0.5), M_PI_6l, DELTA24, 0, 0); check_float ("asin (-0.5) == -pi/6", FUNC(asin) (-0.5), -M_PI_6l, DELTA25, 0, 0); check_float ("asin (1.0) == pi/2", FUNC(asin) (1.0), M_PI_2l, DELTA26, 0, 0); check_float ("asin (-1.0) == -pi/2", FUNC(asin) (-1.0), -M_PI_2l, DELTA27, 0, 0); check_float ("asin (0.7) == 0.77539749661075306374035335271498708", FUNC(asin) (0.7L), 0.77539749661075306374035335271498708L, DELTA28, 0, 0); print_max_error ("asin", DELTAasin, 0); } static void asinh_test (void) { errno = 0; FUNC(asinh) (0.7L); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_float ("asinh (0) == 0", FUNC(asinh) (0), 0, 0, 0, 0); check_float ("asinh (-0) == -0", FUNC(asinh) (minus_zero), minus_zero, 0, 0, 0); #ifndef TEST_INLINE check_float ("asinh (inf) == inf", FUNC(asinh) (plus_infty), plus_infty, 0, 0, 0); check_float ("asinh (-inf) == -inf", FUNC(asinh) (minus_infty), minus_infty, 0, 0, 0); #endif check_float ("asinh (NaN) == NaN", FUNC(asinh) (nan_value), nan_value, 0, 0, 0); check_float ("asinh (0.7) == 0.652666566082355786", FUNC(asinh) (0.7L), 0.652666566082355786L, DELTA34, 0, 0); print_max_error ("asinh", DELTAasinh, 0); } static void atan_test (void) { errno = 0; FUNC(atan) (0); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_float ("atan (0) == 0", FUNC(atan) (0), 0, 0, 0, 0); check_float ("atan (-0) == -0", FUNC(atan) (minus_zero), minus_zero, 0, 0, 0); check_float ("atan (inf) == pi/2", FUNC(atan) (plus_infty), M_PI_2l, 0, 0, 0); check_float ("atan (-inf) == -pi/2", FUNC(atan) (minus_infty), -M_PI_2l, 0, 0, 0); check_float ("atan (NaN) == NaN", FUNC(atan) (nan_value), nan_value, 0, 0, 0); check_float ("atan (1) == pi/4", FUNC(atan) (1), M_PI_4l, 0, 0, 0); check_float ("atan (-1) == -pi/4", FUNC(atan) (-1), -M_PI_4l, 0, 0, 0); check_float ("atan (0.7) == 0.61072596438920861654375887649023613", FUNC(atan) (0.7L), 0.61072596438920861654375887649023613L, DELTA42, 0, 0); print_max_error ("atan", DELTAatan, 0); } static void atanh_test (void) { errno = 0; FUNC(atanh) (0.7L); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_float ("atanh (0) == 0", FUNC(atanh) (0), 0, 0, 0, 0); check_float ("atanh (-0) == -0", FUNC(atanh) (minus_zero), minus_zero, 0, 0, 0); check_float ("atanh (1) == inf plus division by zero exception", FUNC(atanh) (1), plus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_float ("atanh (-1) == -inf plus division by zero exception", FUNC(atanh) (-1), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_float ("atanh (NaN) == NaN", FUNC(atanh) (nan_value), nan_value, 0, 0, 0); /* atanh (x) == NaN plus invalid exception if |x| > 1. */ check_float ("atanh (1.1) == NaN plus invalid exception", FUNC(atanh) (1.1L), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("atanh (-1.1) == NaN plus invalid exception", FUNC(atanh) (-1.1L), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("atanh (0.7) == 0.8673005276940531944", FUNC(atanh) (0.7L), 0.8673005276940531944L, DELTA50, 0, 0); print_max_error ("atanh", DELTAatanh, 0); } static void atan2_test (void) { errno = 0; FUNC(atan2) (-0, 1); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); /* atan2 (0,x) == 0 for x > 0. */ check_float ("atan2 (0, 1) == 0", FUNC(atan2) (0, 1), 0, 0, 0, 0); /* atan2 (-0,x) == -0 for x > 0. */ check_float ("atan2 (-0, 1) == -0", FUNC(atan2) (minus_zero, 1), minus_zero, 0, 0, 0); check_float ("atan2 (0, 0) == 0", FUNC(atan2) (0, 0), 0, 0, 0, 0); check_float ("atan2 (-0, 0) == -0", FUNC(atan2) (minus_zero, 0), minus_zero, 0, 0, 0); /* atan2 (+0,x) == +pi for x < 0. */ check_float ("atan2 (0, -1) == pi", FUNC(atan2) (0, -1), M_PIl, 0, 0, 0); /* atan2 (-0,x) == -pi for x < 0. */ check_float ("atan2 (-0, -1) == -pi", FUNC(atan2) (minus_zero, -1), -M_PIl, 0, 0, 0); check_float ("atan2 (0, -0) == pi", FUNC(atan2) (0, minus_zero), M_PIl, 0, 0, 0); check_float ("atan2 (-0, -0) == -pi", FUNC(atan2) (minus_zero, minus_zero), -M_PIl, 0, 0, 0); /* atan2 (y,+0) == pi/2 for y > 0. */ check_float ("atan2 (1, 0) == pi/2", FUNC(atan2) (1, 0), M_PI_2l, 0, 0, 0); /* atan2 (y,-0) == pi/2 for y > 0. */ check_float ("atan2 (1, -0) == pi/2", FUNC(atan2) (1, minus_zero), M_PI_2l, 0, 0, 0); /* atan2 (y,+0) == -pi/2 for y < 0. */ check_float ("atan2 (-1, 0) == -pi/2", FUNC(atan2) (-1, 0), -M_PI_2l, 0, 0, 0); /* atan2 (y,-0) == -pi/2 for y < 0. */ check_float ("atan2 (-1, -0) == -pi/2", FUNC(atan2) (-1, minus_zero), -M_PI_2l, 0, 0, 0); /* atan2 (y,inf) == +0 for finite y > 0. */ check_float ("atan2 (1, inf) == 0", FUNC(atan2) (1, plus_infty), 0, 0, 0, 0); /* atan2 (y,inf) == -0 for finite y < 0. */ check_float ("atan2 (-1, inf) == -0", FUNC(atan2) (-1, plus_infty), minus_zero, 0, 0, 0); /* atan2(+inf, x) == pi/2 for finite x. */ check_float ("atan2 (inf, -1) == pi/2", FUNC(atan2) (plus_infty, -1), M_PI_2l, 0, 0, 0); /* atan2(-inf, x) == -pi/2 for finite x. */ check_float ("atan2 (-inf, 1) == -pi/2", FUNC(atan2) (minus_infty, 1), -M_PI_2l, 0, 0, 0); /* atan2 (y,-inf) == +pi for finite y > 0. */ check_float ("atan2 (1, -inf) == pi", FUNC(atan2) (1, minus_infty), M_PIl, 0, 0, 0); /* atan2 (y,-inf) == -pi for finite y < 0. */ check_float ("atan2 (-1, -inf) == -pi", FUNC(atan2) (-1, minus_infty), -M_PIl, 0, 0, 0); check_float ("atan2 (inf, inf) == pi/4", FUNC(atan2) (plus_infty, plus_infty), M_PI_4l, 0, 0, 0); check_float ("atan2 (-inf, inf) == -pi/4", FUNC(atan2) (minus_infty, plus_infty), -M_PI_4l, 0, 0, 0); check_float ("atan2 (inf, -inf) == 3/4 pi", FUNC(atan2) (plus_infty, minus_infty), M_PI_34l, 0, 0, 0); check_float ("atan2 (-inf, -inf) == -3/4 pi", FUNC(atan2) (minus_infty, minus_infty), -M_PI_34l, 0, 0, 0); check_float ("atan2 (NaN, NaN) == NaN", FUNC(atan2) (nan_value, nan_value), nan_value, 0, 0, 0); check_float ("atan2 (0.7, 1) == 0.61072596438920861654375887649023613", FUNC(atan2) (0.7L, 1), 0.61072596438920861654375887649023613L, DELTA74, 0, 0); check_float ("atan2 (-0.7, 1.0) == -0.61072596438920861654375887649023613", FUNC(atan2) (-0.7L, 1.0L), -0.61072596438920861654375887649023613L, 0, 0, 0); check_float ("atan2 (0.7, -1.0) == 2.530866689200584621918884506789267", FUNC(atan2) (0.7L, -1.0L), 2.530866689200584621918884506789267L, 0, 0, 0); check_float ("atan2 (-0.7, -1.0) == -2.530866689200584621918884506789267", FUNC(atan2) (-0.7L, -1.0L), -2.530866689200584621918884506789267L, 0, 0, 0); check_float ("atan2 (0.4, 0.0003) == 1.5700463269355215717704032607580829", FUNC(atan2) (0.4L, 0.0003L), 1.5700463269355215717704032607580829L, DELTA78, 0, 0); check_float ("atan2 (1.4, -0.93) == 2.1571487668237843754887415992772736", FUNC(atan2) (1.4L, -0.93L), 2.1571487668237843754887415992772736L, 0, 0, 0); print_max_error ("atan2", DELTAatan2, 0); } #if 0 /* XXX scp XXX */ static void cabs_test (void) { errno = 0; FUNC(cabs) (BUILD_COMPLEX (0.7L, 12.4L)); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); /* cabs (x + iy) is specified as hypot (x,y) */ /* cabs (+inf + i x) == +inf. */ check_float ("cabs (inf + 1.0 i) == inf", FUNC(cabs) (BUILD_COMPLEX (plus_infty, 1.0)), plus_infty, 0, 0, 0); /* cabs (-inf + i x) == +inf. */ check_float ("cabs (-inf + 1.0 i) == inf", FUNC(cabs) (BUILD_COMPLEX (minus_infty, 1.0)), plus_infty, 0, 0, 0); check_float ("cabs (-inf + NaN i) == inf", FUNC(cabs) (BUILD_COMPLEX (minus_infty, nan_value)), plus_infty, 0, 0, 0); check_float ("cabs (-inf + NaN i) == inf", FUNC(cabs) (BUILD_COMPLEX (minus_infty, nan_value)), plus_infty, 0, 0, 0); check_float ("cabs (NaN + NaN i) == NaN", FUNC(cabs) (BUILD_COMPLEX (nan_value, nan_value)), nan_value, 0, 0, 0); /* cabs (x,y) == cabs (y,x). */ check_float ("cabs (0.7 + 12.4 i) == 12.419742348374220601176836866763271", FUNC(cabs) (BUILD_COMPLEX (0.7L, 12.4L)), 12.419742348374220601176836866763271L, DELTA85, 0, 0); /* cabs (x,y) == cabs (-x,y). */ check_float ("cabs (-12.4 + 0.7 i) == 12.419742348374220601176836866763271", FUNC(cabs) (BUILD_COMPLEX (-12.4L, 0.7L)), 12.419742348374220601176836866763271L, DELTA86, 0, 0); /* cabs (x,y) == cabs (-y,x). */ check_float ("cabs (-0.7 + 12.4 i) == 12.419742348374220601176836866763271", FUNC(cabs) (BUILD_COMPLEX (-0.7L, 12.4L)), 12.419742348374220601176836866763271L, DELTA87, 0, 0); /* cabs (x,y) == cabs (-x,-y). */ check_float ("cabs (-12.4 - 0.7 i) == 12.419742348374220601176836866763271", FUNC(cabs) (BUILD_COMPLEX (-12.4L, -0.7L)), 12.419742348374220601176836866763271L, DELTA88, 0, 0); /* cabs (x,y) == cabs (-y,-x). */ check_float ("cabs (-0.7 - 12.4 i) == 12.419742348374220601176836866763271", FUNC(cabs) (BUILD_COMPLEX (-0.7L, -12.4L)), 12.419742348374220601176836866763271L, DELTA89, 0, 0); /* cabs (x,0) == fabs (x). */ check_float ("cabs (-0.7 + 0 i) == 0.7", FUNC(cabs) (BUILD_COMPLEX (-0.7L, 0)), 0.7L, 0, 0, 0); check_float ("cabs (0.7 + 0 i) == 0.7", FUNC(cabs) (BUILD_COMPLEX (0.7L, 0)), 0.7L, 0, 0, 0); check_float ("cabs (-1.0 + 0 i) == 1.0", FUNC(cabs) (BUILD_COMPLEX (-1.0L, 0)), 1.0L, 0, 0, 0); check_float ("cabs (1.0 + 0 i) == 1.0", FUNC(cabs) (BUILD_COMPLEX (1.0L, 0)), 1.0L, 0, 0, 0); check_float ("cabs (-5.7e7 + 0 i) == 5.7e7", FUNC(cabs) (BUILD_COMPLEX (-5.7e7L, 0)), 5.7e7L, 0, 0, 0); check_float ("cabs (5.7e7 + 0 i) == 5.7e7", FUNC(cabs) (BUILD_COMPLEX (5.7e7L, 0)), 5.7e7L, 0, 0, 0); check_float ("cabs (0.7 + 1.2 i) == 1.3892443989449804508432547041028554", FUNC(cabs) (BUILD_COMPLEX (0.7L, 1.2L)), 1.3892443989449804508432547041028554L, DELTA96, 0, 0); print_max_error ("cabs", DELTAcabs, 0); } static void cacos_test (void) { errno = 0; FUNC(cacos) (BUILD_COMPLEX (0.7L, 1.2L)); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_complex ("cacos (0 + 0 i) == pi/2 - 0 i", FUNC(cacos) (BUILD_COMPLEX (0, 0)), BUILD_COMPLEX (M_PI_2l, minus_zero), 0, 0, 0); check_complex ("cacos (-0 + 0 i) == pi/2 - 0 i", FUNC(cacos) (BUILD_COMPLEX (minus_zero, 0)), BUILD_COMPLEX (M_PI_2l, minus_zero), 0, 0, 0); check_complex ("cacos (-0 - 0 i) == pi/2 + 0.0 i", FUNC(cacos) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (M_PI_2l, 0.0), 0, 0, 0); check_complex ("cacos (0 - 0 i) == pi/2 + 0.0 i", FUNC(cacos) (BUILD_COMPLEX (0, minus_zero)), BUILD_COMPLEX (M_PI_2l, 0.0), 0, 0, 0); check_complex ("cacos (-inf + inf i) == 3/4 pi - inf i", FUNC(cacos) (BUILD_COMPLEX (minus_infty, plus_infty)), BUILD_COMPLEX (M_PI_34l, minus_infty), 0, 0, 0); check_complex ("cacos (-inf - inf i) == 3/4 pi + inf i", FUNC(cacos) (BUILD_COMPLEX (minus_infty, minus_infty)), BUILD_COMPLEX (M_PI_34l, plus_infty), 0, 0, 0); check_complex ("cacos (inf + inf i) == pi/4 - inf i", FUNC(cacos) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (M_PI_4l, minus_infty), 0, 0, 0); check_complex ("cacos (inf - inf i) == pi/4 + inf i", FUNC(cacos) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (M_PI_4l, plus_infty), 0, 0, 0); check_complex ("cacos (-10.0 + inf i) == pi/2 - inf i", FUNC(cacos) (BUILD_COMPLEX (-10.0, plus_infty)), BUILD_COMPLEX (M_PI_2l, minus_infty), 0, 0, 0); check_complex ("cacos (-10.0 - inf i) == pi/2 + inf i", FUNC(cacos) (BUILD_COMPLEX (-10.0, minus_infty)), BUILD_COMPLEX (M_PI_2l, plus_infty), 0, 0, 0); check_complex ("cacos (0 + inf i) == pi/2 - inf i", FUNC(cacos) (BUILD_COMPLEX (0, plus_infty)), BUILD_COMPLEX (M_PI_2l, minus_infty), 0, 0, 0); check_complex ("cacos (0 - inf i) == pi/2 + inf i", FUNC(cacos) (BUILD_COMPLEX (0, minus_infty)), BUILD_COMPLEX (M_PI_2l, plus_infty), 0, 0, 0); check_complex ("cacos (0.1 + inf i) == pi/2 - inf i", FUNC(cacos) (BUILD_COMPLEX (0.1L, plus_infty)), BUILD_COMPLEX (M_PI_2l, minus_infty), 0, 0, 0); check_complex ("cacos (0.1 - inf i) == pi/2 + inf i", FUNC(cacos) (BUILD_COMPLEX (0.1L, minus_infty)), BUILD_COMPLEX (M_PI_2l, plus_infty), 0, 0, 0); check_complex ("cacos (-inf + 0 i) == pi - inf i", FUNC(cacos) (BUILD_COMPLEX (minus_infty, 0)), BUILD_COMPLEX (M_PIl, minus_infty), 0, 0, 0); check_complex ("cacos (-inf - 0 i) == pi + inf i", FUNC(cacos) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (M_PIl, plus_infty), 0, 0, 0); check_complex ("cacos (-inf + 100 i) == pi - inf i", FUNC(cacos) (BUILD_COMPLEX (minus_infty, 100)), BUILD_COMPLEX (M_PIl, minus_infty), 0, 0, 0); check_complex ("cacos (-inf - 100 i) == pi + inf i", FUNC(cacos) (BUILD_COMPLEX (minus_infty, -100)), BUILD_COMPLEX (M_PIl, plus_infty), 0, 0, 0); check_complex ("cacos (inf + 0 i) == 0.0 - inf i", FUNC(cacos) (BUILD_COMPLEX (plus_infty, 0)), BUILD_COMPLEX (0.0, minus_infty), 0, 0, 0); check_complex ("cacos (inf - 0 i) == 0.0 + inf i", FUNC(cacos) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (0.0, plus_infty), 0, 0, 0); check_complex ("cacos (inf + 0.5 i) == 0.0 - inf i", FUNC(cacos) (BUILD_COMPLEX (plus_infty, 0.5)), BUILD_COMPLEX (0.0, minus_infty), 0, 0, 0); check_complex ("cacos (inf - 0.5 i) == 0.0 + inf i", FUNC(cacos) (BUILD_COMPLEX (plus_infty, -0.5)), BUILD_COMPLEX (0.0, plus_infty), 0, 0, 0); check_complex ("cacos (inf + NaN i) == NaN + inf i plus sign of zero/inf not specified", FUNC(cacos) (BUILD_COMPLEX (plus_infty, nan_value)), BUILD_COMPLEX (nan_value, plus_infty), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("cacos (-inf + NaN i) == NaN + inf i plus sign of zero/inf not specified", FUNC(cacos) (BUILD_COMPLEX (minus_infty, nan_value)), BUILD_COMPLEX (nan_value, plus_infty), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("cacos (0 + NaN i) == pi/2 + NaN i", FUNC(cacos) (BUILD_COMPLEX (0, nan_value)), BUILD_COMPLEX (M_PI_2l, nan_value), 0, 0, 0); check_complex ("cacos (-0 + NaN i) == pi/2 + NaN i", FUNC(cacos) (BUILD_COMPLEX (minus_zero, nan_value)), BUILD_COMPLEX (M_PI_2l, nan_value), 0, 0, 0); check_complex ("cacos (NaN + inf i) == NaN - inf i", FUNC(cacos) (BUILD_COMPLEX (nan_value, plus_infty)), BUILD_COMPLEX (nan_value, minus_infty), 0, 0, 0); check_complex ("cacos (NaN - inf i) == NaN + inf i", FUNC(cacos) (BUILD_COMPLEX (nan_value, minus_infty)), BUILD_COMPLEX (nan_value, plus_infty), 0, 0, 0); check_complex ("cacos (10.5 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(cacos) (BUILD_COMPLEX (10.5, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("cacos (-10.5 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(cacos) (BUILD_COMPLEX (-10.5, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("cacos (NaN + 0.75 i) == NaN + NaN i plus invalid exception allowed", FUNC(cacos) (BUILD_COMPLEX (nan_value, 0.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("cacos (NaN - 0.75 i) == NaN + NaN i plus invalid exception allowed", FUNC(cacos) (BUILD_COMPLEX (nan_value, -0.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("cacos (NaN + NaN i) == NaN + NaN i", FUNC(cacos) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); check_complex ("cacos (0.7 + 1.2 i) == 1.1351827477151551088992008271819053 - 1.0927647857577371459105272080819308 i", FUNC(cacos) (BUILD_COMPLEX (0.7L, 1.2L)), BUILD_COMPLEX (1.1351827477151551088992008271819053L, -1.0927647857577371459105272080819308L), DELTA130, 0, 0); check_complex ("cacos (-2 - 3 i) == 2.1414491111159960199416055713254211 + 1.9833870299165354323470769028940395 i", FUNC(cacos) (BUILD_COMPLEX (-2, -3)), BUILD_COMPLEX (2.1414491111159960199416055713254211L, 1.9833870299165354323470769028940395L), DELTA131, 0, 0); print_complex_max_error ("cacos", DELTAcacos, 0); } static void cacosh_test (void) { errno = 0; FUNC(cacosh) (BUILD_COMPLEX (0.7L, 1.2L)); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_complex ("cacosh (0 + 0 i) == 0.0 + pi/2 i", FUNC(cacosh) (BUILD_COMPLEX (0, 0)), BUILD_COMPLEX (0.0, M_PI_2l), 0, 0, 0); check_complex ("cacosh (-0 + 0 i) == 0.0 + pi/2 i", FUNC(cacosh) (BUILD_COMPLEX (minus_zero, 0)), BUILD_COMPLEX (0.0, M_PI_2l), 0, 0, 0); check_complex ("cacosh (0 - 0 i) == 0.0 - pi/2 i", FUNC(cacosh) (BUILD_COMPLEX (0, minus_zero)), BUILD_COMPLEX (0.0, -M_PI_2l), 0, 0, 0); check_complex ("cacosh (-0 - 0 i) == 0.0 - pi/2 i", FUNC(cacosh) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (0.0, -M_PI_2l), 0, 0, 0); check_complex ("cacosh (-inf + inf i) == inf + 3/4 pi i", FUNC(cacosh) (BUILD_COMPLEX (minus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI_34l), 0, 0, 0); check_complex ("cacosh (-inf - inf i) == inf - 3/4 pi i", FUNC(cacosh) (BUILD_COMPLEX (minus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI_34l), 0, 0, 0); check_complex ("cacosh (inf + inf i) == inf + pi/4 i", FUNC(cacosh) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI_4l), 0, 0, 0); check_complex ("cacosh (inf - inf i) == inf - pi/4 i", FUNC(cacosh) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI_4l), 0, 0, 0); check_complex ("cacosh (-10.0 + inf i) == inf + pi/2 i", FUNC(cacosh) (BUILD_COMPLEX (-10.0, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI_2l), 0, 0, 0); check_complex ("cacosh (-10.0 - inf i) == inf - pi/2 i", FUNC(cacosh) (BUILD_COMPLEX (-10.0, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI_2l), 0, 0, 0); check_complex ("cacosh (0 + inf i) == inf + pi/2 i", FUNC(cacosh) (BUILD_COMPLEX (0, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI_2l), 0, 0, 0); check_complex ("cacosh (0 - inf i) == inf - pi/2 i", FUNC(cacosh) (BUILD_COMPLEX (0, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI_2l), 0, 0, 0); check_complex ("cacosh (0.1 + inf i) == inf + pi/2 i", FUNC(cacosh) (BUILD_COMPLEX (0.1L, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI_2l), 0, 0, 0); check_complex ("cacosh (0.1 - inf i) == inf - pi/2 i", FUNC(cacosh) (BUILD_COMPLEX (0.1L, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI_2l), 0, 0, 0); check_complex ("cacosh (-inf + 0 i) == inf + pi i", FUNC(cacosh) (BUILD_COMPLEX (minus_infty, 0)), BUILD_COMPLEX (plus_infty, M_PIl), 0, 0, 0); check_complex ("cacosh (-inf - 0 i) == inf - pi i", FUNC(cacosh) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (plus_infty, -M_PIl), 0, 0, 0); check_complex ("cacosh (-inf + 100 i) == inf + pi i", FUNC(cacosh) (BUILD_COMPLEX (minus_infty, 100)), BUILD_COMPLEX (plus_infty, M_PIl), 0, 0, 0); check_complex ("cacosh (-inf - 100 i) == inf - pi i", FUNC(cacosh) (BUILD_COMPLEX (minus_infty, -100)), BUILD_COMPLEX (plus_infty, -M_PIl), 0, 0, 0); check_complex ("cacosh (inf + 0 i) == inf + 0.0 i", FUNC(cacosh) (BUILD_COMPLEX (plus_infty, 0)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); check_complex ("cacosh (inf - 0 i) == inf - 0 i", FUNC(cacosh) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); check_complex ("cacosh (inf + 0.5 i) == inf + 0.0 i", FUNC(cacosh) (BUILD_COMPLEX (plus_infty, 0.5)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); check_complex ("cacosh (inf - 0.5 i) == inf - 0 i", FUNC(cacosh) (BUILD_COMPLEX (plus_infty, -0.5)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); check_complex ("cacosh (inf + NaN i) == inf + NaN i", FUNC(cacosh) (BUILD_COMPLEX (plus_infty, nan_value)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); check_complex ("cacosh (-inf + NaN i) == inf + NaN i", FUNC(cacosh) (BUILD_COMPLEX (minus_infty, nan_value)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); check_complex ("cacosh (0 + NaN i) == NaN + NaN i", FUNC(cacosh) (BUILD_COMPLEX (0, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); check_complex ("cacosh (-0 + NaN i) == NaN + NaN i", FUNC(cacosh) (BUILD_COMPLEX (minus_zero, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); check_complex ("cacosh (NaN + inf i) == inf + NaN i", FUNC(cacosh) (BUILD_COMPLEX (nan_value, plus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); check_complex ("cacosh (NaN - inf i) == inf + NaN i", FUNC(cacosh) (BUILD_COMPLEX (nan_value, minus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); check_complex ("cacosh (10.5 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(cacosh) (BUILD_COMPLEX (10.5, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("cacosh (-10.5 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(cacosh) (BUILD_COMPLEX (-10.5, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("cacosh (NaN + 0.75 i) == NaN + NaN i plus invalid exception allowed", FUNC(cacosh) (BUILD_COMPLEX (nan_value, 0.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("cacosh (NaN - 0.75 i) == NaN + NaN i plus invalid exception allowed", FUNC(cacosh) (BUILD_COMPLEX (nan_value, -0.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("cacosh (NaN + NaN i) == NaN + NaN i", FUNC(cacosh) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); check_complex ("cacosh (0.7 + 1.2 i) == 1.0927647857577371459105272080819308 + 1.1351827477151551088992008271819053 i", FUNC(cacosh) (BUILD_COMPLEX (0.7L, 1.2L)), BUILD_COMPLEX (1.0927647857577371459105272080819308L, 1.1351827477151551088992008271819053L), DELTA165, 0, 0); check_complex ("cacosh (-2 - 3 i) == -1.9833870299165354323470769028940395 + 2.1414491111159960199416055713254211 i", FUNC(cacosh) (BUILD_COMPLEX (-2, -3)), BUILD_COMPLEX (-1.9833870299165354323470769028940395L, 2.1414491111159960199416055713254211L), DELTA166, 0, 0); print_complex_max_error ("cacosh", DELTAcacosh, 0); } static void carg_test (void) { init_max_error (); /* carg (x + iy) is specified as atan2 (y, x) */ /* carg (x + i 0) == 0 for x > 0. */ check_float ("carg (2.0 + 0 i) == 0", FUNC(carg) (BUILD_COMPLEX (2.0, 0)), 0, 0, 0, 0); /* carg (x - i 0) == -0 for x > 0. */ check_float ("carg (2.0 - 0 i) == -0", FUNC(carg) (BUILD_COMPLEX (2.0, minus_zero)), minus_zero, 0, 0, 0); check_float ("carg (0 + 0 i) == 0", FUNC(carg) (BUILD_COMPLEX (0, 0)), 0, 0, 0, 0); check_float ("carg (0 - 0 i) == -0", FUNC(carg) (BUILD_COMPLEX (0, minus_zero)), minus_zero, 0, 0, 0); /* carg (x + i 0) == +pi for x < 0. */ check_float ("carg (-2.0 + 0 i) == pi", FUNC(carg) (BUILD_COMPLEX (-2.0, 0)), M_PIl, 0, 0, 0); /* carg (x - i 0) == -pi for x < 0. */ check_float ("carg (-2.0 - 0 i) == -pi", FUNC(carg) (BUILD_COMPLEX (-2.0, minus_zero)), -M_PIl, 0, 0, 0); check_float ("carg (-0 + 0 i) == pi", FUNC(carg) (BUILD_COMPLEX (minus_zero, 0)), M_PIl, 0, 0, 0); check_float ("carg (-0 - 0 i) == -pi", FUNC(carg) (BUILD_COMPLEX (minus_zero, minus_zero)), -M_PIl, 0, 0, 0); /* carg (+0 + i y) == pi/2 for y > 0. */ check_float ("carg (0 + 2.0 i) == pi/2", FUNC(carg) (BUILD_COMPLEX (0, 2.0)), M_PI_2l, 0, 0, 0); /* carg (-0 + i y) == pi/2 for y > 0. */ check_float ("carg (-0 + 2.0 i) == pi/2", FUNC(carg) (BUILD_COMPLEX (minus_zero, 2.0)), M_PI_2l, 0, 0, 0); /* carg (+0 + i y) == -pi/2 for y < 0. */ check_float ("carg (0 - 2.0 i) == -pi/2", FUNC(carg) (BUILD_COMPLEX (0, -2.0)), -M_PI_2l, 0, 0, 0); /* carg (-0 + i y) == -pi/2 for y < 0. */ check_float ("carg (-0 - 2.0 i) == -pi/2", FUNC(carg) (BUILD_COMPLEX (minus_zero, -2.0)), -M_PI_2l, 0, 0, 0); /* carg (inf + i y) == +0 for finite y > 0. */ check_float ("carg (inf + 2.0 i) == 0", FUNC(carg) (BUILD_COMPLEX (plus_infty, 2.0)), 0, 0, 0, 0); /* carg (inf + i y) == -0 for finite y < 0. */ check_float ("carg (inf - 2.0 i) == -0", FUNC(carg) (BUILD_COMPLEX (plus_infty, -2.0)), minus_zero, 0, 0, 0); /* carg(x + i inf) == pi/2 for finite x. */ check_float ("carg (10.0 + inf i) == pi/2", FUNC(carg) (BUILD_COMPLEX (10.0, plus_infty)), M_PI_2l, 0, 0, 0); /* carg(x - i inf) == -pi/2 for finite x. */ check_float ("carg (10.0 - inf i) == -pi/2", FUNC(carg) (BUILD_COMPLEX (10.0, minus_infty)), -M_PI_2l, 0, 0, 0); /* carg (-inf + i y) == +pi for finite y > 0. */ check_float ("carg (-inf + 10.0 i) == pi", FUNC(carg) (BUILD_COMPLEX (minus_infty, 10.0)), M_PIl, 0, 0, 0); /* carg (-inf + i y) == -pi for finite y < 0. */ check_float ("carg (-inf - 10.0 i) == -pi", FUNC(carg) (BUILD_COMPLEX (minus_infty, -10.0)), -M_PIl, 0, 0, 0); check_float ("carg (inf + inf i) == pi/4", FUNC(carg) (BUILD_COMPLEX (plus_infty, plus_infty)), M_PI_4l, 0, 0, 0); check_float ("carg (inf - inf i) == -pi/4", FUNC(carg) (BUILD_COMPLEX (plus_infty, minus_infty)), -M_PI_4l, 0, 0, 0); check_float ("carg (-inf + inf i) == 3 * M_PI_4l", FUNC(carg) (BUILD_COMPLEX (minus_infty, plus_infty)), 3 * M_PI_4l, 0, 0, 0); check_float ("carg (-inf - inf i) == -3 * M_PI_4l", FUNC(carg) (BUILD_COMPLEX (minus_infty, minus_infty)), -3 * M_PI_4l, 0, 0, 0); check_float ("carg (NaN + NaN i) == NaN", FUNC(carg) (BUILD_COMPLEX (nan_value, nan_value)), nan_value, 0, 0, 0); print_max_error ("carg", 0, 0); } static void casin_test (void) { errno = 0; FUNC(casin) (BUILD_COMPLEX (0.7L, 1.2L)); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_complex ("casin (0 + 0 i) == 0.0 + 0.0 i", FUNC(casin) (BUILD_COMPLEX (0, 0)), BUILD_COMPLEX (0.0, 0.0), 0, 0, 0); check_complex ("casin (-0 + 0 i) == -0 + 0.0 i", FUNC(casin) (BUILD_COMPLEX (minus_zero, 0)), BUILD_COMPLEX (minus_zero, 0.0), 0, 0, 0); check_complex ("casin (0 - 0 i) == 0.0 - 0 i", FUNC(casin) (BUILD_COMPLEX (0, minus_zero)), BUILD_COMPLEX (0.0, minus_zero), 0, 0, 0); check_complex ("casin (-0 - 0 i) == -0 - 0 i", FUNC(casin) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (minus_zero, minus_zero), 0, 0, 0); check_complex ("casin (inf + inf i) == pi/4 + inf i", FUNC(casin) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (M_PI_4l, plus_infty), 0, 0, 0); check_complex ("casin (inf - inf i) == pi/4 - inf i", FUNC(casin) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (M_PI_4l, minus_infty), 0, 0, 0); check_complex ("casin (-inf + inf i) == -pi/4 + inf i", FUNC(casin) (BUILD_COMPLEX (minus_infty, plus_infty)), BUILD_COMPLEX (-M_PI_4l, plus_infty), 0, 0, 0); check_complex ("casin (-inf - inf i) == -pi/4 - inf i", FUNC(casin) (BUILD_COMPLEX (minus_infty, minus_infty)), BUILD_COMPLEX (-M_PI_4l, minus_infty), 0, 0, 0); check_complex ("casin (-10.0 + inf i) == -0 + inf i", FUNC(casin) (BUILD_COMPLEX (-10.0, plus_infty)), BUILD_COMPLEX (minus_zero, plus_infty), 0, 0, 0); check_complex ("casin (-10.0 - inf i) == -0 - inf i", FUNC(casin) (BUILD_COMPLEX (-10.0, minus_infty)), BUILD_COMPLEX (minus_zero, minus_infty), 0, 0, 0); check_complex ("casin (0 + inf i) == 0.0 + inf i", FUNC(casin) (BUILD_COMPLEX (0, plus_infty)), BUILD_COMPLEX (0.0, plus_infty), 0, 0, 0); check_complex ("casin (0 - inf i) == 0.0 - inf i", FUNC(casin) (BUILD_COMPLEX (0, minus_infty)), BUILD_COMPLEX (0.0, minus_infty), 0, 0, 0); check_complex ("casin (-0 + inf i) == -0 + inf i", FUNC(casin) (BUILD_COMPLEX (minus_zero, plus_infty)), BUILD_COMPLEX (minus_zero, plus_infty), 0, 0, 0); check_complex ("casin (-0 - inf i) == -0 - inf i", FUNC(casin) (BUILD_COMPLEX (minus_zero, minus_infty)), BUILD_COMPLEX (minus_zero, minus_infty), 0, 0, 0); check_complex ("casin (0.1 + inf i) == 0.0 + inf i", FUNC(casin) (BUILD_COMPLEX (0.1L, plus_infty)), BUILD_COMPLEX (0.0, plus_infty), 0, 0, 0); check_complex ("casin (0.1 - inf i) == 0.0 - inf i", FUNC(casin) (BUILD_COMPLEX (0.1L, minus_infty)), BUILD_COMPLEX (0.0, minus_infty), 0, 0, 0); check_complex ("casin (-inf + 0 i) == -pi/2 + inf i", FUNC(casin) (BUILD_COMPLEX (minus_infty, 0)), BUILD_COMPLEX (-M_PI_2l, plus_infty), 0, 0, 0); check_complex ("casin (-inf - 0 i) == -pi/2 - inf i", FUNC(casin) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (-M_PI_2l, minus_infty), 0, 0, 0); check_complex ("casin (-inf + 100 i) == -pi/2 + inf i", FUNC(casin) (BUILD_COMPLEX (minus_infty, 100)), BUILD_COMPLEX (-M_PI_2l, plus_infty), 0, 0, 0); check_complex ("casin (-inf - 100 i) == -pi/2 - inf i", FUNC(casin) (BUILD_COMPLEX (minus_infty, -100)), BUILD_COMPLEX (-M_PI_2l, minus_infty), 0, 0, 0); check_complex ("casin (inf + 0 i) == pi/2 + inf i", FUNC(casin) (BUILD_COMPLEX (plus_infty, 0)), BUILD_COMPLEX (M_PI_2l, plus_infty), 0, 0, 0); check_complex ("casin (inf - 0 i) == pi/2 - inf i", FUNC(casin) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (M_PI_2l, minus_infty), 0, 0, 0); check_complex ("casin (inf + 0.5 i) == pi/2 + inf i", FUNC(casin) (BUILD_COMPLEX (plus_infty, 0.5)), BUILD_COMPLEX (M_PI_2l, plus_infty), 0, 0, 0); check_complex ("casin (inf - 0.5 i) == pi/2 - inf i", FUNC(casin) (BUILD_COMPLEX (plus_infty, -0.5)), BUILD_COMPLEX (M_PI_2l, minus_infty), 0, 0, 0); check_complex ("casin (NaN + inf i) == NaN + inf i", FUNC(casin) (BUILD_COMPLEX (nan_value, plus_infty)), BUILD_COMPLEX (nan_value, plus_infty), 0, 0, 0); check_complex ("casin (NaN - inf i) == NaN - inf i", FUNC(casin) (BUILD_COMPLEX (nan_value, minus_infty)), BUILD_COMPLEX (nan_value, minus_infty), 0, 0, 0); check_complex ("casin (0.0 + NaN i) == 0.0 + NaN i", FUNC(casin) (BUILD_COMPLEX (0.0, nan_value)), BUILD_COMPLEX (0.0, nan_value), 0, 0, 0); check_complex ("casin (-0 + NaN i) == -0 + NaN i", FUNC(casin) (BUILD_COMPLEX (minus_zero, nan_value)), BUILD_COMPLEX (minus_zero, nan_value), 0, 0, 0); check_complex ("casin (inf + NaN i) == NaN + inf i plus sign of zero/inf not specified", FUNC(casin) (BUILD_COMPLEX (plus_infty, nan_value)), BUILD_COMPLEX (nan_value, plus_infty), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("casin (-inf + NaN i) == NaN + inf i plus sign of zero/inf not specified", FUNC(casin) (BUILD_COMPLEX (minus_infty, nan_value)), BUILD_COMPLEX (nan_value, plus_infty), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("casin (NaN + 10.5 i) == NaN + NaN i plus invalid exception allowed", FUNC(casin) (BUILD_COMPLEX (nan_value, 10.5)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("casin (NaN - 10.5 i) == NaN + NaN i plus invalid exception allowed", FUNC(casin) (BUILD_COMPLEX (nan_value, -10.5)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("casin (0.75 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(casin) (BUILD_COMPLEX (0.75, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("casin (-0.75 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(casin) (BUILD_COMPLEX (-0.75, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("casin (NaN + NaN i) == NaN + NaN i", FUNC(casin) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); check_complex ("casin (0.7 + 1.2 i) == 0.4356135790797415103321208644578462 + 1.0927647857577371459105272080819308 i", FUNC(casin) (BUILD_COMPLEX (0.7L, 1.2L)), BUILD_COMPLEX (0.4356135790797415103321208644578462L, 1.0927647857577371459105272080819308L), DELTA225, 0, 0); check_complex ("casin (-2 - 3 i) == -0.57065278432109940071028387968566963 - 1.9833870299165354323470769028940395 i", FUNC(casin) (BUILD_COMPLEX (-2, -3)), BUILD_COMPLEX (-0.57065278432109940071028387968566963L, -1.9833870299165354323470769028940395L), DELTA226, 0, 0); print_complex_max_error ("casin", DELTAcasin, 0); } static void casinh_test (void) { errno = 0; FUNC(casinh) (BUILD_COMPLEX (0.7L, 1.2L)); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_complex ("casinh (0 + 0 i) == 0.0 + 0.0 i", FUNC(casinh) (BUILD_COMPLEX (0, 0)), BUILD_COMPLEX (0.0, 0.0), 0, 0, 0); check_complex ("casinh (-0 + 0 i) == -0 + 0 i", FUNC(casinh) (BUILD_COMPLEX (minus_zero, 0)), BUILD_COMPLEX (minus_zero, 0), 0, 0, 0); check_complex ("casinh (0 - 0 i) == 0.0 - 0 i", FUNC(casinh) (BUILD_COMPLEX (0, minus_zero)), BUILD_COMPLEX (0.0, minus_zero), 0, 0, 0); check_complex ("casinh (-0 - 0 i) == -0 - 0 i", FUNC(casinh) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (minus_zero, minus_zero), 0, 0, 0); check_complex ("casinh (inf + inf i) == inf + pi/4 i", FUNC(casinh) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI_4l), 0, 0, 0); check_complex ("casinh (inf - inf i) == inf - pi/4 i", FUNC(casinh) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI_4l), 0, 0, 0); check_complex ("casinh (-inf + inf i) == -inf + pi/4 i", FUNC(casinh) (BUILD_COMPLEX (minus_infty, plus_infty)), BUILD_COMPLEX (minus_infty, M_PI_4l), 0, 0, 0); check_complex ("casinh (-inf - inf i) == -inf - pi/4 i", FUNC(casinh) (BUILD_COMPLEX (minus_infty, minus_infty)), BUILD_COMPLEX (minus_infty, -M_PI_4l), 0, 0, 0); check_complex ("casinh (-10.0 + inf i) == -inf + pi/2 i", FUNC(casinh) (BUILD_COMPLEX (-10.0, plus_infty)), BUILD_COMPLEX (minus_infty, M_PI_2l), 0, 0, 0); check_complex ("casinh (-10.0 - inf i) == -inf - pi/2 i", FUNC(casinh) (BUILD_COMPLEX (-10.0, minus_infty)), BUILD_COMPLEX (minus_infty, -M_PI_2l), 0, 0, 0); check_complex ("casinh (0 + inf i) == inf + pi/2 i", FUNC(casinh) (BUILD_COMPLEX (0, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI_2l), 0, 0, 0); check_complex ("casinh (0 - inf i) == inf - pi/2 i", FUNC(casinh) (BUILD_COMPLEX (0, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI_2l), 0, 0, 0); check_complex ("casinh (-0 + inf i) == -inf + pi/2 i", FUNC(casinh) (BUILD_COMPLEX (minus_zero, plus_infty)), BUILD_COMPLEX (minus_infty, M_PI_2l), 0, 0, 0); check_complex ("casinh (-0 - inf i) == -inf - pi/2 i", FUNC(casinh) (BUILD_COMPLEX (minus_zero, minus_infty)), BUILD_COMPLEX (minus_infty, -M_PI_2l), 0, 0, 0); check_complex ("casinh (0.1 + inf i) == inf + pi/2 i", FUNC(casinh) (BUILD_COMPLEX (0.1L, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI_2l), 0, 0, 0); check_complex ("casinh (0.1 - inf i) == inf - pi/2 i", FUNC(casinh) (BUILD_COMPLEX (0.1L, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI_2l), 0, 0, 0); check_complex ("casinh (-inf + 0 i) == -inf + 0.0 i", FUNC(casinh) (BUILD_COMPLEX (minus_infty, 0)), BUILD_COMPLEX (minus_infty, 0.0), 0, 0, 0); check_complex ("casinh (-inf - 0 i) == -inf - 0 i", FUNC(casinh) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (minus_infty, minus_zero), 0, 0, 0); check_complex ("casinh (-inf + 100 i) == -inf + 0.0 i", FUNC(casinh) (BUILD_COMPLEX (minus_infty, 100)), BUILD_COMPLEX (minus_infty, 0.0), 0, 0, 0); check_complex ("casinh (-inf - 100 i) == -inf - 0 i", FUNC(casinh) (BUILD_COMPLEX (minus_infty, -100)), BUILD_COMPLEX (minus_infty, minus_zero), 0, 0, 0); check_complex ("casinh (inf + 0 i) == inf + 0.0 i", FUNC(casinh) (BUILD_COMPLEX (plus_infty, 0)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); check_complex ("casinh (inf - 0 i) == inf - 0 i", FUNC(casinh) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); check_complex ("casinh (inf + 0.5 i) == inf + 0.0 i", FUNC(casinh) (BUILD_COMPLEX (plus_infty, 0.5)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); check_complex ("casinh (inf - 0.5 i) == inf - 0 i", FUNC(casinh) (BUILD_COMPLEX (plus_infty, -0.5)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); check_complex ("casinh (inf + NaN i) == inf + NaN i", FUNC(casinh) (BUILD_COMPLEX (plus_infty, nan_value)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); check_complex ("casinh (-inf + NaN i) == -inf + NaN i", FUNC(casinh) (BUILD_COMPLEX (minus_infty, nan_value)), BUILD_COMPLEX (minus_infty, nan_value), 0, 0, 0); check_complex ("casinh (NaN + 0 i) == NaN + 0.0 i", FUNC(casinh) (BUILD_COMPLEX (nan_value, 0)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, 0); check_complex ("casinh (NaN - 0 i) == NaN - 0 i", FUNC(casinh) (BUILD_COMPLEX (nan_value, minus_zero)), BUILD_COMPLEX (nan_value, minus_zero), 0, 0, 0); check_complex ("casinh (NaN + inf i) == inf + NaN i plus sign of zero/inf not specified", FUNC(casinh) (BUILD_COMPLEX (nan_value, plus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("casinh (NaN - inf i) == inf + NaN i plus sign of zero/inf not specified", FUNC(casinh) (BUILD_COMPLEX (nan_value, minus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("casinh (10.5 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(casinh) (BUILD_COMPLEX (10.5, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("casinh (-10.5 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(casinh) (BUILD_COMPLEX (-10.5, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("casinh (NaN + 0.75 i) == NaN + NaN i plus invalid exception allowed", FUNC(casinh) (BUILD_COMPLEX (nan_value, 0.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("casinh (-0.75 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(casinh) (BUILD_COMPLEX (-0.75, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("casinh (NaN + NaN i) == NaN + NaN i", FUNC(casinh) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); check_complex ("casinh (0.7 + 1.2 i) == 0.97865459559367387689317593222160964 + 0.91135418953156011567903546856170941 i", FUNC(casinh) (BUILD_COMPLEX (0.7L, 1.2L)), BUILD_COMPLEX (0.97865459559367387689317593222160964L, 0.91135418953156011567903546856170941L), DELTA262, 0, 0); check_complex ("casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i", FUNC(casinh) (BUILD_COMPLEX (-2, -3)), BUILD_COMPLEX (-1.9686379257930962917886650952454982L, -0.96465850440760279204541105949953237L), DELTA263, 0, 0); print_complex_max_error ("casinh", DELTAcasinh, 0); } static void catan_test (void) { errno = 0; FUNC(catan) (BUILD_COMPLEX (0.7L, 1.2L)); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_complex ("catan (0 + 0 i) == 0 + 0 i", FUNC(catan) (BUILD_COMPLEX (0, 0)), BUILD_COMPLEX (0, 0), 0, 0, 0); check_complex ("catan (-0 + 0 i) == -0 + 0 i", FUNC(catan) (BUILD_COMPLEX (minus_zero, 0)), BUILD_COMPLEX (minus_zero, 0), 0, 0, 0); check_complex ("catan (0 - 0 i) == 0 - 0 i", FUNC(catan) (BUILD_COMPLEX (0, minus_zero)), BUILD_COMPLEX (0, minus_zero), 0, 0, 0); check_complex ("catan (-0 - 0 i) == -0 - 0 i", FUNC(catan) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (minus_zero, minus_zero), 0, 0, 0); check_complex ("catan (inf + inf i) == pi/2 + 0 i", FUNC(catan) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (M_PI_2l, 0), 0, 0, 0); check_complex ("catan (inf - inf i) == pi/2 - 0 i", FUNC(catan) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (M_PI_2l, minus_zero), 0, 0, 0); check_complex ("catan (-inf + inf i) == -pi/2 + 0 i", FUNC(catan) (BUILD_COMPLEX (minus_infty, plus_infty)), BUILD_COMPLEX (-M_PI_2l, 0), 0, 0, 0); check_complex ("catan (-inf - inf i) == -pi/2 - 0 i", FUNC(catan) (BUILD_COMPLEX (minus_infty, minus_infty)), BUILD_COMPLEX (-M_PI_2l, minus_zero), 0, 0, 0); check_complex ("catan (inf - 10.0 i) == pi/2 - 0 i", FUNC(catan) (BUILD_COMPLEX (plus_infty, -10.0)), BUILD_COMPLEX (M_PI_2l, minus_zero), 0, 0, 0); check_complex ("catan (-inf - 10.0 i) == -pi/2 - 0 i", FUNC(catan) (BUILD_COMPLEX (minus_infty, -10.0)), BUILD_COMPLEX (-M_PI_2l, minus_zero), 0, 0, 0); check_complex ("catan (inf - 0 i) == pi/2 - 0 i", FUNC(catan) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (M_PI_2l, minus_zero), 0, 0, 0); check_complex ("catan (-inf - 0 i) == -pi/2 - 0 i", FUNC(catan) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (-M_PI_2l, minus_zero), 0, 0, 0); check_complex ("catan (inf + 0.0 i) == pi/2 + 0 i", FUNC(catan) (BUILD_COMPLEX (plus_infty, 0.0)), BUILD_COMPLEX (M_PI_2l, 0), 0, 0, 0); check_complex ("catan (-inf + 0.0 i) == -pi/2 + 0 i", FUNC(catan) (BUILD_COMPLEX (minus_infty, 0.0)), BUILD_COMPLEX (-M_PI_2l, 0), 0, 0, 0); check_complex ("catan (inf + 0.1 i) == pi/2 + 0 i", FUNC(catan) (BUILD_COMPLEX (plus_infty, 0.1L)), BUILD_COMPLEX (M_PI_2l, 0), 0, 0, 0); check_complex ("catan (-inf + 0.1 i) == -pi/2 + 0 i", FUNC(catan) (BUILD_COMPLEX (minus_infty, 0.1L)), BUILD_COMPLEX (-M_PI_2l, 0), 0, 0, 0); check_complex ("catan (0.0 - inf i) == pi/2 - 0 i", FUNC(catan) (BUILD_COMPLEX (0.0, minus_infty)), BUILD_COMPLEX (M_PI_2l, minus_zero), 0, 0, 0); check_complex ("catan (-0 - inf i) == -pi/2 - 0 i", FUNC(catan) (BUILD_COMPLEX (minus_zero, minus_infty)), BUILD_COMPLEX (-M_PI_2l, minus_zero), 0, 0, 0); check_complex ("catan (100.0 - inf i) == pi/2 - 0 i", FUNC(catan) (BUILD_COMPLEX (100.0, minus_infty)), BUILD_COMPLEX (M_PI_2l, minus_zero), 0, 0, 0); check_complex ("catan (-100.0 - inf i) == -pi/2 - 0 i", FUNC(catan) (BUILD_COMPLEX (-100.0, minus_infty)), BUILD_COMPLEX (-M_PI_2l, minus_zero), 0, 0, 0); check_complex ("catan (0.0 + inf i) == pi/2 + 0 i", FUNC(catan) (BUILD_COMPLEX (0.0, plus_infty)), BUILD_COMPLEX (M_PI_2l, 0), 0, 0, 0); check_complex ("catan (-0 + inf i) == -pi/2 + 0 i", FUNC(catan) (BUILD_COMPLEX (minus_zero, plus_infty)), BUILD_COMPLEX (-M_PI_2l, 0), 0, 0, 0); check_complex ("catan (0.5 + inf i) == pi/2 + 0 i", FUNC(catan) (BUILD_COMPLEX (0.5, plus_infty)), BUILD_COMPLEX (M_PI_2l, 0), 0, 0, 0); check_complex ("catan (-0.5 + inf i) == -pi/2 + 0 i", FUNC(catan) (BUILD_COMPLEX (-0.5, plus_infty)), BUILD_COMPLEX (-M_PI_2l, 0), 0, 0, 0); check_complex ("catan (NaN + 0.0 i) == NaN + 0 i", FUNC(catan) (BUILD_COMPLEX (nan_value, 0.0)), BUILD_COMPLEX (nan_value, 0), 0, 0, 0); check_complex ("catan (NaN - 0 i) == NaN - 0 i", FUNC(catan) (BUILD_COMPLEX (nan_value, minus_zero)), BUILD_COMPLEX (nan_value, minus_zero), 0, 0, 0); check_complex ("catan (NaN + inf i) == NaN + 0 i", FUNC(catan) (BUILD_COMPLEX (nan_value, plus_infty)), BUILD_COMPLEX (nan_value, 0), 0, 0, 0); check_complex ("catan (NaN - inf i) == NaN - 0 i", FUNC(catan) (BUILD_COMPLEX (nan_value, minus_infty)), BUILD_COMPLEX (nan_value, minus_zero), 0, 0, 0); check_complex ("catan (0.0 + NaN i) == NaN + NaN i", FUNC(catan) (BUILD_COMPLEX (0.0, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); check_complex ("catan (-0 + NaN i) == NaN + NaN i", FUNC(catan) (BUILD_COMPLEX (minus_zero, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); check_complex ("catan (inf + NaN i) == pi/2 + 0 i plus sign of zero/inf not specified", FUNC(catan) (BUILD_COMPLEX (plus_infty, nan_value)), BUILD_COMPLEX (M_PI_2l, 0), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("catan (-inf + NaN i) == -pi/2 + 0 i plus sign of zero/inf not specified", FUNC(catan) (BUILD_COMPLEX (minus_infty, nan_value)), BUILD_COMPLEX (-M_PI_2l, 0), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("catan (NaN + 10.5 i) == NaN + NaN i plus invalid exception allowed", FUNC(catan) (BUILD_COMPLEX (nan_value, 10.5)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("catan (NaN - 10.5 i) == NaN + NaN i plus invalid exception allowed", FUNC(catan) (BUILD_COMPLEX (nan_value, -10.5)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("catan (0.75 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(catan) (BUILD_COMPLEX (0.75, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("catan (-0.75 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(catan) (BUILD_COMPLEX (-0.75, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("catan (NaN + NaN i) == NaN + NaN i", FUNC(catan) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); check_complex ("catan (0.7 + 1.2 i) == 1.0785743834118921877443707996386368 + 0.57705737765343067644394541889341712 i", FUNC(catan) (BUILD_COMPLEX (0.7L, 1.2L)), BUILD_COMPLEX (1.0785743834118921877443707996386368L, 0.57705737765343067644394541889341712L), DELTA301, 0, 0); check_complex ("catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i", FUNC(catan) (BUILD_COMPLEX (-2, -3)), BUILD_COMPLEX (-1.4099210495965755225306193844604208L, -0.22907268296853876629588180294200276L), DELTA302, 0, 0); print_complex_max_error ("catan", DELTAcatan, 0); } static void catanh_test (void) { errno = 0; FUNC(catanh) (BUILD_COMPLEX (0.7L, 1.2L)); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_complex ("catanh (0 + 0 i) == 0.0 + 0.0 i", FUNC(catanh) (BUILD_COMPLEX (0, 0)), BUILD_COMPLEX (0.0, 0.0), 0, 0, 0); check_complex ("catanh (-0 + 0 i) == -0 + 0.0 i", FUNC(catanh) (BUILD_COMPLEX (minus_zero, 0)), BUILD_COMPLEX (minus_zero, 0.0), 0, 0, 0); check_complex ("catanh (0 - 0 i) == 0.0 - 0 i", FUNC(catanh) (BUILD_COMPLEX (0, minus_zero)), BUILD_COMPLEX (0.0, minus_zero), 0, 0, 0); check_complex ("catanh (-0 - 0 i) == -0 - 0 i", FUNC(catanh) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (minus_zero, minus_zero), 0, 0, 0); check_complex ("catanh (inf + inf i) == 0.0 + pi/2 i", FUNC(catanh) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (0.0, M_PI_2l), 0, 0, 0); check_complex ("catanh (inf - inf i) == 0.0 - pi/2 i", FUNC(catanh) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (0.0, -M_PI_2l), 0, 0, 0); check_complex ("catanh (-inf + inf i) == -0 + pi/2 i", FUNC(catanh) (BUILD_COMPLEX (minus_infty, plus_infty)), BUILD_COMPLEX (minus_zero, M_PI_2l), 0, 0, 0); check_complex ("catanh (-inf - inf i) == -0 - pi/2 i", FUNC(catanh) (BUILD_COMPLEX (minus_infty, minus_infty)), BUILD_COMPLEX (minus_zero, -M_PI_2l), 0, 0, 0); check_complex ("catanh (-10.0 + inf i) == -0 + pi/2 i", FUNC(catanh) (BUILD_COMPLEX (-10.0, plus_infty)), BUILD_COMPLEX (minus_zero, M_PI_2l), 0, 0, 0); check_complex ("catanh (-10.0 - inf i) == -0 - pi/2 i", FUNC(catanh) (BUILD_COMPLEX (-10.0, minus_infty)), BUILD_COMPLEX (minus_zero, -M_PI_2l), 0, 0, 0); check_complex ("catanh (-0 + inf i) == -0 + pi/2 i", FUNC(catanh) (BUILD_COMPLEX (minus_zero, plus_infty)), BUILD_COMPLEX (minus_zero, M_PI_2l), 0, 0, 0); check_complex ("catanh (-0 - inf i) == -0 - pi/2 i", FUNC(catanh) (BUILD_COMPLEX (minus_zero, minus_infty)), BUILD_COMPLEX (minus_zero, -M_PI_2l), 0, 0, 0); check_complex ("catanh (0 + inf i) == 0.0 + pi/2 i", FUNC(catanh) (BUILD_COMPLEX (0, plus_infty)), BUILD_COMPLEX (0.0, M_PI_2l), 0, 0, 0); check_complex ("catanh (0 - inf i) == 0.0 - pi/2 i", FUNC(catanh) (BUILD_COMPLEX (0, minus_infty)), BUILD_COMPLEX (0.0, -M_PI_2l), 0, 0, 0); check_complex ("catanh (0.1 + inf i) == 0.0 + pi/2 i", FUNC(catanh) (BUILD_COMPLEX (0.1L, plus_infty)), BUILD_COMPLEX (0.0, M_PI_2l), 0, 0, 0); check_complex ("catanh (0.1 - inf i) == 0.0 - pi/2 i", FUNC(catanh) (BUILD_COMPLEX (0.1L, minus_infty)), BUILD_COMPLEX (0.0, -M_PI_2l), 0, 0, 0); check_complex ("catanh (-inf + 0 i) == -0 + pi/2 i", FUNC(catanh) (BUILD_COMPLEX (minus_infty, 0)), BUILD_COMPLEX (minus_zero, M_PI_2l), 0, 0, 0); check_complex ("catanh (-inf - 0 i) == -0 - pi/2 i", FUNC(catanh) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (minus_zero, -M_PI_2l), 0, 0, 0); check_complex ("catanh (-inf + 100 i) == -0 + pi/2 i", FUNC(catanh) (BUILD_COMPLEX (minus_infty, 100)), BUILD_COMPLEX (minus_zero, M_PI_2l), 0, 0, 0); check_complex ("catanh (-inf - 100 i) == -0 - pi/2 i", FUNC(catanh) (BUILD_COMPLEX (minus_infty, -100)), BUILD_COMPLEX (minus_zero, -M_PI_2l), 0, 0, 0); check_complex ("catanh (inf + 0 i) == 0.0 + pi/2 i", FUNC(catanh) (BUILD_COMPLEX (plus_infty, 0)), BUILD_COMPLEX (0.0, M_PI_2l), 0, 0, 0); check_complex ("catanh (inf - 0 i) == 0.0 - pi/2 i", FUNC(catanh) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (0.0, -M_PI_2l), 0, 0, 0); check_complex ("catanh (inf + 0.5 i) == 0.0 + pi/2 i", FUNC(catanh) (BUILD_COMPLEX (plus_infty, 0.5)), BUILD_COMPLEX (0.0, M_PI_2l), 0, 0, 0); check_complex ("catanh (inf - 0.5 i) == 0.0 - pi/2 i", FUNC(catanh) (BUILD_COMPLEX (plus_infty, -0.5)), BUILD_COMPLEX (0.0, -M_PI_2l), 0, 0, 0); check_complex ("catanh (0 + NaN i) == 0.0 + NaN i", FUNC(catanh) (BUILD_COMPLEX (0, nan_value)), BUILD_COMPLEX (0.0, nan_value), 0, 0, 0); check_complex ("catanh (-0 + NaN i) == -0 + NaN i", FUNC(catanh) (BUILD_COMPLEX (minus_zero, nan_value)), BUILD_COMPLEX (minus_zero, nan_value), 0, 0, 0); check_complex ("catanh (inf + NaN i) == 0.0 + NaN i", FUNC(catanh) (BUILD_COMPLEX (plus_infty, nan_value)), BUILD_COMPLEX (0.0, nan_value), 0, 0, 0); check_complex ("catanh (-inf + NaN i) == -0 + NaN i", FUNC(catanh) (BUILD_COMPLEX (minus_infty, nan_value)), BUILD_COMPLEX (minus_zero, nan_value), 0, 0, 0); check_complex ("catanh (NaN + 0 i) == NaN + NaN i", FUNC(catanh) (BUILD_COMPLEX (nan_value, 0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); check_complex ("catanh (NaN - 0 i) == NaN + NaN i", FUNC(catanh) (BUILD_COMPLEX (nan_value, minus_zero)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); check_complex ("catanh (NaN + inf i) == 0.0 + pi/2 i plus sign of zero/inf not specified", FUNC(catanh) (BUILD_COMPLEX (nan_value, plus_infty)), BUILD_COMPLEX (0.0, M_PI_2l), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("catanh (NaN - inf i) == 0.0 - pi/2 i plus sign of zero/inf not specified", FUNC(catanh) (BUILD_COMPLEX (nan_value, minus_infty)), BUILD_COMPLEX (0.0, -M_PI_2l), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("catanh (10.5 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(catanh) (BUILD_COMPLEX (10.5, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("catanh (-10.5 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(catanh) (BUILD_COMPLEX (-10.5, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("catanh (NaN + 0.75 i) == NaN + NaN i plus invalid exception allowed", FUNC(catanh) (BUILD_COMPLEX (nan_value, 0.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("catanh (NaN - 0.75 i) == NaN + NaN i plus invalid exception allowed", FUNC(catanh) (BUILD_COMPLEX (nan_value, -0.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("catanh (NaN + NaN i) == NaN + NaN i", FUNC(catanh) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); check_complex ("catanh (0.7 + 1.2 i) == 0.2600749516525135959200648705635915 + 0.97024030779509898497385130162655963 i", FUNC(catanh) (BUILD_COMPLEX (0.7L, 1.2L)), BUILD_COMPLEX (0.2600749516525135959200648705635915L, 0.97024030779509898497385130162655963L), DELTA340, 0, 0); check_complex ("catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i", FUNC(catanh) (BUILD_COMPLEX (-2, -3)), BUILD_COMPLEX (-0.14694666622552975204743278515471595L, -1.3389725222944935611241935759091443L), DELTA341, 0, 0); print_complex_max_error ("catanh", DELTAcatanh, 0); } #endif static void cbrt_test (void) { errno = 0; FUNC(cbrt) (8); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_float ("cbrt (0.0) == 0.0", FUNC(cbrt) (0.0), 0.0, 0, 0, 0); check_float ("cbrt (-0) == -0", FUNC(cbrt) (minus_zero), minus_zero, 0, 0, 0); check_float ("cbrt (inf) == inf", FUNC(cbrt) (plus_infty), plus_infty, 0, 0, 0); check_float ("cbrt (-inf) == -inf", FUNC(cbrt) (minus_infty), minus_infty, 0, 0, 0); check_float ("cbrt (NaN) == NaN", FUNC(cbrt) (nan_value), nan_value, 0, 0, 0); check_float ("cbrt (-0.001) == -0.1", FUNC(cbrt) (-0.001L), -0.1L, DELTA347, 0, 0); check_float ("cbrt (8) == 2", FUNC(cbrt) (8), 2, 0, 0, 0); check_float ("cbrt (-27.0) == -3.0", FUNC(cbrt) (-27.0), -3.0, DELTA349, 0, 0); check_float ("cbrt (0.970299) == 0.99", FUNC(cbrt) (0.970299L), 0.99L, DELTA350, 0, 0); check_float ("cbrt (0.7) == 0.8879040017426007084", FUNC(cbrt) (0.7L), 0.8879040017426007084L, DELTA351, 0, 0); print_max_error ("cbrt", DELTAcbrt, 0); } #if 0 /* XXX scp XXX */ static void ccos_test (void) { errno = 0; FUNC(ccos) (BUILD_COMPLEX (0, 0)); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_complex ("ccos (0.0 + 0.0 i) == 1.0 - 0 i", FUNC(ccos) (BUILD_COMPLEX (0.0, 0.0)), BUILD_COMPLEX (1.0, minus_zero), 0, 0, 0); check_complex ("ccos (-0 + 0.0 i) == 1.0 + 0.0 i", FUNC(ccos) (BUILD_COMPLEX (minus_zero, 0.0)), BUILD_COMPLEX (1.0, 0.0), 0, 0, 0); check_complex ("ccos (0.0 - 0 i) == 1.0 + 0.0 i", FUNC(ccos) (BUILD_COMPLEX (0.0, minus_zero)), BUILD_COMPLEX (1.0, 0.0), 0, 0, 0); check_complex ("ccos (-0 - 0 i) == 1.0 - 0 i", FUNC(ccos) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (1.0, minus_zero), 0, 0, 0); check_complex ("ccos (inf + 0.0 i) == NaN + 0.0 i plus invalid exception and sign of zero/inf not specified", FUNC(ccos) (BUILD_COMPLEX (plus_infty, 0.0)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); check_complex ("ccos (inf - 0 i) == NaN + 0.0 i plus invalid exception and sign of zero/inf not specified", FUNC(ccos) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); check_complex ("ccos (-inf + 0.0 i) == NaN + 0.0 i plus invalid exception and sign of zero/inf not specified", FUNC(ccos) (BUILD_COMPLEX (minus_infty, 0.0)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); check_complex ("ccos (-inf - 0 i) == NaN + 0.0 i plus invalid exception and sign of zero/inf not specified", FUNC(ccos) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); check_complex ("ccos (0.0 + inf i) == inf - 0 i", FUNC(ccos) (BUILD_COMPLEX (0.0, plus_infty)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); check_complex ("ccos (0.0 - inf i) == inf + 0.0 i", FUNC(ccos) (BUILD_COMPLEX (0.0, minus_infty)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); check_complex ("ccos (-0 + inf i) == inf + 0.0 i", FUNC(ccos) (BUILD_COMPLEX (minus_zero, plus_infty)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); check_complex ("ccos (-0 - inf i) == inf - 0 i", FUNC(ccos) (BUILD_COMPLEX (minus_zero, minus_infty)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); check_complex ("ccos (inf + inf i) == inf + NaN i plus invalid exception", FUNC(ccos) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ccos (-inf + inf i) == inf + NaN i plus invalid exception", FUNC(ccos) (BUILD_COMPLEX (minus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ccos (inf - inf i) == inf + NaN i plus invalid exception", FUNC(ccos) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ccos (-inf - inf i) == inf + NaN i plus invalid exception", FUNC(ccos) (BUILD_COMPLEX (minus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ccos (4.625 + inf i) == -inf + inf i", FUNC(ccos) (BUILD_COMPLEX (4.625, plus_infty)), BUILD_COMPLEX (minus_infty, plus_infty), 0, 0, 0); check_complex ("ccos (4.625 - inf i) == -inf - inf i", FUNC(ccos) (BUILD_COMPLEX (4.625, minus_infty)), BUILD_COMPLEX (minus_infty, minus_infty), 0, 0, 0); check_complex ("ccos (-4.625 + inf i) == -inf - inf i", FUNC(ccos) (BUILD_COMPLEX (-4.625, plus_infty)), BUILD_COMPLEX (minus_infty, minus_infty), 0, 0, 0); check_complex ("ccos (-4.625 - inf i) == -inf + inf i", FUNC(ccos) (BUILD_COMPLEX (-4.625, minus_infty)), BUILD_COMPLEX (minus_infty, plus_infty), 0, 0, 0); check_complex ("ccos (inf + 6.75 i) == NaN + NaN i plus invalid exception", FUNC(ccos) (BUILD_COMPLEX (plus_infty, 6.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ccos (inf - 6.75 i) == NaN + NaN i plus invalid exception", FUNC(ccos) (BUILD_COMPLEX (plus_infty, -6.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ccos (-inf + 6.75 i) == NaN + NaN i plus invalid exception", FUNC(ccos) (BUILD_COMPLEX (minus_infty, 6.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ccos (-inf - 6.75 i) == NaN + NaN i plus invalid exception", FUNC(ccos) (BUILD_COMPLEX (minus_infty, -6.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ccos (NaN + 0.0 i) == NaN + 0.0 i plus sign of zero/inf not specified", FUNC(ccos) (BUILD_COMPLEX (nan_value, 0.0)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("ccos (NaN - 0 i) == NaN + 0.0 i plus sign of zero/inf not specified", FUNC(ccos) (BUILD_COMPLEX (nan_value, minus_zero)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("ccos (NaN + inf i) == inf + NaN i", FUNC(ccos) (BUILD_COMPLEX (nan_value, plus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); check_complex ("ccos (NaN - inf i) == inf + NaN i", FUNC(ccos) (BUILD_COMPLEX (nan_value, minus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); check_complex ("ccos (NaN + 9.0 i) == NaN + NaN i plus invalid exception allowed", FUNC(ccos) (BUILD_COMPLEX (nan_value, 9.0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("ccos (NaN - 9.0 i) == NaN + NaN i plus invalid exception allowed", FUNC(ccos) (BUILD_COMPLEX (nan_value, -9.0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("ccos (0.0 + NaN i) == NaN + 0.0 i plus sign of zero/inf not specified", FUNC(ccos) (BUILD_COMPLEX (0.0, nan_value)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("ccos (-0 + NaN i) == NaN + 0.0 i plus sign of zero/inf not specified", FUNC(ccos) (BUILD_COMPLEX (minus_zero, nan_value)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("ccos (10.0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(ccos) (BUILD_COMPLEX (10.0, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("ccos (-10.0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(ccos) (BUILD_COMPLEX (-10.0, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("ccos (inf + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(ccos) (BUILD_COMPLEX (plus_infty, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("ccos (-inf + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(ccos) (BUILD_COMPLEX (minus_infty, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("ccos (NaN + NaN i) == NaN + NaN i", FUNC(ccos) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); check_complex ("ccos (0.7 + 1.2 i) == 1.3848657645312111080 - 0.97242170335830028619 i", FUNC(ccos) (BUILD_COMPLEX (0.7L, 1.2L)), BUILD_COMPLEX (1.3848657645312111080L, -0.97242170335830028619L), DELTA389, 0, 0); check_complex ("ccos (-2 - 3 i) == -4.1896256909688072301 - 9.1092278937553365979 i", FUNC(ccos) (BUILD_COMPLEX (-2, -3)), BUILD_COMPLEX (-4.1896256909688072301L, -9.1092278937553365979L), DELTA390, 0, 0); print_complex_max_error ("ccos", DELTAccos, 0); } static void ccosh_test (void) { errno = 0; FUNC(ccosh) (BUILD_COMPLEX (0.7L, 1.2L)); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_complex ("ccosh (0.0 + 0.0 i) == 1.0 + 0.0 i", FUNC(ccosh) (BUILD_COMPLEX (0.0, 0.0)), BUILD_COMPLEX (1.0, 0.0), 0, 0, 0); check_complex ("ccosh (-0 + 0.0 i) == 1.0 - 0 i", FUNC(ccosh) (BUILD_COMPLEX (minus_zero, 0.0)), BUILD_COMPLEX (1.0, minus_zero), 0, 0, 0); check_complex ("ccosh (0.0 - 0 i) == 1.0 - 0 i", FUNC(ccosh) (BUILD_COMPLEX (0.0, minus_zero)), BUILD_COMPLEX (1.0, minus_zero), 0, 0, 0); check_complex ("ccosh (-0 - 0 i) == 1.0 + 0.0 i", FUNC(ccosh) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (1.0, 0.0), 0, 0, 0); check_complex ("ccosh (0.0 + inf i) == NaN + 0.0 i plus invalid exception and sign of zero/inf not specified", FUNC(ccosh) (BUILD_COMPLEX (0.0, plus_infty)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); check_complex ("ccosh (-0 + inf i) == NaN + 0.0 i plus invalid exception and sign of zero/inf not specified", FUNC(ccosh) (BUILD_COMPLEX (minus_zero, plus_infty)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); check_complex ("ccosh (0.0 - inf i) == NaN + 0.0 i plus invalid exception and sign of zero/inf not specified", FUNC(ccosh) (BUILD_COMPLEX (0.0, minus_infty)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); check_complex ("ccosh (-0 - inf i) == NaN + 0.0 i plus invalid exception and sign of zero/inf not specified", FUNC(ccosh) (BUILD_COMPLEX (minus_zero, minus_infty)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); check_complex ("ccosh (inf + 0.0 i) == inf + 0.0 i", FUNC(ccosh) (BUILD_COMPLEX (plus_infty, 0.0)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); check_complex ("ccosh (-inf + 0.0 i) == inf - 0 i", FUNC(ccosh) (BUILD_COMPLEX (minus_infty, 0.0)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); check_complex ("ccosh (inf - 0 i) == inf - 0 i", FUNC(ccosh) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); check_complex ("ccosh (-inf - 0 i) == inf + 0.0 i", FUNC(ccosh) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); check_complex ("ccosh (inf + inf i) == inf + NaN i plus invalid exception", FUNC(ccosh) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ccosh (-inf + inf i) == inf + NaN i plus invalid exception", FUNC(ccosh) (BUILD_COMPLEX (minus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ccosh (inf - inf i) == inf + NaN i plus invalid exception", FUNC(ccosh) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ccosh (-inf - inf i) == inf + NaN i plus invalid exception", FUNC(ccosh) (BUILD_COMPLEX (minus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ccosh (inf + 4.625 i) == -inf - inf i", FUNC(ccosh) (BUILD_COMPLEX (plus_infty, 4.625)), BUILD_COMPLEX (minus_infty, minus_infty), 0, 0, 0); check_complex ("ccosh (-inf + 4.625 i) == -inf + inf i", FUNC(ccosh) (BUILD_COMPLEX (minus_infty, 4.625)), BUILD_COMPLEX (minus_infty, plus_infty), 0, 0, 0); check_complex ("ccosh (inf - 4.625 i) == -inf + inf i", FUNC(ccosh) (BUILD_COMPLEX (plus_infty, -4.625)), BUILD_COMPLEX (minus_infty, plus_infty), 0, 0, 0); check_complex ("ccosh (-inf - 4.625 i) == -inf - inf i", FUNC(ccosh) (BUILD_COMPLEX (minus_infty, -4.625)), BUILD_COMPLEX (minus_infty, minus_infty), 0, 0, 0); check_complex ("ccosh (6.75 + inf i) == NaN + NaN i plus invalid exception", FUNC(ccosh) (BUILD_COMPLEX (6.75, plus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ccosh (-6.75 + inf i) == NaN + NaN i plus invalid exception", FUNC(ccosh) (BUILD_COMPLEX (-6.75, plus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ccosh (6.75 - inf i) == NaN + NaN i plus invalid exception", FUNC(ccosh) (BUILD_COMPLEX (6.75, minus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ccosh (-6.75 - inf i) == NaN + NaN i plus invalid exception", FUNC(ccosh) (BUILD_COMPLEX (-6.75, minus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ccosh (0.0 + NaN i) == NaN + 0.0 i plus sign of zero/inf not specified", FUNC(ccosh) (BUILD_COMPLEX (0.0, nan_value)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("ccosh (-0 + NaN i) == NaN + 0.0 i plus sign of zero/inf not specified", FUNC(ccosh) (BUILD_COMPLEX (minus_zero, nan_value)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("ccosh (inf + NaN i) == inf + NaN i", FUNC(ccosh) (BUILD_COMPLEX (plus_infty, nan_value)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); check_complex ("ccosh (-inf + NaN i) == inf + NaN i", FUNC(ccosh) (BUILD_COMPLEX (minus_infty, nan_value)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); check_complex ("ccosh (9.0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(ccosh) (BUILD_COMPLEX (9.0, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("ccosh (-9.0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(ccosh) (BUILD_COMPLEX (-9.0, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("ccosh (NaN + 0.0 i) == NaN + 0.0 i plus sign of zero/inf not specified", FUNC(ccosh) (BUILD_COMPLEX (nan_value, 0.0)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("ccosh (NaN - 0 i) == NaN + 0.0 i plus sign of zero/inf not specified", FUNC(ccosh) (BUILD_COMPLEX (nan_value, minus_zero)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("ccosh (NaN + 10.0 i) == NaN + NaN i plus invalid exception allowed", FUNC(ccosh) (BUILD_COMPLEX (nan_value, 10.0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("ccosh (NaN - 10.0 i) == NaN + NaN i plus invalid exception allowed", FUNC(ccosh) (BUILD_COMPLEX (nan_value, -10.0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("ccosh (NaN + inf i) == NaN + NaN i plus invalid exception allowed", FUNC(ccosh) (BUILD_COMPLEX (nan_value, plus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("ccosh (NaN - inf i) == NaN + NaN i plus invalid exception allowed", FUNC(ccosh) (BUILD_COMPLEX (nan_value, minus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("ccosh (NaN + NaN i) == NaN + NaN i", FUNC(ccosh) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); check_complex ("ccosh (0.7 + 1.2 i) == 0.4548202223691477654 + 0.7070296600921537682 i", FUNC(ccosh) (BUILD_COMPLEX (0.7L, 1.2L)), BUILD_COMPLEX (0.4548202223691477654L, 0.7070296600921537682L), DELTA428, 0, 0); check_complex ("ccosh (-2 - 3 i) == -3.7245455049153225654 + 0.5118225699873846088 i", FUNC(ccosh) (BUILD_COMPLEX (-2, -3)), BUILD_COMPLEX (-3.7245455049153225654L, 0.5118225699873846088L), DELTA429, 0, 0); print_complex_max_error ("ccosh", DELTAccosh, 0); } #endif static void ceil_test (void) { init_max_error (); check_float ("ceil (0.0) == 0.0", FUNC(ceil) (0.0), 0.0, 0, 0, 0); check_float ("ceil (-0) == -0", FUNC(ceil) (minus_zero), minus_zero, 0, 0, 0); check_float ("ceil (inf) == inf", FUNC(ceil) (plus_infty), plus_infty, 0, 0, 0); check_float ("ceil (-inf) == -inf", FUNC(ceil) (minus_infty), minus_infty, 0, 0, 0); check_float ("ceil (NaN) == NaN", FUNC(ceil) (nan_value), nan_value, 0, 0, 0); check_float ("ceil (pi) == 4.0", FUNC(ceil) (M_PIl), 4.0, 0, 0, 0); check_float ("ceil (-pi) == -3.0", FUNC(ceil) (-M_PIl), -3.0, 0, 0, 0); print_max_error ("ceil", 0, 0); } #if 0 /* XXX scp XXX */ static void cexp_test (void) { errno = 0; FUNC(cexp) (BUILD_COMPLEX (0, 0)); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_complex ("cexp (+0 + +0 i) == 1 + 0.0 i", FUNC(cexp) (BUILD_COMPLEX (plus_zero, plus_zero)), BUILD_COMPLEX (1, 0.0), 0, 0, 0); check_complex ("cexp (-0 + +0 i) == 1 + 0.0 i", FUNC(cexp) (BUILD_COMPLEX (minus_zero, plus_zero)), BUILD_COMPLEX (1, 0.0), 0, 0, 0); check_complex ("cexp (+0 - 0 i) == 1 - 0 i", FUNC(cexp) (BUILD_COMPLEX (plus_zero, minus_zero)), BUILD_COMPLEX (1, minus_zero), 0, 0, 0); check_complex ("cexp (-0 - 0 i) == 1 - 0 i", FUNC(cexp) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (1, minus_zero), 0, 0, 0); check_complex ("cexp (inf + +0 i) == inf + 0.0 i", FUNC(cexp) (BUILD_COMPLEX (plus_infty, plus_zero)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); check_complex ("cexp (inf - 0 i) == inf - 0 i", FUNC(cexp) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); check_complex ("cexp (-inf + +0 i) == 0.0 + 0.0 i", FUNC(cexp) (BUILD_COMPLEX (minus_infty, plus_zero)), BUILD_COMPLEX (0.0, 0.0), 0, 0, 0); check_complex ("cexp (-inf - 0 i) == 0.0 - 0 i", FUNC(cexp) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (0.0, minus_zero), 0, 0, 0); check_complex ("cexp (0.0 + inf i) == NaN + NaN i plus invalid exception", FUNC(cexp) (BUILD_COMPLEX (0.0, plus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("cexp (-0 + inf i) == NaN + NaN i plus invalid exception", FUNC(cexp) (BUILD_COMPLEX (minus_zero, plus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("cexp (0.0 - inf i) == NaN + NaN i plus invalid exception", FUNC(cexp) (BUILD_COMPLEX (0.0, minus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("cexp (-0 - inf i) == NaN + NaN i plus invalid exception", FUNC(cexp) (BUILD_COMPLEX (minus_zero, minus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("cexp (100.0 + inf i) == NaN + NaN i plus invalid exception", FUNC(cexp) (BUILD_COMPLEX (100.0, plus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("cexp (-100.0 + inf i) == NaN + NaN i plus invalid exception", FUNC(cexp) (BUILD_COMPLEX (-100.0, plus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("cexp (100.0 - inf i) == NaN + NaN i plus invalid exception", FUNC(cexp) (BUILD_COMPLEX (100.0, minus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("cexp (-100.0 - inf i) == NaN + NaN i plus invalid exception", FUNC(cexp) (BUILD_COMPLEX (-100.0, minus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("cexp (-inf + 2.0 i) == -0 + 0.0 i", FUNC(cexp) (BUILD_COMPLEX (minus_infty, 2.0)), BUILD_COMPLEX (minus_zero, 0.0), 0, 0, 0); check_complex ("cexp (-inf + 4.0 i) == -0 - 0 i", FUNC(cexp) (BUILD_COMPLEX (minus_infty, 4.0)), BUILD_COMPLEX (minus_zero, minus_zero), 0, 0, 0); check_complex ("cexp (inf + 2.0 i) == -inf + inf i", FUNC(cexp) (BUILD_COMPLEX (plus_infty, 2.0)), BUILD_COMPLEX (minus_infty, plus_infty), 0, 0, 0); check_complex ("cexp (inf + 4.0 i) == -inf - inf i", FUNC(cexp) (BUILD_COMPLEX (plus_infty, 4.0)), BUILD_COMPLEX (minus_infty, minus_infty), 0, 0, 0); check_complex ("cexp (inf + inf i) == inf + NaN i plus invalid exception and sign of zero/inf not specified", FUNC(cexp) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); check_complex ("cexp (inf - inf i) == inf + NaN i plus invalid exception and sign of zero/inf not specified", FUNC(cexp) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); check_complex ("cexp (-inf + inf i) == 0.0 + 0.0 i plus sign of zero/inf not specified", FUNC(cexp) (BUILD_COMPLEX (minus_infty, plus_infty)), BUILD_COMPLEX (0.0, 0.0), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("cexp (-inf - inf i) == 0.0 - 0 i plus sign of zero/inf not specified", FUNC(cexp) (BUILD_COMPLEX (minus_infty, minus_infty)), BUILD_COMPLEX (0.0, minus_zero), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("cexp (-inf + NaN i) == 0 + 0 i plus sign of zero/inf not specified", FUNC(cexp) (BUILD_COMPLEX (minus_infty, nan_value)), BUILD_COMPLEX (0, 0), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("cexp (inf + NaN i) == inf + NaN i", FUNC(cexp) (BUILD_COMPLEX (plus_infty, nan_value)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); check_complex ("cexp (NaN + 0.0 i) == NaN + NaN i plus invalid exception allowed", FUNC(cexp) (BUILD_COMPLEX (nan_value, 0.0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("cexp (NaN + 1.0 i) == NaN + NaN i plus invalid exception allowed", FUNC(cexp) (BUILD_COMPLEX (nan_value, 1.0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("cexp (NaN + inf i) == NaN + NaN i plus invalid exception allowed", FUNC(cexp) (BUILD_COMPLEX (nan_value, plus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("cexp (0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(cexp) (BUILD_COMPLEX (0, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("cexp (1 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(cexp) (BUILD_COMPLEX (1, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("cexp (NaN + NaN i) == NaN + NaN i", FUNC(cexp) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); check_complex ("cexp (0.7 + 1.2 i) == 0.72969890915032360123451688642930727 + 1.8768962328348102821139467908203072 i", FUNC(cexp) (BUILD_COMPLEX (0.7L, 1.2L)), BUILD_COMPLEX (0.72969890915032360123451688642930727L, 1.8768962328348102821139467908203072L), DELTA469, 0, 0); check_complex ("cexp (-2.0 - 3.0 i) == -0.13398091492954261346140525546115575 - 0.019098516261135196432576240858800925 i", FUNC(cexp) (BUILD_COMPLEX (-2.0, -3.0)), BUILD_COMPLEX (-0.13398091492954261346140525546115575L, -0.019098516261135196432576240858800925L), DELTA470, 0, 0); print_complex_max_error ("cexp", DELTAcexp, 0); } static void cimag_test (void) { init_max_error (); check_float ("cimag (1.0 + 0.0 i) == 0.0", FUNC(cimag) (BUILD_COMPLEX (1.0, 0.0)), 0.0, 0, 0, 0); check_float ("cimag (1.0 - 0 i) == -0", FUNC(cimag) (BUILD_COMPLEX (1.0, minus_zero)), minus_zero, 0, 0, 0); check_float ("cimag (1.0 + NaN i) == NaN", FUNC(cimag) (BUILD_COMPLEX (1.0, nan_value)), nan_value, 0, 0, 0); check_float ("cimag (NaN + NaN i) == NaN", FUNC(cimag) (BUILD_COMPLEX (nan_value, nan_value)), nan_value, 0, 0, 0); check_float ("cimag (1.0 + inf i) == inf", FUNC(cimag) (BUILD_COMPLEX (1.0, plus_infty)), plus_infty, 0, 0, 0); check_float ("cimag (1.0 - inf i) == -inf", FUNC(cimag) (BUILD_COMPLEX (1.0, minus_infty)), minus_infty, 0, 0, 0); check_float ("cimag (2.0 + 3.0 i) == 3.0", FUNC(cimag) (BUILD_COMPLEX (2.0, 3.0)), 3.0, 0, 0, 0); print_max_error ("cimag", 0, 0); } static void clog_test (void) { errno = 0; FUNC(clog) (BUILD_COMPLEX (-2, -3)); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_complex ("clog (-0 + 0 i) == -inf + pi i plus division by zero exception", FUNC(clog) (BUILD_COMPLEX (minus_zero, 0)), BUILD_COMPLEX (minus_infty, M_PIl), 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_complex ("clog (-0 - 0 i) == -inf - pi i plus division by zero exception", FUNC(clog) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (minus_infty, -M_PIl), 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_complex ("clog (0 + 0 i) == -inf + 0.0 i plus division by zero exception", FUNC(clog) (BUILD_COMPLEX (0, 0)), BUILD_COMPLEX (minus_infty, 0.0), 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_complex ("clog (0 - 0 i) == -inf - 0 i plus division by zero exception", FUNC(clog) (BUILD_COMPLEX (0, minus_zero)), BUILD_COMPLEX (minus_infty, minus_zero), 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_complex ("clog (-inf + inf i) == inf + 3/4 pi i", FUNC(clog) (BUILD_COMPLEX (minus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI_34l), 0, 0, 0); check_complex ("clog (-inf - inf i) == inf - 3/4 pi i", FUNC(clog) (BUILD_COMPLEX (minus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI_34l), 0, 0, 0); check_complex ("clog (inf + inf i) == inf + pi/4 i", FUNC(clog) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI_4l), 0, 0, 0); check_complex ("clog (inf - inf i) == inf - pi/4 i", FUNC(clog) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI_4l), 0, 0, 0); check_complex ("clog (0 + inf i) == inf + pi/2 i", FUNC(clog) (BUILD_COMPLEX (0, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI_2l), 0, 0, 0); check_complex ("clog (3 + inf i) == inf + pi/2 i", FUNC(clog) (BUILD_COMPLEX (3, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI_2l), 0, 0, 0); check_complex ("clog (-0 + inf i) == inf + pi/2 i", FUNC(clog) (BUILD_COMPLEX (minus_zero, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI_2l), 0, 0, 0); check_complex ("clog (-3 + inf i) == inf + pi/2 i", FUNC(clog) (BUILD_COMPLEX (-3, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI_2l), 0, 0, 0); check_complex ("clog (0 - inf i) == inf - pi/2 i", FUNC(clog) (BUILD_COMPLEX (0, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI_2l), 0, 0, 0); check_complex ("clog (3 - inf i) == inf - pi/2 i", FUNC(clog) (BUILD_COMPLEX (3, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI_2l), 0, 0, 0); check_complex ("clog (-0 - inf i) == inf - pi/2 i", FUNC(clog) (BUILD_COMPLEX (minus_zero, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI_2l), 0, 0, 0); check_complex ("clog (-3 - inf i) == inf - pi/2 i", FUNC(clog) (BUILD_COMPLEX (-3, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI_2l), 0, 0, 0); check_complex ("clog (-inf + 0 i) == inf + pi i", FUNC(clog) (BUILD_COMPLEX (minus_infty, 0)), BUILD_COMPLEX (plus_infty, M_PIl), 0, 0, 0); check_complex ("clog (-inf + 1 i) == inf + pi i", FUNC(clog) (BUILD_COMPLEX (minus_infty, 1)), BUILD_COMPLEX (plus_infty, M_PIl), 0, 0, 0); check_complex ("clog (-inf - 0 i) == inf - pi i", FUNC(clog) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (plus_infty, -M_PIl), 0, 0, 0); check_complex ("clog (-inf - 1 i) == inf - pi i", FUNC(clog) (BUILD_COMPLEX (minus_infty, -1)), BUILD_COMPLEX (plus_infty, -M_PIl), 0, 0, 0); check_complex ("clog (inf + 0 i) == inf + 0.0 i", FUNC(clog) (BUILD_COMPLEX (plus_infty, 0)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); check_complex ("clog (inf + 1 i) == inf + 0.0 i", FUNC(clog) (BUILD_COMPLEX (plus_infty, 1)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); check_complex ("clog (inf - 0 i) == inf - 0 i", FUNC(clog) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); check_complex ("clog (inf - 1 i) == inf - 0 i", FUNC(clog) (BUILD_COMPLEX (plus_infty, -1)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); check_complex ("clog (inf + NaN i) == inf + NaN i", FUNC(clog) (BUILD_COMPLEX (plus_infty, nan_value)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); check_complex ("clog (-inf + NaN i) == inf + NaN i", FUNC(clog) (BUILD_COMPLEX (minus_infty, nan_value)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); check_complex ("clog (NaN + inf i) == inf + NaN i", FUNC(clog) (BUILD_COMPLEX (nan_value, plus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); check_complex ("clog (NaN - inf i) == inf + NaN i", FUNC(clog) (BUILD_COMPLEX (nan_value, minus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); check_complex ("clog (0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(clog) (BUILD_COMPLEX (0, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("clog (3 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(clog) (BUILD_COMPLEX (3, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("clog (-0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(clog) (BUILD_COMPLEX (minus_zero, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("clog (-3 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(clog) (BUILD_COMPLEX (-3, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("clog (NaN + 0 i) == NaN + NaN i plus invalid exception allowed", FUNC(clog) (BUILD_COMPLEX (nan_value, 0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("clog (NaN + 5 i) == NaN + NaN i plus invalid exception allowed", FUNC(clog) (BUILD_COMPLEX (nan_value, 5)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("clog (NaN - 0 i) == NaN + NaN i plus invalid exception allowed", FUNC(clog) (BUILD_COMPLEX (nan_value, minus_zero)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("clog (NaN - 5 i) == NaN + NaN i plus invalid exception allowed", FUNC(clog) (BUILD_COMPLEX (nan_value, -5)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("clog (NaN + NaN i) == NaN + NaN i", FUNC(clog) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); check_complex ("clog (-2 - 3 i) == 1.2824746787307683680267437207826593 - 2.1587989303424641704769327722648368 i", FUNC(clog) (BUILD_COMPLEX (-2, -3)), BUILD_COMPLEX (1.2824746787307683680267437207826593L, -2.1587989303424641704769327722648368L), DELTA515, 0, 0); print_complex_max_error ("clog", DELTAclog, 0); } static void clog10_test (void) { errno = 0; FUNC(clog10) (BUILD_COMPLEX (0.7L, 1.2L)); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_complex ("clog10 (-0 + 0 i) == -inf + pi i plus division by zero exception", FUNC(clog10) (BUILD_COMPLEX (minus_zero, 0)), BUILD_COMPLEX (minus_infty, M_PIl), 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_complex ("clog10 (-0 - 0 i) == -inf - pi i plus division by zero exception", FUNC(clog10) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (minus_infty, -M_PIl), 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_complex ("clog10 (0 + 0 i) == -inf + 0.0 i plus division by zero exception", FUNC(clog10) (BUILD_COMPLEX (0, 0)), BUILD_COMPLEX (minus_infty, 0.0), 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_complex ("clog10 (0 - 0 i) == -inf - 0 i plus division by zero exception", FUNC(clog10) (BUILD_COMPLEX (0, minus_zero)), BUILD_COMPLEX (minus_infty, minus_zero), 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_complex ("clog10 (-inf + inf i) == inf + 3/4 pi*log10(e) i", FUNC(clog10) (BUILD_COMPLEX (minus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI_34_LOG10El), DELTA520, 0, 0); check_complex ("clog10 (inf + inf i) == inf + pi/4*log10(e) i", FUNC(clog10) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI4_LOG10El), DELTA521, 0, 0); check_complex ("clog10 (inf - inf i) == inf - pi/4*log10(e) i", FUNC(clog10) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI4_LOG10El), DELTA522, 0, 0); check_complex ("clog10 (0 + inf i) == inf + pi/2*log10(e) i", FUNC(clog10) (BUILD_COMPLEX (0, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI2_LOG10El), DELTA523, 0, 0); check_complex ("clog10 (3 + inf i) == inf + pi/2*log10(e) i", FUNC(clog10) (BUILD_COMPLEX (3, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI2_LOG10El), DELTA524, 0, 0); check_complex ("clog10 (-0 + inf i) == inf + pi/2*log10(e) i", FUNC(clog10) (BUILD_COMPLEX (minus_zero, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI2_LOG10El), DELTA525, 0, 0); check_complex ("clog10 (-3 + inf i) == inf + pi/2*log10(e) i", FUNC(clog10) (BUILD_COMPLEX (-3, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI2_LOG10El), DELTA526, 0, 0); check_complex ("clog10 (0 - inf i) == inf - pi/2*log10(e) i", FUNC(clog10) (BUILD_COMPLEX (0, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI2_LOG10El), DELTA527, 0, 0); check_complex ("clog10 (3 - inf i) == inf - pi/2*log10(e) i", FUNC(clog10) (BUILD_COMPLEX (3, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI2_LOG10El), DELTA528, 0, 0); check_complex ("clog10 (-0 - inf i) == inf - pi/2*log10(e) i", FUNC(clog10) (BUILD_COMPLEX (minus_zero, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI2_LOG10El), DELTA529, 0, 0); check_complex ("clog10 (-3 - inf i) == inf - pi/2*log10(e) i", FUNC(clog10) (BUILD_COMPLEX (-3, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI2_LOG10El), DELTA530, 0, 0); check_complex ("clog10 (-inf + 0 i) == inf + pi*log10(e) i", FUNC(clog10) (BUILD_COMPLEX (minus_infty, 0)), BUILD_COMPLEX (plus_infty, M_PI_LOG10El), DELTA531, 0, 0); check_complex ("clog10 (-inf + 1 i) == inf + pi*log10(e) i", FUNC(clog10) (BUILD_COMPLEX (minus_infty, 1)), BUILD_COMPLEX (plus_infty, M_PI_LOG10El), DELTA532, 0, 0); check_complex ("clog10 (-inf - 0 i) == inf - pi*log10(e) i", FUNC(clog10) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (plus_infty, -M_PI_LOG10El), DELTA533, 0, 0); check_complex ("clog10 (-inf - 1 i) == inf - pi*log10(e) i", FUNC(clog10) (BUILD_COMPLEX (minus_infty, -1)), BUILD_COMPLEX (plus_infty, -M_PI_LOG10El), DELTA534, 0, 0); check_complex ("clog10 (inf + 0 i) == inf + 0.0 i", FUNC(clog10) (BUILD_COMPLEX (plus_infty, 0)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); check_complex ("clog10 (inf + 1 i) == inf + 0.0 i", FUNC(clog10) (BUILD_COMPLEX (plus_infty, 1)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); check_complex ("clog10 (inf - 0 i) == inf - 0 i", FUNC(clog10) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); check_complex ("clog10 (inf - 1 i) == inf - 0 i", FUNC(clog10) (BUILD_COMPLEX (plus_infty, -1)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); check_complex ("clog10 (inf + NaN i) == inf + NaN i", FUNC(clog10) (BUILD_COMPLEX (plus_infty, nan_value)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); check_complex ("clog10 (-inf + NaN i) == inf + NaN i", FUNC(clog10) (BUILD_COMPLEX (minus_infty, nan_value)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); check_complex ("clog10 (NaN + inf i) == inf + NaN i", FUNC(clog10) (BUILD_COMPLEX (nan_value, plus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); check_complex ("clog10 (NaN - inf i) == inf + NaN i", FUNC(clog10) (BUILD_COMPLEX (nan_value, minus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); check_complex ("clog10 (0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(clog10) (BUILD_COMPLEX (0, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("clog10 (3 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(clog10) (BUILD_COMPLEX (3, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("clog10 (-0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(clog10) (BUILD_COMPLEX (minus_zero, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("clog10 (-3 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(clog10) (BUILD_COMPLEX (-3, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("clog10 (NaN + 0 i) == NaN + NaN i plus invalid exception allowed", FUNC(clog10) (BUILD_COMPLEX (nan_value, 0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("clog10 (NaN + 5 i) == NaN + NaN i plus invalid exception allowed", FUNC(clog10) (BUILD_COMPLEX (nan_value, 5)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("clog10 (NaN - 0 i) == NaN + NaN i plus invalid exception allowed", FUNC(clog10) (BUILD_COMPLEX (nan_value, minus_zero)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("clog10 (NaN - 5 i) == NaN + NaN i plus invalid exception allowed", FUNC(clog10) (BUILD_COMPLEX (nan_value, -5)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("clog10 (NaN + NaN i) == NaN + NaN i", FUNC(clog10) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); check_complex ("clog10 (0.7 + 1.2 i) == 0.1427786545038868803 + 0.4528483579352493248 i", FUNC(clog10) (BUILD_COMPLEX (0.7L, 1.2L)), BUILD_COMPLEX (0.1427786545038868803L, 0.4528483579352493248L), DELTA552, 0, 0); check_complex ("clog10 (-2 - 3 i) == 0.5569716761534183846 - 0.9375544629863747085 i", FUNC(clog10) (BUILD_COMPLEX (-2, -3)), BUILD_COMPLEX (0.5569716761534183846L, -0.9375544629863747085L), DELTA553, 0, 0); print_complex_max_error ("clog10", DELTAclog10, 0); } static void conj_test (void) { init_max_error (); check_complex ("conj (0.0 + 0.0 i) == 0.0 - 0 i", FUNC(conj) (BUILD_COMPLEX (0.0, 0.0)), BUILD_COMPLEX (0.0, minus_zero), 0, 0, 0); check_complex ("conj (0.0 - 0 i) == 0.0 + 0.0 i", FUNC(conj) (BUILD_COMPLEX (0.0, minus_zero)), BUILD_COMPLEX (0.0, 0.0), 0, 0, 0); check_complex ("conj (NaN + NaN i) == NaN + NaN i", FUNC(conj) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); check_complex ("conj (inf - inf i) == inf + inf i", FUNC(conj) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, plus_infty), 0, 0, 0); check_complex ("conj (inf + inf i) == inf - inf i", FUNC(conj) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, minus_infty), 0, 0, 0); check_complex ("conj (1.0 + 2.0 i) == 1.0 - 2.0 i", FUNC(conj) (BUILD_COMPLEX (1.0, 2.0)), BUILD_COMPLEX (1.0, -2.0), 0, 0, 0); check_complex ("conj (3.0 - 4.0 i) == 3.0 + 4.0 i", FUNC(conj) (BUILD_COMPLEX (3.0, -4.0)), BUILD_COMPLEX (3.0, 4.0), 0, 0, 0); print_complex_max_error ("conj", 0, 0); } #endif static void copysign_test (void) { init_max_error (); check_float ("copysign (0, 4) == 0", FUNC(copysign) (0, 4), 0, 0, 0, 0); check_float ("copysign (0, -4) == -0", FUNC(copysign) (0, -4), minus_zero, 0, 0, 0); check_float ("copysign (-0, 4) == 0", FUNC(copysign) (minus_zero, 4), 0, 0, 0, 0); check_float ("copysign (-0, -4) == -0", FUNC(copysign) (minus_zero, -4), minus_zero, 0, 0, 0); check_float ("copysign (inf, 0) == inf", FUNC(copysign) (plus_infty, 0), plus_infty, 0, 0, 0); check_float ("copysign (inf, -0) == -inf", FUNC(copysign) (plus_infty, minus_zero), minus_infty, 0, 0, 0); check_float ("copysign (-inf, 0) == inf", FUNC(copysign) (minus_infty, 0), plus_infty, 0, 0, 0); check_float ("copysign (-inf, -0) == -inf", FUNC(copysign) (minus_infty, minus_zero), minus_infty, 0, 0, 0); check_float ("copysign (0, inf) == 0", FUNC(copysign) (0, plus_infty), 0, 0, 0, 0); check_float ("copysign (0, -0) == -0", FUNC(copysign) (0, minus_zero), minus_zero, 0, 0, 0); check_float ("copysign (-0, inf) == 0", FUNC(copysign) (minus_zero, plus_infty), 0, 0, 0, 0); check_float ("copysign (-0, -0) == -0", FUNC(copysign) (minus_zero, minus_zero), minus_zero, 0, 0, 0); /* XXX More correctly we would have to check the sign of the NaN. */ check_float ("copysign (NaN, 0) == NaN", FUNC(copysign) (nan_value, 0), nan_value, 0, 0, 0); check_float ("copysign (NaN, -0) == NaN", FUNC(copysign) (nan_value, minus_zero), nan_value, 0, 0, 0); check_float ("copysign (-NaN, 0) == NaN", FUNC(copysign) (-nan_value, 0), nan_value, 0, 0, 0); check_float ("copysign (-NaN, -0) == NaN", FUNC(copysign) (-nan_value, minus_zero), nan_value, 0, 0, 0); print_max_error ("copysign", 0, 0); } static void cos_test (void) { errno = 0; FUNC(cos) (0); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_float ("cos (0) == 1", FUNC(cos) (0), 1, 0, 0, 0); check_float ("cos (-0) == 1", FUNC(cos) (minus_zero), 1, 0, 0, 0); check_float ("cos (inf) == NaN plus invalid exception", FUNC(cos) (plus_infty), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("cos (-inf) == NaN plus invalid exception", FUNC(cos) (minus_infty), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("cos (NaN) == NaN", FUNC(cos) (nan_value), nan_value, 0, 0, 0); check_float ("cos (M_PI_6l * 2.0) == 0.5", FUNC(cos) (M_PI_6l * 2.0), 0.5, DELTA582, 0, 0); check_float ("cos (M_PI_6l * 4.0) == -0.5", FUNC(cos) (M_PI_6l * 4.0), -0.5, DELTA583, 0, 0); check_float ("cos (pi/2) == 0", FUNC(cos) (M_PI_2l), 0, DELTA584, 0, 0); check_float ("cos (0.7) == 0.76484218728448842625585999019186495", FUNC(cos) (0.7L), 0.76484218728448842625585999019186495L, DELTA585, 0, 0); print_max_error ("cos", DELTAcos, 0); } static void cosh_test (void) { errno = 0; FUNC(cosh) (0.7L); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_float ("cosh (0) == 1", FUNC(cosh) (0), 1, 0, 0, 0); check_float ("cosh (-0) == 1", FUNC(cosh) (minus_zero), 1, 0, 0, 0); #ifndef TEST_INLINE check_float ("cosh (inf) == inf", FUNC(cosh) (plus_infty), plus_infty, 0, 0, 0); check_float ("cosh (-inf) == inf", FUNC(cosh) (minus_infty), plus_infty, 0, 0, 0); #endif check_float ("cosh (NaN) == NaN", FUNC(cosh) (nan_value), nan_value, 0, 0, 0); check_float ("cosh (0.7) == 1.255169005630943018", FUNC(cosh) (0.7L), 1.255169005630943018L, DELTA591, 0, 0); print_max_error ("cosh", DELTAcosh, 0); } #if 0 /* XXX scp XXX */ static void cpow_test (void) { errno = 0; FUNC(cpow) (BUILD_COMPLEX (1, 0), BUILD_COMPLEX (0, 0)); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_complex ("cpow (1 + 0 i, 0 + 0 i) == 1.0 + 0.0 i", FUNC(cpow) (BUILD_COMPLEX (1, 0), BUILD_COMPLEX (0, 0)), BUILD_COMPLEX (1.0, 0.0), 0, 0, 0); check_complex ("cpow (2 + 0 i, 10 + 0 i) == 1024.0 + 0.0 i", FUNC(cpow) (BUILD_COMPLEX (2, 0), BUILD_COMPLEX (10, 0)), BUILD_COMPLEX (1024.0, 0.0), 0, 0, 0); check_complex ("cpow (e + 0 i, 0 + 2 * M_PIl i) == 1.0 + 0.0 i", FUNC(cpow) (BUILD_COMPLEX (M_El, 0), BUILD_COMPLEX (0, 2 * M_PIl)), BUILD_COMPLEX (1.0, 0.0), DELTA594, 0, 0); check_complex ("cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i", FUNC(cpow) (BUILD_COMPLEX (2, 3), BUILD_COMPLEX (4, 0)), BUILD_COMPLEX (-119.0, -120.0), DELTA595, 0, 0); check_complex ("cpow (NaN + NaN i, NaN + NaN i) == NaN + NaN i", FUNC(cpow) (BUILD_COMPLEX (nan_value, nan_value), BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); print_complex_max_error ("cpow", DELTAcpow, 0); } static void cproj_test (void) { init_max_error (); check_complex ("cproj (0.0 + 0.0 i) == 0.0 + 0.0 i", FUNC(cproj) (BUILD_COMPLEX (0.0, 0.0)), BUILD_COMPLEX (0.0, 0.0), 0, 0, 0); check_complex ("cproj (-0 - 0 i) == -0 - 0 i", FUNC(cproj) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (minus_zero, minus_zero), 0, 0, 0); check_complex ("cproj (0.0 - 0 i) == 0.0 - 0 i", FUNC(cproj) (BUILD_COMPLEX (0.0, minus_zero)), BUILD_COMPLEX (0.0, minus_zero), 0, 0, 0); check_complex ("cproj (-0 + 0.0 i) == -0 + 0.0 i", FUNC(cproj) (BUILD_COMPLEX (minus_zero, 0.0)), BUILD_COMPLEX (minus_zero, 0.0), 0, 0, 0); check_complex ("cproj (NaN + NaN i) == NaN + NaN i", FUNC(cproj) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); check_complex ("cproj (inf + inf i) == inf + 0.0 i", FUNC(cproj) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); check_complex ("cproj (inf - inf i) == inf - 0 i", FUNC(cproj) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); check_complex ("cproj (-inf + inf i) == inf + 0.0 i", FUNC(cproj) (BUILD_COMPLEX (minus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); check_complex ("cproj (-inf - inf i) == inf - 0 i", FUNC(cproj) (BUILD_COMPLEX (minus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); check_complex ("cproj (1.0 + 0.0 i) == 1.0 + 0.0 i", FUNC(cproj) (BUILD_COMPLEX (1.0, 0.0)), BUILD_COMPLEX (1.0, 0.0), 0, 0, 0); check_complex ("cproj (2.0 + 3.0 i) == 0.2857142857142857142857142857142857 + 0.42857142857142857142857142857142855 i", FUNC(cproj) (BUILD_COMPLEX (2.0, 3.0)), BUILD_COMPLEX (0.2857142857142857142857142857142857L, 0.42857142857142857142857142857142855L), 0, 0, 0); print_complex_max_error ("cproj", 0, 0); } static void creal_test (void) { init_max_error (); check_float ("creal (0.0 + 1.0 i) == 0.0", FUNC(creal) (BUILD_COMPLEX (0.0, 1.0)), 0.0, 0, 0, 0); check_float ("creal (-0 + 1.0 i) == -0", FUNC(creal) (BUILD_COMPLEX (minus_zero, 1.0)), minus_zero, 0, 0, 0); check_float ("creal (NaN + 1.0 i) == NaN", FUNC(creal) (BUILD_COMPLEX (nan_value, 1.0)), nan_value, 0, 0, 0); check_float ("creal (NaN + NaN i) == NaN", FUNC(creal) (BUILD_COMPLEX (nan_value, nan_value)), nan_value, 0, 0, 0); check_float ("creal (inf + 1.0 i) == inf", FUNC(creal) (BUILD_COMPLEX (plus_infty, 1.0)), plus_infty, 0, 0, 0); check_float ("creal (-inf + 1.0 i) == -inf", FUNC(creal) (BUILD_COMPLEX (minus_infty, 1.0)), minus_infty, 0, 0, 0); check_float ("creal (2.0 + 3.0 i) == 2.0", FUNC(creal) (BUILD_COMPLEX (2.0, 3.0)), 2.0, 0, 0, 0); print_max_error ("creal", 0, 0); } static void csin_test (void) { errno = 0; FUNC(csin) (BUILD_COMPLEX (0.7L, 1.2L)); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_complex ("csin (0.0 + 0.0 i) == 0.0 + 0.0 i", FUNC(csin) (BUILD_COMPLEX (0.0, 0.0)), BUILD_COMPLEX (0.0, 0.0), 0, 0, 0); check_complex ("csin (-0 + 0.0 i) == -0 + 0.0 i", FUNC(csin) (BUILD_COMPLEX (minus_zero, 0.0)), BUILD_COMPLEX (minus_zero, 0.0), 0, 0, 0); check_complex ("csin (0.0 - 0 i) == 0 - 0 i", FUNC(csin) (BUILD_COMPLEX (0.0, minus_zero)), BUILD_COMPLEX (0, minus_zero), 0, 0, 0); check_complex ("csin (-0 - 0 i) == -0 - 0 i", FUNC(csin) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (minus_zero, minus_zero), 0, 0, 0); check_complex ("csin (0.0 + inf i) == 0.0 + inf i", FUNC(csin) (BUILD_COMPLEX (0.0, plus_infty)), BUILD_COMPLEX (0.0, plus_infty), 0, 0, 0); check_complex ("csin (-0 + inf i) == -0 + inf i", FUNC(csin) (BUILD_COMPLEX (minus_zero, plus_infty)), BUILD_COMPLEX (minus_zero, plus_infty), 0, 0, 0); check_complex ("csin (0.0 - inf i) == 0.0 - inf i", FUNC(csin) (BUILD_COMPLEX (0.0, minus_infty)), BUILD_COMPLEX (0.0, minus_infty), 0, 0, 0); check_complex ("csin (-0 - inf i) == -0 - inf i", FUNC(csin) (BUILD_COMPLEX (minus_zero, minus_infty)), BUILD_COMPLEX (minus_zero, minus_infty), 0, 0, 0); check_complex ("csin (inf + 0.0 i) == NaN + 0.0 i plus invalid exception and sign of zero/inf not specified", FUNC(csin) (BUILD_COMPLEX (plus_infty, 0.0)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); check_complex ("csin (-inf + 0.0 i) == NaN + 0.0 i plus invalid exception and sign of zero/inf not specified", FUNC(csin) (BUILD_COMPLEX (minus_infty, 0.0)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); check_complex ("csin (inf - 0 i) == NaN + 0.0 i plus invalid exception and sign of zero/inf not specified", FUNC(csin) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); check_complex ("csin (-inf - 0 i) == NaN + 0.0 i plus invalid exception and sign of zero/inf not specified", FUNC(csin) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); check_complex ("csin (inf + inf i) == NaN + inf i plus invalid exception and sign of zero/inf not specified", FUNC(csin) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (nan_value, plus_infty), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); check_complex ("csin (-inf + inf i) == NaN + inf i plus invalid exception and sign of zero/inf not specified", FUNC(csin) (BUILD_COMPLEX (minus_infty, plus_infty)), BUILD_COMPLEX (nan_value, plus_infty), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); check_complex ("csin (inf - inf i) == NaN + inf i plus invalid exception and sign of zero/inf not specified", FUNC(csin) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (nan_value, plus_infty), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); check_complex ("csin (-inf - inf i) == NaN + inf i plus invalid exception and sign of zero/inf not specified", FUNC(csin) (BUILD_COMPLEX (minus_infty, minus_infty)), BUILD_COMPLEX (nan_value, plus_infty), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); check_complex ("csin (inf + 6.75 i) == NaN + NaN i plus invalid exception", FUNC(csin) (BUILD_COMPLEX (plus_infty, 6.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("csin (inf - 6.75 i) == NaN + NaN i plus invalid exception", FUNC(csin) (BUILD_COMPLEX (plus_infty, -6.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("csin (-inf + 6.75 i) == NaN + NaN i plus invalid exception", FUNC(csin) (BUILD_COMPLEX (minus_infty, 6.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("csin (-inf - 6.75 i) == NaN + NaN i plus invalid exception", FUNC(csin) (BUILD_COMPLEX (minus_infty, -6.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("csin (4.625 + inf i) == -inf - inf i", FUNC(csin) (BUILD_COMPLEX (4.625, plus_infty)), BUILD_COMPLEX (minus_infty, minus_infty), 0, 0, 0); check_complex ("csin (4.625 - inf i) == -inf + inf i", FUNC(csin) (BUILD_COMPLEX (4.625, minus_infty)), BUILD_COMPLEX (minus_infty, plus_infty), 0, 0, 0); check_complex ("csin (-4.625 + inf i) == inf - inf i", FUNC(csin) (BUILD_COMPLEX (-4.625, plus_infty)), BUILD_COMPLEX (plus_infty, minus_infty), 0, 0, 0); check_complex ("csin (-4.625 - inf i) == inf + inf i", FUNC(csin) (BUILD_COMPLEX (-4.625, minus_infty)), BUILD_COMPLEX (plus_infty, plus_infty), 0, 0, 0); check_complex ("csin (NaN + 0.0 i) == NaN + 0.0 i plus sign of zero/inf not specified", FUNC(csin) (BUILD_COMPLEX (nan_value, 0.0)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("csin (NaN - 0 i) == NaN + 0.0 i plus sign of zero/inf not specified", FUNC(csin) (BUILD_COMPLEX (nan_value, minus_zero)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("csin (NaN + inf i) == NaN + inf i plus sign of zero/inf not specified", FUNC(csin) (BUILD_COMPLEX (nan_value, plus_infty)), BUILD_COMPLEX (nan_value, plus_infty), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("csin (NaN - inf i) == NaN + inf i plus sign of zero/inf not specified", FUNC(csin) (BUILD_COMPLEX (nan_value, minus_infty)), BUILD_COMPLEX (nan_value, plus_infty), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("csin (NaN + 9.0 i) == NaN + NaN i plus invalid exception allowed", FUNC(csin) (BUILD_COMPLEX (nan_value, 9.0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("csin (NaN - 9.0 i) == NaN + NaN i plus invalid exception allowed", FUNC(csin) (BUILD_COMPLEX (nan_value, -9.0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("csin (0.0 + NaN i) == 0.0 + NaN i", FUNC(csin) (BUILD_COMPLEX (0.0, nan_value)), BUILD_COMPLEX (0.0, nan_value), 0, 0, 0); check_complex ("csin (-0 + NaN i) == -0 + NaN i", FUNC(csin) (BUILD_COMPLEX (minus_zero, nan_value)), BUILD_COMPLEX (minus_zero, nan_value), 0, 0, 0); check_complex ("csin (10.0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(csin) (BUILD_COMPLEX (10.0, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("csin (NaN - 10.0 i) == NaN + NaN i plus invalid exception allowed", FUNC(csin) (BUILD_COMPLEX (nan_value, -10.0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("csin (inf + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(csin) (BUILD_COMPLEX (plus_infty, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("csin (-inf + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(csin) (BUILD_COMPLEX (minus_infty, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("csin (NaN + NaN i) == NaN + NaN i", FUNC(csin) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); check_complex ("csin (0.7 + 1.2 i) == 1.1664563419657581376 + 1.1544997246948547371 i", FUNC(csin) (BUILD_COMPLEX (0.7L, 1.2L)), BUILD_COMPLEX (1.1664563419657581376L, 1.1544997246948547371L), DELTA652, 0, 0); check_complex ("csin (-2 - 3 i) == -9.1544991469114295734 + 4.1689069599665643507 i", FUNC(csin) (BUILD_COMPLEX (-2, -3)), BUILD_COMPLEX (-9.1544991469114295734L, 4.1689069599665643507L), 0, 0, 0); print_complex_max_error ("csin", DELTAcsin, 0); } static void csinh_test (void) { errno = 0; FUNC(csinh) (BUILD_COMPLEX (0.7L, 1.2L)); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_complex ("csinh (0.0 + 0.0 i) == 0.0 + 0.0 i", FUNC(csinh) (BUILD_COMPLEX (0.0, 0.0)), BUILD_COMPLEX (0.0, 0.0), 0, 0, 0); check_complex ("csinh (-0 + 0.0 i) == -0 + 0.0 i", FUNC(csinh) (BUILD_COMPLEX (minus_zero, 0.0)), BUILD_COMPLEX (minus_zero, 0.0), 0, 0, 0); check_complex ("csinh (0.0 - 0 i) == 0.0 - 0 i", FUNC(csinh) (BUILD_COMPLEX (0.0, minus_zero)), BUILD_COMPLEX (0.0, minus_zero), 0, 0, 0); check_complex ("csinh (-0 - 0 i) == -0 - 0 i", FUNC(csinh) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (minus_zero, minus_zero), 0, 0, 0); check_complex ("csinh (0.0 + inf i) == 0.0 + NaN i plus invalid exception and sign of zero/inf not specified", FUNC(csinh) (BUILD_COMPLEX (0.0, plus_infty)), BUILD_COMPLEX (0.0, nan_value), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); check_complex ("csinh (-0 + inf i) == 0.0 + NaN i plus invalid exception and sign of zero/inf not specified", FUNC(csinh) (BUILD_COMPLEX (minus_zero, plus_infty)), BUILD_COMPLEX (0.0, nan_value), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); check_complex ("csinh (0.0 - inf i) == 0.0 + NaN i plus invalid exception and sign of zero/inf not specified", FUNC(csinh) (BUILD_COMPLEX (0.0, minus_infty)), BUILD_COMPLEX (0.0, nan_value), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); check_complex ("csinh (-0 - inf i) == 0.0 + NaN i plus invalid exception and sign of zero/inf not specified", FUNC(csinh) (BUILD_COMPLEX (minus_zero, minus_infty)), BUILD_COMPLEX (0.0, nan_value), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); check_complex ("csinh (inf + 0.0 i) == inf + 0.0 i", FUNC(csinh) (BUILD_COMPLEX (plus_infty, 0.0)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); check_complex ("csinh (-inf + 0.0 i) == -inf + 0.0 i", FUNC(csinh) (BUILD_COMPLEX (minus_infty, 0.0)), BUILD_COMPLEX (minus_infty, 0.0), 0, 0, 0); check_complex ("csinh (inf - 0 i) == inf - 0 i", FUNC(csinh) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); check_complex ("csinh (-inf - 0 i) == -inf - 0 i", FUNC(csinh) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (minus_infty, minus_zero), 0, 0, 0); check_complex ("csinh (inf + inf i) == inf + NaN i plus invalid exception and sign of zero/inf not specified", FUNC(csinh) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); check_complex ("csinh (-inf + inf i) == inf + NaN i plus invalid exception and sign of zero/inf not specified", FUNC(csinh) (BUILD_COMPLEX (minus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); check_complex ("csinh (inf - inf i) == inf + NaN i plus invalid exception and sign of zero/inf not specified", FUNC(csinh) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); check_complex ("csinh (-inf - inf i) == inf + NaN i plus invalid exception and sign of zero/inf not specified", FUNC(csinh) (BUILD_COMPLEX (minus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); check_complex ("csinh (inf + 4.625 i) == -inf - inf i", FUNC(csinh) (BUILD_COMPLEX (plus_infty, 4.625)), BUILD_COMPLEX (minus_infty, minus_infty), 0, 0, 0); check_complex ("csinh (-inf + 4.625 i) == inf - inf i", FUNC(csinh) (BUILD_COMPLEX (minus_infty, 4.625)), BUILD_COMPLEX (plus_infty, minus_infty), 0, 0, 0); check_complex ("csinh (inf - 4.625 i) == -inf + inf i", FUNC(csinh) (BUILD_COMPLEX (plus_infty, -4.625)), BUILD_COMPLEX (minus_infty, plus_infty), 0, 0, 0); check_complex ("csinh (-inf - 4.625 i) == inf + inf i", FUNC(csinh) (BUILD_COMPLEX (minus_infty, -4.625)), BUILD_COMPLEX (plus_infty, plus_infty), 0, 0, 0); check_complex ("csinh (6.75 + inf i) == NaN + NaN i plus invalid exception", FUNC(csinh) (BUILD_COMPLEX (6.75, plus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("csinh (-6.75 + inf i) == NaN + NaN i plus invalid exception", FUNC(csinh) (BUILD_COMPLEX (-6.75, plus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("csinh (6.75 - inf i) == NaN + NaN i plus invalid exception", FUNC(csinh) (BUILD_COMPLEX (6.75, minus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("csinh (-6.75 - inf i) == NaN + NaN i plus invalid exception", FUNC(csinh) (BUILD_COMPLEX (-6.75, minus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("csinh (0.0 + NaN i) == 0.0 + NaN i plus sign of zero/inf not specified", FUNC(csinh) (BUILD_COMPLEX (0.0, nan_value)), BUILD_COMPLEX (0.0, nan_value), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("csinh (-0 + NaN i) == 0.0 + NaN i plus sign of zero/inf not specified", FUNC(csinh) (BUILD_COMPLEX (minus_zero, nan_value)), BUILD_COMPLEX (0.0, nan_value), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("csinh (inf + NaN i) == inf + NaN i plus sign of zero/inf not specified", FUNC(csinh) (BUILD_COMPLEX (plus_infty, nan_value)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("csinh (-inf + NaN i) == inf + NaN i plus sign of zero/inf not specified", FUNC(csinh) (BUILD_COMPLEX (minus_infty, nan_value)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("csinh (9.0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(csinh) (BUILD_COMPLEX (9.0, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("csinh (-9.0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(csinh) (BUILD_COMPLEX (-9.0, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("csinh (NaN + 0.0 i) == NaN + 0.0 i", FUNC(csinh) (BUILD_COMPLEX (nan_value, 0.0)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, 0); check_complex ("csinh (NaN - 0 i) == NaN - 0 i", FUNC(csinh) (BUILD_COMPLEX (nan_value, minus_zero)), BUILD_COMPLEX (nan_value, minus_zero), 0, 0, 0); check_complex ("csinh (NaN + 10.0 i) == NaN + NaN i plus invalid exception allowed", FUNC(csinh) (BUILD_COMPLEX (nan_value, 10.0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("csinh (NaN - 10.0 i) == NaN + NaN i plus invalid exception allowed", FUNC(csinh) (BUILD_COMPLEX (nan_value, -10.0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("csinh (NaN + inf i) == NaN + NaN i plus invalid exception allowed", FUNC(csinh) (BUILD_COMPLEX (nan_value, plus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("csinh (NaN - inf i) == NaN + NaN i plus invalid exception allowed", FUNC(csinh) (BUILD_COMPLEX (nan_value, minus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("csinh (NaN + NaN i) == NaN + NaN i", FUNC(csinh) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); check_complex ("csinh (0.7 + 1.2 i) == 0.27487868678117583582 + 1.1698665727426565139 i", FUNC(csinh) (BUILD_COMPLEX (0.7L, 1.2L)), BUILD_COMPLEX (0.27487868678117583582L, 1.1698665727426565139L), DELTA691, 0, 0); check_complex ("csinh (-2 - 3 i) == 3.5905645899857799520 - 0.5309210862485198052 i", FUNC(csinh) (BUILD_COMPLEX (-2, -3)), BUILD_COMPLEX (3.5905645899857799520L, -0.5309210862485198052L), DELTA692, 0, 0); print_complex_max_error ("csinh", DELTAcsinh, 0); } static void csqrt_test (void) { errno = 0; FUNC(csqrt) (BUILD_COMPLEX (-1, 0)); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_complex ("csqrt (0 + 0 i) == 0.0 + 0.0 i", FUNC(csqrt) (BUILD_COMPLEX (0, 0)), BUILD_COMPLEX (0.0, 0.0), 0, 0, 0); check_complex ("csqrt (0 - 0 i) == 0 - 0 i", FUNC(csqrt) (BUILD_COMPLEX (0, minus_zero)), BUILD_COMPLEX (0, minus_zero), 0, 0, 0); check_complex ("csqrt (-0 + 0 i) == 0.0 + 0.0 i", FUNC(csqrt) (BUILD_COMPLEX (minus_zero, 0)), BUILD_COMPLEX (0.0, 0.0), 0, 0, 0); check_complex ("csqrt (-0 - 0 i) == 0.0 - 0 i", FUNC(csqrt) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (0.0, minus_zero), 0, 0, 0); check_complex ("csqrt (-inf + 0 i) == 0.0 + inf i", FUNC(csqrt) (BUILD_COMPLEX (minus_infty, 0)), BUILD_COMPLEX (0.0, plus_infty), 0, 0, 0); check_complex ("csqrt (-inf + 6 i) == 0.0 + inf i", FUNC(csqrt) (BUILD_COMPLEX (minus_infty, 6)), BUILD_COMPLEX (0.0, plus_infty), 0, 0, 0); check_complex ("csqrt (-inf - 0 i) == 0.0 - inf i", FUNC(csqrt) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (0.0, minus_infty), 0, 0, 0); check_complex ("csqrt (-inf - 6 i) == 0.0 - inf i", FUNC(csqrt) (BUILD_COMPLEX (minus_infty, -6)), BUILD_COMPLEX (0.0, minus_infty), 0, 0, 0); check_complex ("csqrt (inf + 0 i) == inf + 0.0 i", FUNC(csqrt) (BUILD_COMPLEX (plus_infty, 0)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); check_complex ("csqrt (inf + 6 i) == inf + 0.0 i", FUNC(csqrt) (BUILD_COMPLEX (plus_infty, 6)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); check_complex ("csqrt (inf - 0 i) == inf - 0 i", FUNC(csqrt) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); check_complex ("csqrt (inf - 6 i) == inf - 0 i", FUNC(csqrt) (BUILD_COMPLEX (plus_infty, -6)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); check_complex ("csqrt (0 + inf i) == inf + inf i", FUNC(csqrt) (BUILD_COMPLEX (0, plus_infty)), BUILD_COMPLEX (plus_infty, plus_infty), 0, 0, 0); check_complex ("csqrt (4 + inf i) == inf + inf i", FUNC(csqrt) (BUILD_COMPLEX (4, plus_infty)), BUILD_COMPLEX (plus_infty, plus_infty), 0, 0, 0); check_complex ("csqrt (inf + inf i) == inf + inf i", FUNC(csqrt) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, plus_infty), 0, 0, 0); check_complex ("csqrt (-0 + inf i) == inf + inf i", FUNC(csqrt) (BUILD_COMPLEX (minus_zero, plus_infty)), BUILD_COMPLEX (plus_infty, plus_infty), 0, 0, 0); check_complex ("csqrt (-4 + inf i) == inf + inf i", FUNC(csqrt) (BUILD_COMPLEX (-4, plus_infty)), BUILD_COMPLEX (plus_infty, plus_infty), 0, 0, 0); check_complex ("csqrt (-inf + inf i) == inf + inf i", FUNC(csqrt) (BUILD_COMPLEX (minus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, plus_infty), 0, 0, 0); check_complex ("csqrt (0 - inf i) == inf - inf i", FUNC(csqrt) (BUILD_COMPLEX (0, minus_infty)), BUILD_COMPLEX (plus_infty, minus_infty), 0, 0, 0); check_complex ("csqrt (4 - inf i) == inf - inf i", FUNC(csqrt) (BUILD_COMPLEX (4, minus_infty)), BUILD_COMPLEX (plus_infty, minus_infty), 0, 0, 0); check_complex ("csqrt (inf - inf i) == inf - inf i", FUNC(csqrt) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, minus_infty), 0, 0, 0); check_complex ("csqrt (-0 - inf i) == inf - inf i", FUNC(csqrt) (BUILD_COMPLEX (minus_zero, minus_infty)), BUILD_COMPLEX (plus_infty, minus_infty), 0, 0, 0); check_complex ("csqrt (-4 - inf i) == inf - inf i", FUNC(csqrt) (BUILD_COMPLEX (-4, minus_infty)), BUILD_COMPLEX (plus_infty, minus_infty), 0, 0, 0); check_complex ("csqrt (-inf - inf i) == inf - inf i", FUNC(csqrt) (BUILD_COMPLEX (minus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, minus_infty), 0, 0, 0); check_complex ("csqrt (-inf + NaN i) == NaN + inf i plus sign of zero/inf not specified", FUNC(csqrt) (BUILD_COMPLEX (minus_infty, nan_value)), BUILD_COMPLEX (nan_value, plus_infty), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("csqrt (inf + NaN i) == inf + NaN i", FUNC(csqrt) (BUILD_COMPLEX (plus_infty, nan_value)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); check_complex ("csqrt (0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(csqrt) (BUILD_COMPLEX (0, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("csqrt (1 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(csqrt) (BUILD_COMPLEX (1, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("csqrt (-0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(csqrt) (BUILD_COMPLEX (minus_zero, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("csqrt (-1 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(csqrt) (BUILD_COMPLEX (-1, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("csqrt (NaN + 0 i) == NaN + NaN i plus invalid exception allowed", FUNC(csqrt) (BUILD_COMPLEX (nan_value, 0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("csqrt (NaN + 8 i) == NaN + NaN i plus invalid exception allowed", FUNC(csqrt) (BUILD_COMPLEX (nan_value, 8)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("csqrt (NaN - 0 i) == NaN + NaN i plus invalid exception allowed", FUNC(csqrt) (BUILD_COMPLEX (nan_value, minus_zero)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("csqrt (NaN - 8 i) == NaN + NaN i plus invalid exception allowed", FUNC(csqrt) (BUILD_COMPLEX (nan_value, -8)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("csqrt (NaN + NaN i) == NaN + NaN i", FUNC(csqrt) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); check_complex ("csqrt (16.0 - 30.0 i) == 5.0 - 3.0 i", FUNC(csqrt) (BUILD_COMPLEX (16.0, -30.0)), BUILD_COMPLEX (5.0, -3.0), 0, 0, 0); check_complex ("csqrt (-1 + 0 i) == 0.0 + 1.0 i", FUNC(csqrt) (BUILD_COMPLEX (-1, 0)), BUILD_COMPLEX (0.0, 1.0), 0, 0, 0); check_complex ("csqrt (0 + 2 i) == 1.0 + 1.0 i", FUNC(csqrt) (BUILD_COMPLEX (0, 2)), BUILD_COMPLEX (1.0, 1.0), 0, 0, 0); check_complex ("csqrt (119 + 120 i) == 12.0 + 5.0 i", FUNC(csqrt) (BUILD_COMPLEX (119, 120)), BUILD_COMPLEX (12.0, 5.0), 0, 0, 0); check_complex ("csqrt (0.7 + 1.2 i) == 1.022067610030026450706487883081139 + 0.58704531296356521154977678719838035 i", FUNC(csqrt) (BUILD_COMPLEX (0.7L, 1.2L)), BUILD_COMPLEX (1.022067610030026450706487883081139L, 0.58704531296356521154977678719838035L), DELTA732, 0, 0); check_complex ("csqrt (-2 - 3 i) == 0.89597747612983812471573375529004348 - 1.6741492280355400404480393008490519 i", FUNC(csqrt) (BUILD_COMPLEX (-2, -3)), BUILD_COMPLEX (0.89597747612983812471573375529004348L, -1.6741492280355400404480393008490519L), DELTA733, 0, 0); check_complex ("csqrt (-2 + 3 i) == 0.89597747612983812471573375529004348 + 1.6741492280355400404480393008490519 i", FUNC(csqrt) (BUILD_COMPLEX (-2, 3)), BUILD_COMPLEX (0.89597747612983812471573375529004348L, 1.6741492280355400404480393008490519L), DELTA734, 0, 0); print_complex_max_error ("csqrt", DELTAcsqrt, 0); } static void ctan_test (void) { errno = 0; FUNC(ctan) (BUILD_COMPLEX (0.7L, 1.2L)); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_complex ("ctan (0 + 0 i) == 0.0 + 0.0 i", FUNC(ctan) (BUILD_COMPLEX (0, 0)), BUILD_COMPLEX (0.0, 0.0), 0, 0, 0); check_complex ("ctan (0 - 0 i) == 0.0 - 0 i", FUNC(ctan) (BUILD_COMPLEX (0, minus_zero)), BUILD_COMPLEX (0.0, minus_zero), 0, 0, 0); check_complex ("ctan (-0 + 0 i) == -0 + 0.0 i", FUNC(ctan) (BUILD_COMPLEX (minus_zero, 0)), BUILD_COMPLEX (minus_zero, 0.0), 0, 0, 0); check_complex ("ctan (-0 - 0 i) == -0 - 0 i", FUNC(ctan) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (minus_zero, minus_zero), 0, 0, 0); check_complex ("ctan (0 + inf i) == 0.0 + 1.0 i", FUNC(ctan) (BUILD_COMPLEX (0, plus_infty)), BUILD_COMPLEX (0.0, 1.0), 0, 0, 0); check_complex ("ctan (1 + inf i) == 0.0 + 1.0 i", FUNC(ctan) (BUILD_COMPLEX (1, plus_infty)), BUILD_COMPLEX (0.0, 1.0), 0, 0, 0); check_complex ("ctan (-0 + inf i) == -0 + 1.0 i", FUNC(ctan) (BUILD_COMPLEX (minus_zero, plus_infty)), BUILD_COMPLEX (minus_zero, 1.0), 0, 0, 0); check_complex ("ctan (-1 + inf i) == -0 + 1.0 i", FUNC(ctan) (BUILD_COMPLEX (-1, plus_infty)), BUILD_COMPLEX (minus_zero, 1.0), 0, 0, 0); check_complex ("ctan (0 - inf i) == 0.0 - 1.0 i", FUNC(ctan) (BUILD_COMPLEX (0, minus_infty)), BUILD_COMPLEX (0.0, -1.0), 0, 0, 0); check_complex ("ctan (1 - inf i) == 0.0 - 1.0 i", FUNC(ctan) (BUILD_COMPLEX (1, minus_infty)), BUILD_COMPLEX (0.0, -1.0), 0, 0, 0); check_complex ("ctan (-0 - inf i) == -0 - 1.0 i", FUNC(ctan) (BUILD_COMPLEX (minus_zero, minus_infty)), BUILD_COMPLEX (minus_zero, -1.0), 0, 0, 0); check_complex ("ctan (-1 - inf i) == -0 - 1.0 i", FUNC(ctan) (BUILD_COMPLEX (-1, minus_infty)), BUILD_COMPLEX (minus_zero, -1.0), 0, 0, 0); check_complex ("ctan (inf + 0 i) == NaN + NaN i plus invalid exception", FUNC(ctan) (BUILD_COMPLEX (plus_infty, 0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ctan (inf + 2 i) == NaN + NaN i plus invalid exception", FUNC(ctan) (BUILD_COMPLEX (plus_infty, 2)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ctan (-inf + 0 i) == NaN + NaN i plus invalid exception", FUNC(ctan) (BUILD_COMPLEX (minus_infty, 0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ctan (-inf + 2 i) == NaN + NaN i plus invalid exception", FUNC(ctan) (BUILD_COMPLEX (minus_infty, 2)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ctan (inf - 0 i) == NaN + NaN i plus invalid exception", FUNC(ctan) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ctan (inf - 2 i) == NaN + NaN i plus invalid exception", FUNC(ctan) (BUILD_COMPLEX (plus_infty, -2)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ctan (-inf - 0 i) == NaN + NaN i plus invalid exception", FUNC(ctan) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ctan (-inf - 2 i) == NaN + NaN i plus invalid exception", FUNC(ctan) (BUILD_COMPLEX (minus_infty, -2)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ctan (NaN + inf i) == 0.0 + 1.0 i plus sign of zero/inf not specified", FUNC(ctan) (BUILD_COMPLEX (nan_value, plus_infty)), BUILD_COMPLEX (0.0, 1.0), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("ctan (NaN - inf i) == 0.0 - 1.0 i plus sign of zero/inf not specified", FUNC(ctan) (BUILD_COMPLEX (nan_value, minus_infty)), BUILD_COMPLEX (0.0, -1.0), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("ctan (0 + NaN i) == 0.0 + NaN i", FUNC(ctan) (BUILD_COMPLEX (0, nan_value)), BUILD_COMPLEX (0.0, nan_value), 0, 0, 0); check_complex ("ctan (-0 + NaN i) == -0 + NaN i", FUNC(ctan) (BUILD_COMPLEX (minus_zero, nan_value)), BUILD_COMPLEX (minus_zero, nan_value), 0, 0, 0); check_complex ("ctan (0.5 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(ctan) (BUILD_COMPLEX (0.5, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("ctan (-4.5 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(ctan) (BUILD_COMPLEX (-4.5, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("ctan (NaN + 0 i) == NaN + NaN i plus invalid exception allowed", FUNC(ctan) (BUILD_COMPLEX (nan_value, 0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("ctan (NaN + 5 i) == NaN + NaN i plus invalid exception allowed", FUNC(ctan) (BUILD_COMPLEX (nan_value, 5)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("ctan (NaN - 0 i) == NaN + NaN i plus invalid exception allowed", FUNC(ctan) (BUILD_COMPLEX (nan_value, minus_zero)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("ctan (NaN - 0.25 i) == NaN + NaN i plus invalid exception allowed", FUNC(ctan) (BUILD_COMPLEX (nan_value, -0.25)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("ctan (NaN + NaN i) == NaN + NaN i", FUNC(ctan) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); check_complex ("ctan (0.7 + 1.2 i) == 0.1720734197630349001 + 0.9544807059989405538 i", FUNC(ctan) (BUILD_COMPLEX (0.7L, 1.2L)), BUILD_COMPLEX (0.1720734197630349001L, 0.9544807059989405538L), DELTA766, 0, 0); check_complex ("ctan (-2 - 3 i) == 0.0037640256415042482 - 1.0032386273536098014 i", FUNC(ctan) (BUILD_COMPLEX (-2, -3)), BUILD_COMPLEX (0.0037640256415042482L, -1.0032386273536098014L), DELTA767, 0, 0); print_complex_max_error ("ctan", DELTActan, 0); } static void ctanh_test (void) { errno = 0; FUNC(ctanh) (BUILD_COMPLEX (0, 0)); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_complex ("ctanh (0 + 0 i) == 0.0 + 0.0 i", FUNC(ctanh) (BUILD_COMPLEX (0, 0)), BUILD_COMPLEX (0.0, 0.0), 0, 0, 0); check_complex ("ctanh (0 - 0 i) == 0.0 - 0 i", FUNC(ctanh) (BUILD_COMPLEX (0, minus_zero)), BUILD_COMPLEX (0.0, minus_zero), 0, 0, 0); check_complex ("ctanh (-0 + 0 i) == -0 + 0.0 i", FUNC(ctanh) (BUILD_COMPLEX (minus_zero, 0)), BUILD_COMPLEX (minus_zero, 0.0), 0, 0, 0); check_complex ("ctanh (-0 - 0 i) == -0 - 0 i", FUNC(ctanh) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (minus_zero, minus_zero), 0, 0, 0); check_complex ("ctanh (inf + 0 i) == 1.0 + 0.0 i", FUNC(ctanh) (BUILD_COMPLEX (plus_infty, 0)), BUILD_COMPLEX (1.0, 0.0), 0, 0, 0); check_complex ("ctanh (inf + 1 i) == 1.0 + 0.0 i", FUNC(ctanh) (BUILD_COMPLEX (plus_infty, 1)), BUILD_COMPLEX (1.0, 0.0), 0, 0, 0); check_complex ("ctanh (inf - 0 i) == 1.0 - 0 i", FUNC(ctanh) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (1.0, minus_zero), 0, 0, 0); check_complex ("ctanh (inf - 1 i) == 1.0 - 0 i", FUNC(ctanh) (BUILD_COMPLEX (plus_infty, -1)), BUILD_COMPLEX (1.0, minus_zero), 0, 0, 0); check_complex ("ctanh (-inf + 0 i) == -1.0 + 0.0 i", FUNC(ctanh) (BUILD_COMPLEX (minus_infty, 0)), BUILD_COMPLEX (-1.0, 0.0), 0, 0, 0); check_complex ("ctanh (-inf + 1 i) == -1.0 + 0.0 i", FUNC(ctanh) (BUILD_COMPLEX (minus_infty, 1)), BUILD_COMPLEX (-1.0, 0.0), 0, 0, 0); check_complex ("ctanh (-inf - 0 i) == -1.0 - 0 i", FUNC(ctanh) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (-1.0, minus_zero), 0, 0, 0); check_complex ("ctanh (-inf - 1 i) == -1.0 - 0 i", FUNC(ctanh) (BUILD_COMPLEX (minus_infty, -1)), BUILD_COMPLEX (-1.0, minus_zero), 0, 0, 0); check_complex ("ctanh (0 + inf i) == NaN + NaN i plus invalid exception", FUNC(ctanh) (BUILD_COMPLEX (0, plus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ctanh (2 + inf i) == NaN + NaN i plus invalid exception", FUNC(ctanh) (BUILD_COMPLEX (2, plus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ctanh (0 - inf i) == NaN + NaN i plus invalid exception", FUNC(ctanh) (BUILD_COMPLEX (0, minus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ctanh (2 - inf i) == NaN + NaN i plus invalid exception", FUNC(ctanh) (BUILD_COMPLEX (2, minus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ctanh (-0 + inf i) == NaN + NaN i plus invalid exception", FUNC(ctanh) (BUILD_COMPLEX (minus_zero, plus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ctanh (-2 + inf i) == NaN + NaN i plus invalid exception", FUNC(ctanh) (BUILD_COMPLEX (-2, plus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ctanh (-0 - inf i) == NaN + NaN i plus invalid exception", FUNC(ctanh) (BUILD_COMPLEX (minus_zero, minus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ctanh (-2 - inf i) == NaN + NaN i plus invalid exception", FUNC(ctanh) (BUILD_COMPLEX (-2, minus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); check_complex ("ctanh (inf + NaN i) == 1.0 + 0.0 i plus sign of zero/inf not specified", FUNC(ctanh) (BUILD_COMPLEX (plus_infty, nan_value)), BUILD_COMPLEX (1.0, 0.0), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("ctanh (-inf + NaN i) == -1.0 + 0.0 i plus sign of zero/inf not specified", FUNC(ctanh) (BUILD_COMPLEX (minus_infty, nan_value)), BUILD_COMPLEX (-1.0, 0.0), 0, 0, IGNORE_ZERO_INF_SIGN); check_complex ("ctanh (NaN + 0 i) == NaN + 0.0 i", FUNC(ctanh) (BUILD_COMPLEX (nan_value, 0)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, 0); check_complex ("ctanh (NaN - 0 i) == NaN - 0 i", FUNC(ctanh) (BUILD_COMPLEX (nan_value, minus_zero)), BUILD_COMPLEX (nan_value, minus_zero), 0, 0, 0); check_complex ("ctanh (NaN + 0.5 i) == NaN + NaN i plus invalid exception allowed", FUNC(ctanh) (BUILD_COMPLEX (nan_value, 0.5)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("ctanh (NaN - 4.5 i) == NaN + NaN i plus invalid exception allowed", FUNC(ctanh) (BUILD_COMPLEX (nan_value, -4.5)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("ctanh (0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(ctanh) (BUILD_COMPLEX (0, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("ctanh (5 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(ctanh) (BUILD_COMPLEX (5, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("ctanh (-0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(ctanh) (BUILD_COMPLEX (minus_zero, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("ctanh (-0.25 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(ctanh) (BUILD_COMPLEX (-0.25, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); check_complex ("ctanh (NaN + NaN i) == NaN + NaN i", FUNC(ctanh) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); check_complex ("ctanh (0 + pi/4 i) == 0.0 + 1.0 i", FUNC(ctanh) (BUILD_COMPLEX (0, M_PI_4l)), BUILD_COMPLEX (0.0, 1.0), DELTA799, 0, 0); check_complex ("ctanh (0.7 + 1.2 i) == 1.3472197399061191630 + 0.4778641038326365540 i", FUNC(ctanh) (BUILD_COMPLEX (0.7L, 1.2L)), BUILD_COMPLEX (1.3472197399061191630L, 0.4778641038326365540L), DELTA800, 0, 0); check_complex ("ctanh (-2 - 3 i) == -0.9653858790221331242 + 0.0098843750383224937 i", FUNC(ctanh) (BUILD_COMPLEX (-2, -3)), BUILD_COMPLEX (-0.9653858790221331242L, 0.0098843750383224937L), DELTA801, 0, 0); print_complex_max_error ("ctanh", DELTActanh, 0); } #endif static void erf_test (void) { errno = 0; FUNC(erf) (0); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_float ("erf (0) == 0", FUNC(erf) (0), 0, 0, 0, 0); check_float ("erf (-0) == -0", FUNC(erf) (minus_zero), minus_zero, 0, 0, 0); check_float ("erf (inf) == 1", FUNC(erf) (plus_infty), 1, 0, 0, 0); check_float ("erf (-inf) == -1", FUNC(erf) (minus_infty), -1, 0, 0, 0); check_float ("erf (NaN) == NaN", FUNC(erf) (nan_value), nan_value, 0, 0, 0); check_float ("erf (0.7) == 0.67780119383741847297", FUNC(erf) (0.7L), 0.67780119383741847297L, 0, 0, 0); check_float ("erf (1.2) == 0.91031397822963538024", FUNC(erf) (1.2L), 0.91031397822963538024L, 0, 0, 0); check_float ("erf (2.0) == 0.99532226501895273416", FUNC(erf) (2.0), 0.99532226501895273416L, 0, 0, 0); check_float ("erf (4.1) == 0.99999999329997234592", FUNC(erf) (4.1L), 0.99999999329997234592L, 0, 0, 0); check_float ("erf (27) == 1.0", FUNC(erf) (27), 1.0L, 0, 0, 0); print_max_error ("erf", 0, 0); } static void erfc_test (void) { errno = 0; FUNC(erfc) (0); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_float ("erfc (inf) == 0.0", FUNC(erfc) (plus_infty), 0.0, 0, 0, 0); check_float ("erfc (-inf) == 2.0", FUNC(erfc) (minus_infty), 2.0, 0, 0, 0); check_float ("erfc (0.0) == 1.0", FUNC(erfc) (0.0), 1.0, 0, 0, 0); check_float ("erfc (-0) == 1.0", FUNC(erfc) (minus_zero), 1.0, 0, 0, 0); check_float ("erfc (NaN) == NaN", FUNC(erfc) (nan_value), nan_value, 0, 0, 0); check_float ("erfc (0.7) == 0.32219880616258152702", FUNC(erfc) (0.7L), 0.32219880616258152702L, DELTA817, 0, 0); check_float ("erfc (1.2) == 0.089686021770364619762", FUNC(erfc) (1.2L), 0.089686021770364619762L, DELTA818, 0, 0); check_float ("erfc (2.0) == 0.0046777349810472658379", FUNC(erfc) (2.0), 0.0046777349810472658379L, DELTA819, 0, 0); check_float ("erfc (4.1) == 0.67000276540848983727e-8", FUNC(erfc) (4.1L), 0.67000276540848983727e-8L, DELTA820, 0, 0); check_float ("erfc (9) == 0.41370317465138102381e-36", FUNC(erfc) (9), 0.41370317465138102381e-36L, DELTA821, 0, 0); print_max_error ("erfc", DELTAerfc, 0); } static void exp_test (void) { errno = 0; FUNC(exp) (0); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_float ("exp (0) == 1", FUNC(exp) (0), 1, 0, 0, 0); check_float ("exp (-0) == 1", FUNC(exp) (minus_zero), 1, 0, 0, 0); #ifndef TEST_INLINE check_float ("exp (inf) == inf", FUNC(exp) (plus_infty), plus_infty, 0, 0, 0); check_float ("exp (-inf) == 0", FUNC(exp) (minus_infty), 0, 0, 0, 0); #endif check_float ("exp (NaN) == NaN", FUNC(exp) (nan_value), nan_value, 0, 0, 0); check_float ("exp (1) == e", FUNC(exp) (1), M_El, 0, 0, 0); check_float ("exp (2) == e^2", FUNC(exp) (2), M_E2l, 0, 0, 0); check_float ("exp (3) == e^3", FUNC(exp) (3), M_E3l, 0, 0, 0); check_float ("exp (0.7) == 2.0137527074704765216", FUNC(exp) (0.7L), 2.0137527074704765216L, DELTA830, 0, 0); check_float ("exp (50.0) == 5184705528587072464087.45332293348538", FUNC(exp) (50.0L), 5184705528587072464087.45332293348538L, DELTA831, 0, 0); #ifdef TEST_LDOUBLE /* The result can only be represented in long double. */ check_float ("exp (1000.0) == 0.197007111401704699388887935224332313e435", FUNC(exp) (1000.0L), 0.197007111401704699388887935224332313e435L, DELTA832, 0, 0); #endif print_max_error ("exp", DELTAexp, 0); } #if 0 /* XXX scp XXX */ static void exp10_test (void) { errno = 0; FUNC(exp10) (0); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_float ("exp10 (0) == 1", FUNC(exp10) (0), 1, 0, 0, 0); check_float ("exp10 (-0) == 1", FUNC(exp10) (minus_zero), 1, 0, 0, 0); check_float ("exp10 (inf) == inf", FUNC(exp10) (plus_infty), plus_infty, 0, 0, 0); check_float ("exp10 (-inf) == 0", FUNC(exp10) (minus_infty), 0, 0, 0, 0); check_float ("exp10 (NaN) == NaN", FUNC(exp10) (nan_value), nan_value, 0, 0, 0); check_float ("exp10 (3) == 1000", FUNC(exp10) (3), 1000, DELTA838, 0, 0); check_float ("exp10 (-1) == 0.1", FUNC(exp10) (-1), 0.1L, DELTA839, 0, 0); check_float ("exp10 (1e6) == inf", FUNC(exp10) (1e6), plus_infty, 0, 0, 0); check_float ("exp10 (-1e6) == 0", FUNC(exp10) (-1e6), 0, 0, 0, 0); check_float ("exp10 (0.7) == 5.0118723362727228500155418688494574", FUNC(exp10) (0.7L), 5.0118723362727228500155418688494574L, DELTA842, 0, 0); print_max_error ("exp10", DELTAexp10, 0); } #endif static void exp2_test (void) { errno = 0; FUNC(exp2) (0); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_float ("exp2 (0) == 1", FUNC(exp2) (0), 1, 0, 0, 0); check_float ("exp2 (-0) == 1", FUNC(exp2) (minus_zero), 1, 0, 0, 0); check_float ("exp2 (inf) == inf", FUNC(exp2) (plus_infty), plus_infty, 0, 0, 0); check_float ("exp2 (-inf) == 0", FUNC(exp2) (minus_infty), 0, 0, 0, 0); check_float ("exp2 (NaN) == NaN", FUNC(exp2) (nan_value), nan_value, 0, 0, 0); check_float ("exp2 (10) == 1024", FUNC(exp2) (10), 1024, 0, 0, 0); check_float ("exp2 (-1) == 0.5", FUNC(exp2) (-1), 0.5, 0, 0, 0); check_float ("exp2 (1e6) == inf", FUNC(exp2) (1e6), plus_infty, 0, 0, 0); check_float ("exp2 (-1e6) == 0", FUNC(exp2) (-1e6), 0, 0, 0, 0); check_float ("exp2 (0.7) == 1.6245047927124710452", FUNC(exp2) (0.7L), 1.6245047927124710452L, DELTA852, 0, 0); print_max_error ("exp2", DELTAexp2, 0); } static void expm1_test (void) { errno = 0; FUNC(expm1) (0); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_float ("expm1 (0) == 0", FUNC(expm1) (0), 0, 0, 0, 0); check_float ("expm1 (-0) == -0", FUNC(expm1) (minus_zero), minus_zero, 0, 0, 0); #ifndef TEST_INLINE check_float ("expm1 (inf) == inf", FUNC(expm1) (plus_infty), plus_infty, 0, 0, 0); check_float ("expm1 (-inf) == -1", FUNC(expm1) (minus_infty), -1, 0, 0, 0); #endif check_float ("expm1 (NaN) == NaN", FUNC(expm1) (nan_value), nan_value, 0, 0, 0); check_float ("expm1 (1) == M_El - 1.0", FUNC(expm1) (1), M_El - 1.0, 0, 0, 0); check_float ("expm1 (0.7) == 1.0137527074704765216", FUNC(expm1) (0.7L), 1.0137527074704765216L, DELTA859, 0, 0); print_max_error ("expm1", DELTAexpm1, 0); } static void fabs_test (void) { init_max_error (); check_float ("fabs (0) == 0", FUNC(fabs) ((FLOAT)0.0), 0, 0, 0, 0); check_float ("fabs (-0) == 0", FUNC(fabs) (minus_zero), 0, 0, 0, 0); check_float ("fabs (inf) == inf", FUNC(fabs) (plus_infty), plus_infty, 0, 0, 0); check_float ("fabs (-inf) == inf", FUNC(fabs) (minus_infty), plus_infty, 0, 0, 0); check_float ("fabs (NaN) == NaN", FUNC(fabs) (nan_value), nan_value, 0, 0, 0); check_float ("fabs (38.0) == 38.0", FUNC(fabs) ((FLOAT)38.0), 38.0, 0, 0, 0); check_float ("fabs (-e) == e", FUNC(fabs) ((FLOAT)-M_El), M_El, 0, 0, 0); print_max_error ("fabs", 0, 0); } static void fdim_test (void) { init_max_error (); check_float ("fdim (0, 0) == 0", FUNC(fdim) (0, 0), 0, 0, 0, 0); check_float ("fdim (9, 0) == 9", FUNC(fdim) (9, 0), 9, 0, 0, 0); check_float ("fdim (0, 9) == 0", FUNC(fdim) (0, 9), 0, 0, 0, 0); check_float ("fdim (-9, 0) == 0", FUNC(fdim) (-9, 0), 0, 0, 0, 0); check_float ("fdim (0, -9) == 9", FUNC(fdim) (0, -9), 9, 0, 0, 0); check_float ("fdim (inf, 9) == inf", FUNC(fdim) (plus_infty, 9), plus_infty, 0, 0, 0); check_float ("fdim (inf, -9) == inf", FUNC(fdim) (plus_infty, -9), plus_infty, 0, 0, 0); check_float ("fdim (-inf, 9) == 0", FUNC(fdim) (minus_infty, 9), 0, 0, 0, 0); check_float ("fdim (-inf, -9) == 0", FUNC(fdim) (minus_infty, -9), 0, 0, 0, 0); check_float ("fdim (9, -inf) == inf", FUNC(fdim) (9, minus_infty), plus_infty, 0, 0, 0); check_float ("fdim (-9, -inf) == inf", FUNC(fdim) (-9, minus_infty), plus_infty, 0, 0, 0); check_float ("fdim (9, inf) == 0", FUNC(fdim) (9, plus_infty), 0, 0, 0, 0); check_float ("fdim (-9, inf) == 0", FUNC(fdim) (-9, plus_infty), 0, 0, 0, 0); check_float ("fdim (0, NaN) == NaN", FUNC(fdim) (0, nan_value), nan_value, 0, 0, 0); check_float ("fdim (9, NaN) == NaN", FUNC(fdim) (9, nan_value), nan_value, 0, 0, 0); check_float ("fdim (-9, NaN) == NaN", FUNC(fdim) (-9, nan_value), nan_value, 0, 0, 0); check_float ("fdim (NaN, 9) == NaN", FUNC(fdim) (nan_value, 9), nan_value, 0, 0, 0); check_float ("fdim (NaN, -9) == NaN", FUNC(fdim) (nan_value, -9), nan_value, 0, 0, 0); check_float ("fdim (inf, NaN) == NaN", FUNC(fdim) (plus_infty, nan_value), nan_value, 0, 0, 0); check_float ("fdim (-inf, NaN) == NaN", FUNC(fdim) (minus_infty, nan_value), nan_value, 0, 0, 0); check_float ("fdim (NaN, inf) == NaN", FUNC(fdim) (nan_value, plus_infty), nan_value, 0, 0, 0); check_float ("fdim (NaN, -inf) == NaN", FUNC(fdim) (nan_value, minus_infty), nan_value, 0, 0, 0); check_float ("fdim (NaN, NaN) == NaN", FUNC(fdim) (nan_value, nan_value), nan_value, 0, 0, 0); print_max_error ("fdim", 0, 0); } static void floor_test (void) { init_max_error (); check_float ("floor (0.0) == 0.0", FUNC(floor) (0.0), 0.0, 0, 0, 0); check_float ("floor (-0) == -0", FUNC(floor) (minus_zero), minus_zero, 0, 0, 0); check_float ("floor (inf) == inf", FUNC(floor) (plus_infty), plus_infty, 0, 0, 0); check_float ("floor (-inf) == -inf", FUNC(floor) (minus_infty), minus_infty, 0, 0, 0); check_float ("floor (NaN) == NaN", FUNC(floor) (nan_value), nan_value, 0, 0, 0); check_float ("floor (pi) == 3.0", FUNC(floor) (M_PIl), 3.0, 0, 0, 0); check_float ("floor (-pi) == -4.0", FUNC(floor) (-M_PIl), -4.0, 0, 0, 0); print_max_error ("floor", 0, 0); } static void fma_test (void) { init_max_error (); check_float ("fma (1.0, 2.0, 3.0) == 5.0", FUNC(fma) (1.0, 2.0, 3.0), 5.0, 0, 0, 0); check_float ("fma (NaN, 2.0, 3.0) == NaN", FUNC(fma) (nan_value, 2.0, 3.0), nan_value, 0, 0, 0); check_float ("fma (1.0, NaN, 3.0) == NaN", FUNC(fma) (1.0, nan_value, 3.0), nan_value, 0, 0, 0); check_float ("fma (1.0, 2.0, NaN) == NaN plus invalid exception allowed", FUNC(fma) (1.0, 2.0, nan_value), nan_value, 0, 0, INVALID_EXCEPTION_OK); check_float ("fma (inf, 0.0, NaN) == NaN plus invalid exception allowed", FUNC(fma) (plus_infty, 0.0, nan_value), nan_value, 0, 0, INVALID_EXCEPTION_OK); check_float ("fma (-inf, 0.0, NaN) == NaN plus invalid exception allowed", FUNC(fma) (minus_infty, 0.0, nan_value), nan_value, 0, 0, INVALID_EXCEPTION_OK); check_float ("fma (0.0, inf, NaN) == NaN plus invalid exception allowed", FUNC(fma) (0.0, plus_infty, nan_value), nan_value, 0, 0, INVALID_EXCEPTION_OK); check_float ("fma (0.0, -inf, NaN) == NaN plus invalid exception allowed", FUNC(fma) (0.0, minus_infty, nan_value), nan_value, 0, 0, INVALID_EXCEPTION_OK); check_float ("fma (inf, 0.0, 1.0) == NaN plus invalid exception", FUNC(fma) (plus_infty, 0.0, 1.0), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("fma (-inf, 0.0, 1.0) == NaN plus invalid exception", FUNC(fma) (minus_infty, 0.0, 1.0), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("fma (0.0, inf, 1.0) == NaN plus invalid exception", FUNC(fma) (0.0, plus_infty, 1.0), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("fma (0.0, -inf, 1.0) == NaN plus invalid exception", FUNC(fma) (0.0, minus_infty, 1.0), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("fma (inf, inf, -inf) == NaN plus invalid exception", FUNC(fma) (plus_infty, plus_infty, minus_infty), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("fma (-inf, inf, inf) == NaN plus invalid exception", FUNC(fma) (minus_infty, plus_infty, plus_infty), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("fma (inf, -inf, inf) == NaN plus invalid exception", FUNC(fma) (plus_infty, minus_infty, plus_infty), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("fma (-inf, -inf, -inf) == NaN plus invalid exception", FUNC(fma) (minus_infty, minus_infty, minus_infty), nan_value, 0, 0, INVALID_EXCEPTION); print_max_error ("fma", 0, 0); } static void fmax_test (void) { init_max_error (); check_float ("fmax (0, 0) == 0", FUNC(fmax) (0, 0), 0, 0, 0, 0); check_float ("fmax (-0, -0) == -0", FUNC(fmax) (minus_zero, minus_zero), minus_zero, 0, 0, 0); check_float ("fmax (9, 0) == 9", FUNC(fmax) (9, 0), 9, 0, 0, 0); check_float ("fmax (0, 9) == 9", FUNC(fmax) (0, 9), 9, 0, 0, 0); check_float ("fmax (-9, 0) == 0", FUNC(fmax) (-9, 0), 0, 0, 0, 0); check_float ("fmax (0, -9) == 0", FUNC(fmax) (0, -9), 0, 0, 0, 0); check_float ("fmax (inf, 9) == inf", FUNC(fmax) (plus_infty, 9), plus_infty, 0, 0, 0); check_float ("fmax (0, inf) == inf", FUNC(fmax) (0, plus_infty), plus_infty, 0, 0, 0); check_float ("fmax (-9, inf) == inf", FUNC(fmax) (-9, plus_infty), plus_infty, 0, 0, 0); check_float ("fmax (inf, -9) == inf", FUNC(fmax) (plus_infty, -9), plus_infty, 0, 0, 0); check_float ("fmax (-inf, 9) == 9", FUNC(fmax) (minus_infty, 9), 9, 0, 0, 0); check_float ("fmax (-inf, -9) == -9", FUNC(fmax) (minus_infty, -9), -9, 0, 0, 0); check_float ("fmax (9, -inf) == 9", FUNC(fmax) (9, minus_infty), 9, 0, 0, 0); check_float ("fmax (-9, -inf) == -9", FUNC(fmax) (-9, minus_infty), -9, 0, 0, 0); check_float ("fmax (0, NaN) == 0", FUNC(fmax) (0, nan_value), 0, 0, 0, 0); check_float ("fmax (9, NaN) == 9", FUNC(fmax) (9, nan_value), 9, 0, 0, 0); check_float ("fmax (-9, NaN) == -9", FUNC(fmax) (-9, nan_value), -9, 0, 0, 0); check_float ("fmax (NaN, 0) == 0", FUNC(fmax) (nan_value, 0), 0, 0, 0, 0); check_float ("fmax (NaN, 9) == 9", FUNC(fmax) (nan_value, 9), 9, 0, 0, 0); check_float ("fmax (NaN, -9) == -9", FUNC(fmax) (nan_value, -9), -9, 0, 0, 0); check_float ("fmax (inf, NaN) == inf", FUNC(fmax) (plus_infty, nan_value), plus_infty, 0, 0, 0); check_float ("fmax (-inf, NaN) == -inf", FUNC(fmax) (minus_infty, nan_value), minus_infty, 0, 0, 0); check_float ("fmax (NaN, inf) == inf", FUNC(fmax) (nan_value, plus_infty), plus_infty, 0, 0, 0); check_float ("fmax (NaN, -inf) == -inf", FUNC(fmax) (nan_value, minus_infty), minus_infty, 0, 0, 0); check_float ("fmax (NaN, NaN) == NaN", FUNC(fmax) (nan_value, nan_value), nan_value, 0, 0, 0); print_max_error ("fmax", 0, 0); } static void fmin_test (void) { init_max_error (); check_float ("fmin (0, 0) == 0", FUNC(fmin) (0, 0), 0, 0, 0, 0); check_float ("fmin (-0, -0) == -0", FUNC(fmin) (minus_zero, minus_zero), minus_zero, 0, 0, 0); check_float ("fmin (9, 0) == 0", FUNC(fmin) (9, 0), 0, 0, 0, 0); check_float ("fmin (0, 9) == 0", FUNC(fmin) (0, 9), 0, 0, 0, 0); check_float ("fmin (-9, 0) == -9", FUNC(fmin) (-9, 0), -9, 0, 0, 0); check_float ("fmin (0, -9) == -9", FUNC(fmin) (0, -9), -9, 0, 0, 0); check_float ("fmin (inf, 9) == 9", FUNC(fmin) (plus_infty, 9), 9, 0, 0, 0); check_float ("fmin (9, inf) == 9", FUNC(fmin) (9, plus_infty), 9, 0, 0, 0); check_float ("fmin (inf, -9) == -9", FUNC(fmin) (plus_infty, -9), -9, 0, 0, 0); check_float ("fmin (-9, inf) == -9", FUNC(fmin) (-9, plus_infty), -9, 0, 0, 0); check_float ("fmin (-inf, 9) == -inf", FUNC(fmin) (minus_infty, 9), minus_infty, 0, 0, 0); check_float ("fmin (-inf, -9) == -inf", FUNC(fmin) (minus_infty, -9), minus_infty, 0, 0, 0); check_float ("fmin (9, -inf) == -inf", FUNC(fmin) (9, minus_infty), minus_infty, 0, 0, 0); check_float ("fmin (-9, -inf) == -inf", FUNC(fmin) (-9, minus_infty), minus_infty, 0, 0, 0); check_float ("fmin (0, NaN) == 0", FUNC(fmin) (0, nan_value), 0, 0, 0, 0); check_float ("fmin (9, NaN) == 9", FUNC(fmin) (9, nan_value), 9, 0, 0, 0); check_float ("fmin (-9, NaN) == -9", FUNC(fmin) (-9, nan_value), -9, 0, 0, 0); check_float ("fmin (NaN, 0) == 0", FUNC(fmin) (nan_value, 0), 0, 0, 0, 0); check_float ("fmin (NaN, 9) == 9", FUNC(fmin) (nan_value, 9), 9, 0, 0, 0); check_float ("fmin (NaN, -9) == -9", FUNC(fmin) (nan_value, -9), -9, 0, 0, 0); check_float ("fmin (inf, NaN) == inf", FUNC(fmin) (plus_infty, nan_value), plus_infty, 0, 0, 0); check_float ("fmin (-inf, NaN) == -inf", FUNC(fmin) (minus_infty, nan_value), minus_infty, 0, 0, 0); check_float ("fmin (NaN, inf) == inf", FUNC(fmin) (nan_value, plus_infty), plus_infty, 0, 0, 0); check_float ("fmin (NaN, -inf) == -inf", FUNC(fmin) (nan_value, minus_infty), minus_infty, 0, 0, 0); check_float ("fmin (NaN, NaN) == NaN", FUNC(fmin) (nan_value, nan_value), nan_value, 0, 0, 0); print_max_error ("fmin", 0, 0); } static void fmod_test (void) { errno = 0; FUNC(fmod) (6.5, 2.3L); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); /* fmod (+0, y) == +0 for y != 0. */ check_float ("fmod (0, 3) == 0", FUNC(fmod) (0, 3), 0, 0, 0, 0); /* fmod (-0, y) == -0 for y != 0. */ check_float ("fmod (-0, 3) == -0", FUNC(fmod) (minus_zero, 3), minus_zero, 0, 0, 0); /* fmod (+inf, y) == NaN plus invalid exception. */ check_float ("fmod (inf, 3) == NaN plus invalid exception", FUNC(fmod) (plus_infty, 3), nan_value, 0, 0, INVALID_EXCEPTION); /* fmod (-inf, y) == NaN plus invalid exception. */ check_float ("fmod (-inf, 3) == NaN plus invalid exception", FUNC(fmod) (minus_infty, 3), nan_value, 0, 0, INVALID_EXCEPTION); /* fmod (x, +0) == NaN plus invalid exception. */ check_float ("fmod (3, 0) == NaN plus invalid exception", FUNC(fmod) (3, 0), nan_value, 0, 0, INVALID_EXCEPTION); /* fmod (x, -0) == NaN plus invalid exception. */ check_float ("fmod (3, -0) == NaN plus invalid exception", FUNC(fmod) (3, minus_zero), nan_value, 0, 0, INVALID_EXCEPTION); /* fmod (x, +inf) == x for x not infinite. */ check_float ("fmod (3.0, inf) == 3.0", FUNC(fmod) (3.0, plus_infty), 3.0, 0, 0, 0); /* fmod (x, -inf) == x for x not infinite. */ check_float ("fmod (3.0, -inf) == 3.0", FUNC(fmod) (3.0, minus_infty), 3.0, 0, 0, 0); check_float ("fmod (NaN, NaN) == NaN", FUNC(fmod) (nan_value, nan_value), nan_value, 0, 0, 0); check_float ("fmod (6.5, 2.3) == 1.9", FUNC(fmod) (6.5, 2.3L), 1.9L, DELTA972, 0, 0); check_float ("fmod (-6.5, 2.3) == -1.9", FUNC(fmod) (-6.5, 2.3L), -1.9L, DELTA973, 0, 0); check_float ("fmod (6.5, -2.3) == 1.9", FUNC(fmod) (6.5, -2.3L), 1.9L, DELTA974, 0, 0); check_float ("fmod (-6.5, -2.3) == -1.9", FUNC(fmod) (-6.5, -2.3L), -1.9L, DELTA975, 0, 0); print_max_error ("fmod", DELTAfmod, 0); } static void fpclassify_test (void) { init_max_error (); check_int ("fpclassify (NaN) == FP_NAN", fpclassify (nan_value), FP_NAN, 0, 0, 0); check_int ("fpclassify (inf) == FP_INFINITE", fpclassify (plus_infty), FP_INFINITE, 0, 0, 0); check_int ("fpclassify (-inf) == FP_INFINITE", fpclassify (minus_infty), FP_INFINITE, 0, 0, 0); check_int ("fpclassify (+0) == FP_ZERO", fpclassify (plus_zero), FP_ZERO, 0, 0, 0); check_int ("fpclassify (-0) == FP_ZERO", fpclassify (minus_zero), FP_ZERO, 0, 0, 0); check_int ("fpclassify (1000) == FP_NORMAL", fpclassify (1000.0), FP_NORMAL, 0, 0, 0); print_max_error ("fpclassify", 0, 0); } static void frexp_test (void) { int x; init_max_error (); check_float ("frexp (inf, &x) == inf", FUNC(frexp) (plus_infty, &x), plus_infty, 0, 0, 0); check_float ("frexp (-inf, &x) == -inf", FUNC(frexp) (minus_infty, &x), minus_infty, 0, 0, 0); check_float ("frexp (NaN, &x) == NaN", FUNC(frexp) (nan_value, &x), nan_value, 0, 0, 0); check_float ("frexp (0.0, &x) == 0.0", FUNC(frexp) (0.0, &x), 0.0, 0, 0, 0); check_int ("frexp (0.0, &x) sets x to 0.0", x, 0.0, 0, 0, 0); check_float ("frexp (-0, &x) == -0", FUNC(frexp) (minus_zero, &x), minus_zero, 0, 0, 0); check_int ("frexp (-0, &x) sets x to 0.0", x, 0.0, 0, 0, 0); check_float ("frexp (12.8, &x) == 0.8", FUNC(frexp) (12.8L, &x), 0.8L, 0, 0, 0); check_int ("frexp (12.8, &x) sets x to 4", x, 4, 0, 0, 0); check_float ("frexp (-27.34, &x) == -0.854375", FUNC(frexp) (-27.34L, &x), -0.854375L, 0, 0, 0); check_int ("frexp (-27.34, &x) sets x to 5", x, 5, 0, 0, 0); print_max_error ("frexp", 0, 0); } #define gamma lgamma /* XXX scp XXX */ #define gammaf lgammaf /* XXX scp XXX */ static void gamma_test (void) { errno = 0; FUNC(gamma) (1); if (errno == ENOSYS) /* Function not implemented. */ return; feclearexcept (FE_ALL_EXCEPT); init_max_error (); signgam = 0; check_float ("gamma (inf) == inf", FUNC(gamma) (plus_infty), plus_infty, 0, 0, 0); signgam = 0; check_float ("gamma (0) == inf plus division by zero exception", FUNC(gamma) (0), plus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); signgam = 0; check_float ("gamma (-3) == inf plus division by zero exception", FUNC(gamma) (-3), plus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); signgam = 0; check_float ("gamma (-inf) == inf", FUNC(gamma) (minus_infty), plus_infty, 0, 0, 0); signgam = 0; check_float ("gamma (NaN) == NaN", FUNC(gamma) (nan_value), nan_value, 0, 0, 0); signgam = 0; check_float ("gamma (1) == 0", FUNC(gamma) (1), 0, 0, 0, 0); check_int ("gamma (1) sets signgam to 1", signgam, 1, 0, 0, 0); signgam = 0; check_float ("gamma (3) == M_LN2l", FUNC(gamma) (3), M_LN2l, 0, 0, 0); check_int ("gamma (3) sets signgam to 1", signgam, 1, 0, 0, 0); signgam = 0; check_float ("gamma (0.5) == log(sqrt(pi))", FUNC(gamma) (0.5), M_LOG_SQRT_PIl, 0, 0, 0); check_int ("gamma (0.5) sets signgam to 1", signgam, 1, 0, 0, 0); signgam = 0; check_float ("gamma (-0.5) == log(2*sqrt(pi))", FUNC(gamma) (-0.5), M_LOG_2_SQRT_PIl, DELTA1004, 0, 0); check_int ("gamma (-0.5) sets signgam to -1", signgam, -1, 0, 0, 0); print_max_error ("gamma", DELTAgamma, 0); } #undef gamma /* XXX scp XXX */ #undef gammaf /* XXX scp XXX */ static void hypot_test (void) { errno = 0; FUNC(hypot) (0.7L, 12.4L); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_float ("hypot (inf, 1) == inf plus sign of zero/inf not specified", FUNC(hypot) (plus_infty, 1), plus_infty, 0, 0, IGNORE_ZERO_INF_SIGN); check_float ("hypot (-inf, 1) == inf plus sign of zero/inf not specified", FUNC(hypot) (minus_infty, 1), plus_infty, 0, 0, IGNORE_ZERO_INF_SIGN); #ifndef TEST_INLINE check_float ("hypot (inf, NaN) == inf", FUNC(hypot) (plus_infty, nan_value), plus_infty, 0, 0, 0); check_float ("hypot (-inf, NaN) == inf", FUNC(hypot) (minus_infty, nan_value), plus_infty, 0, 0, 0); check_float ("hypot (NaN, inf) == inf", FUNC(hypot) (nan_value, plus_infty), plus_infty, 0, 0, 0); check_float ("hypot (NaN, -inf) == inf", FUNC(hypot) (nan_value, minus_infty), plus_infty, 0, 0, 0); #endif check_float ("hypot (NaN, NaN) == NaN", FUNC(hypot) (nan_value, nan_value), nan_value, 0, 0, 0); /* hypot (x,y) == hypot (+-x, +-y) */ check_float ("hypot (0.7, 12.4) == 12.419742348374220601176836866763271", FUNC(hypot) (0.7L, 12.4L), 12.419742348374220601176836866763271L, DELTA1013, 0, 0); check_float ("hypot (-0.7, 12.4) == 12.419742348374220601176836866763271", FUNC(hypot) (-0.7L, 12.4L), 12.419742348374220601176836866763271L, DELTA1014, 0, 0); check_float ("hypot (0.7, -12.4) == 12.419742348374220601176836866763271", FUNC(hypot) (0.7L, -12.4L), 12.419742348374220601176836866763271L, DELTA1015, 0, 0); check_float ("hypot (-0.7, -12.4) == 12.419742348374220601176836866763271", FUNC(hypot) (-0.7L, -12.4L), 12.419742348374220601176836866763271L, DELTA1016, 0, 0); check_float ("hypot (12.4, 0.7) == 12.419742348374220601176836866763271", FUNC(hypot) (12.4L, 0.7L), 12.419742348374220601176836866763271L, DELTA1017, 0, 0); check_float ("hypot (-12.4, 0.7) == 12.419742348374220601176836866763271", FUNC(hypot) (-12.4L, 0.7L), 12.419742348374220601176836866763271L, DELTA1018, 0, 0); check_float ("hypot (12.4, -0.7) == 12.419742348374220601176836866763271", FUNC(hypot) (12.4L, -0.7L), 12.419742348374220601176836866763271L, DELTA1019, 0, 0); check_float ("hypot (-12.4, -0.7) == 12.419742348374220601176836866763271", FUNC(hypot) (-12.4L, -0.7L), 12.419742348374220601176836866763271L, DELTA1020, 0, 0); /* hypot (x,0) == fabs (x) */ check_float ("hypot (0.7, 0) == 0.7", FUNC(hypot) (0.7L, 0), 0.7L, 0, 0, 0); check_float ("hypot (-0.7, 0) == 0.7", FUNC(hypot) (-0.7L, 0), 0.7L, 0, 0, 0); check_float ("hypot (-5.7e7, 0) == 5.7e7", FUNC(hypot) (-5.7e7, 0), 5.7e7L, 0, 0, 0); check_float ("hypot (0.7, 1.2) == 1.3892443989449804508432547041028554", FUNC(hypot) (0.7L, 1.2L), 1.3892443989449804508432547041028554L, DELTA1024, 0, 0); print_max_error ("hypot", DELTAhypot, 0); } static void ilogb_test (void) { init_max_error (); check_int ("ilogb (1) == 0", FUNC(ilogb) (1), 0, 0, 0, 0); check_int ("ilogb (e) == 1", FUNC(ilogb) (M_El), 1, 0, 0, 0); check_int ("ilogb (1024) == 10", FUNC(ilogb) (1024), 10, 0, 0, 0); check_int ("ilogb (-2000) == 10", FUNC(ilogb) (-2000), 10, 0, 0, 0); /* XXX We have a problem here: the standard does not tell us whether exceptions are allowed/required. ignore them for now. */ check_int ("ilogb (0.0) == FP_ILOGB0 plus exceptions allowed", FUNC(ilogb) (0.0), FP_ILOGB0, 0, 0, EXCEPTIONS_OK); check_int ("ilogb (NaN) == FP_ILOGBNAN plus exceptions allowed", FUNC(ilogb) (nan_value), FP_ILOGBNAN, 0, 0, EXCEPTIONS_OK); check_int ("ilogb (inf) == INT_MAX plus exceptions allowed", FUNC(ilogb) (plus_infty), INT_MAX, 0, 0, EXCEPTIONS_OK); check_int ("ilogb (-inf) == INT_MAX plus exceptions allowed", FUNC(ilogb) (minus_infty), INT_MAX, 0, 0, EXCEPTIONS_OK); print_max_error ("ilogb", 0, 0); } static void isfinite_test (void) { init_max_error (); check_bool ("isfinite (0) == true", isfinite (0.0), 1, 0, 0, 0); check_bool ("isfinite (-0) == true", isfinite (minus_zero), 1, 0, 0, 0); check_bool ("isfinite (10) == true", isfinite (10.0), 1, 0, 0, 0); check_bool ("isfinite (inf) == false", isfinite (plus_infty), 0, 0, 0, 0); check_bool ("isfinite (-inf) == false", isfinite (minus_infty), 0, 0, 0, 0); check_bool ("isfinite (NaN) == false", isfinite (nan_value), 0, 0, 0, 0); print_max_error ("isfinite", 0, 0); } static void isnormal_test (void) { init_max_error (); check_bool ("isnormal (0) == false", isnormal (0.0), 0, 0, 0, 0); check_bool ("isnormal (-0) == false", isnormal (minus_zero), 0, 0, 0, 0); check_bool ("isnormal (10) == true", isnormal (10.0), 1, 0, 0, 0); check_bool ("isnormal (inf) == false", isnormal (plus_infty), 0, 0, 0, 0); check_bool ("isnormal (-inf) == false", isnormal (minus_infty), 0, 0, 0, 0); check_bool ("isnormal (NaN) == false", isnormal (nan_value), 0, 0, 0, 0); print_max_error ("isnormal", 0, 0); } static void j0_test (void) { FLOAT s, c; errno = 0; FUNC (sincos) (0, &s, &c); if (errno == ENOSYS) /* Required function not implemented. */ return; FUNC(j0) (0); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); /* j0 is the Bessel function of the first kind of order 0 */ check_float ("j0 (NaN) == NaN", FUNC(j0) (nan_value), nan_value, 0, 0, 0); check_float ("j0 (inf) == 0", FUNC(j0) (plus_infty), 0, 0, 0, 0); check_float ("j0 (-1.0) == 0.76519768655796655145", FUNC(j0) (-1.0), 0.76519768655796655145L, 0, 0, 0); check_float ("j0 (0.0) == 1.0", FUNC(j0) (0.0), 1.0, 0, 0, 0); check_float ("j0 (0.1) == 0.99750156206604003228", FUNC(j0) (0.1L), 0.99750156206604003228L, 0, 0, 0); check_float ("j0 (0.7) == 0.88120088860740528084", FUNC(j0) (0.7L), 0.88120088860740528084L, 0, 0, 0); check_float ("j0 (1.0) == 0.76519768655796655145", FUNC(j0) (1.0), 0.76519768655796655145L, 0, 0, 0); check_float ("j0 (1.5) == 0.51182767173591812875", FUNC(j0) (1.5), 0.51182767173591812875L, 0, 0, 0); check_float ("j0 (2.0) == 0.22389077914123566805", FUNC(j0) (2.0), 0.22389077914123566805L, DELTA1053, 0, 0); check_float ("j0 (8.0) == 0.17165080713755390609", FUNC(j0) (8.0), 0.17165080713755390609L, DELTA1054, 0, 0); check_float ("j0 (10.0) == -0.24593576445134833520", FUNC(j0) (10.0), -0.24593576445134833520L, DELTA1055, 0, 0); print_max_error ("j0", DELTAj0, 0); } static void j1_test (void) { FLOAT s, c; errno = 0; FUNC (sincos) (0, &s, &c); if (errno == ENOSYS) /* Required function not implemented. */ return; FUNC(j1) (0); if (errno == ENOSYS) /* Function not implemented. */ return; /* j1 is the Bessel function of the first kind of order 1 */ init_max_error (); check_float ("j1 (NaN) == NaN", FUNC(j1) (nan_value), nan_value, 0, 0, 0); check_float ("j1 (inf) == 0", FUNC(j1) (plus_infty), 0, 0, 0, 0); check_float ("j1 (-1.0) == -0.44005058574493351596", FUNC(j1) (-1.0), -0.44005058574493351596L, 0, 0, 0); check_float ("j1 (0.0) == 0.0", FUNC(j1) (0.0), 0.0, 0, 0, 0); check_float ("j1 (0.1) == 0.049937526036241997556", FUNC(j1) (0.1L), 0.049937526036241997556L, 0, 0, 0); check_float ("j1 (0.7) == 0.32899574154005894785", FUNC(j1) (0.7L), 0.32899574154005894785L, 0, 0, 0); check_float ("j1 (1.0) == 0.44005058574493351596", FUNC(j1) (1.0), 0.44005058574493351596L, 0, 0, 0); check_float ("j1 (1.5) == 0.55793650791009964199", FUNC(j1) (1.5), 0.55793650791009964199L, 0, 0, 0); check_float ("j1 (2.0) == 0.57672480775687338720", FUNC(j1) (2.0), 0.57672480775687338720L, DELTA1064, 0, 0); check_float ("j1 (8.0) == 0.23463634685391462438", FUNC(j1) (8.0), 0.23463634685391462438L, DELTA1065, 0, 0); check_float ("j1 (10.0) == 0.043472746168861436670", FUNC(j1) (10.0), 0.043472746168861436670L, DELTA1066, 0, 0); print_max_error ("j1", DELTAj1, 0); } static void jn_test (void) { FLOAT s, c; errno = 0; FUNC (sincos) (0, &s, &c); if (errno == ENOSYS) /* Required function not implemented. */ return; FUNC(jn) (1, 1); if (errno == ENOSYS) /* Function not implemented. */ return; /* jn is the Bessel function of the first kind of order n. */ init_max_error (); /* jn (0, x) == j0 (x) */ check_float ("jn (0, NaN) == NaN", FUNC(jn) (0, nan_value), nan_value, 0, 0, 0); check_float ("jn (0, inf) == 0", FUNC(jn) (0, plus_infty), 0, 0, 0, 0); check_float ("jn (0, -1.0) == 0.76519768655796655145", FUNC(jn) (0, -1.0), 0.76519768655796655145L, 0, 0, 0); check_float ("jn (0, 0.0) == 1.0", FUNC(jn) (0, 0.0), 1.0, 0, 0, 0); check_float ("jn (0, 0.1) == 0.99750156206604003228", FUNC(jn) (0, 0.1L), 0.99750156206604003228L, 0, 0, 0); check_float ("jn (0, 0.7) == 0.88120088860740528084", FUNC(jn) (0, 0.7L), 0.88120088860740528084L, 0, 0, 0); check_float ("jn (0, 1.0) == 0.76519768655796655145", FUNC(jn) (0, 1.0), 0.76519768655796655145L, 0, 0, 0); check_float ("jn (0, 1.5) == 0.51182767173591812875", FUNC(jn) (0, 1.5), 0.51182767173591812875L, 0, 0, 0); check_float ("jn (0, 2.0) == 0.22389077914123566805", FUNC(jn) (0, 2.0), 0.22389077914123566805L, DELTA1075, 0, 0); check_float ("jn (0, 8.0) == 0.17165080713755390609", FUNC(jn) (0, 8.0), 0.17165080713755390609L, DELTA1076, 0, 0); check_float ("jn (0, 10.0) == -0.24593576445134833520", FUNC(jn) (0, 10.0), -0.24593576445134833520L, DELTA1077, 0, 0); /* jn (1, x) == j1 (x) */ check_float ("jn (1, NaN) == NaN", FUNC(jn) (1, nan_value), nan_value, 0, 0, 0); check_float ("jn (1, inf) == 0", FUNC(jn) (1, plus_infty), 0, 0, 0, 0); check_float ("jn (1, -1.0) == -0.44005058574493351596", FUNC(jn) (1, -1.0), -0.44005058574493351596L, 0, 0, 0); check_float ("jn (1, 0.0) == 0.0", FUNC(jn) (1, 0.0), 0.0, 0, 0, 0); check_float ("jn (1, 0.1) == 0.049937526036241997556", FUNC(jn) (1, 0.1L), 0.049937526036241997556L, 0, 0, 0); check_float ("jn (1, 0.7) == 0.32899574154005894785", FUNC(jn) (1, 0.7L), 0.32899574154005894785L, 0, 0, 0); check_float ("jn (1, 1.0) == 0.44005058574493351596", FUNC(jn) (1, 1.0), 0.44005058574493351596L, 0, 0, 0); check_float ("jn (1, 1.5) == 0.55793650791009964199", FUNC(jn) (1, 1.5), 0.55793650791009964199L, 0, 0, 0); check_float ("jn (1, 2.0) == 0.57672480775687338720", FUNC(jn) (1, 2.0), 0.57672480775687338720L, DELTA1086, 0, 0); check_float ("jn (1, 8.0) == 0.23463634685391462438", FUNC(jn) (1, 8.0), 0.23463634685391462438L, DELTA1087, 0, 0); check_float ("jn (1, 10.0) == 0.043472746168861436670", FUNC(jn) (1, 10.0), 0.043472746168861436670L, DELTA1088, 0, 0); /* jn (3, x) */ check_float ("jn (3, NaN) == NaN", FUNC(jn) (3, nan_value), nan_value, 0, 0, 0); check_float ("jn (3, inf) == 0", FUNC(jn) (3, plus_infty), 0, 0, 0, 0); check_float ("jn (3, -1.0) == -0.019563353982668405919", FUNC(jn) (3, -1.0), -0.019563353982668405919L, DELTA1091, 0, 0); check_float ("jn (3, 0.0) == 0.0", FUNC(jn) (3, 0.0), 0.0, 0, 0, 0); check_float ("jn (3, 0.1) == 0.000020820315754756261429", FUNC(jn) (3, 0.1L), 0.000020820315754756261429L, DELTA1093, 0, 0); check_float ("jn (3, 0.7) == 0.0069296548267508408077", FUNC(jn) (3, 0.7L), 0.0069296548267508408077L, DELTA1094, 0, 0); check_float ("jn (3, 1.0) == 0.019563353982668405919", FUNC(jn) (3, 1.0), 0.019563353982668405919L, DELTA1095, 0, 0); check_float ("jn (3, 2.0) == 0.12894324947440205110", FUNC(jn) (3, 2.0), 0.12894324947440205110L, DELTA1096, 0, 0); check_float ("jn (3, 10.0) == 0.058379379305186812343", FUNC(jn) (3, 10.0), 0.058379379305186812343L, DELTA1097, 0, 0); /* jn (10, x) */ check_float ("jn (10, NaN) == NaN", FUNC(jn) (10, nan_value), nan_value, 0, 0, 0); check_float ("jn (10, inf) == 0", FUNC(jn) (10, plus_infty), 0, 0, 0, 0); check_float ("jn (10, -1.0) == 0.26306151236874532070e-9", FUNC(jn) (10, -1.0), 0.26306151236874532070e-9L, DELTA1100, 0, 0); check_float ("jn (10, 0.0) == 0.0", FUNC(jn) (10, 0.0), 0.0, 0, 0, 0); check_float ("jn (10, 0.1) == 0.26905328954342155795e-19", FUNC(jn) (10, 0.1L), 0.26905328954342155795e-19L, DELTA1102, 0, 0); check_float ("jn (10, 0.7) == 0.75175911502153953928e-11", FUNC(jn) (10, 0.7L), 0.75175911502153953928e-11L, DELTA1103, 0, 0); check_float ("jn (10, 1.0) == 0.26306151236874532070e-9", FUNC(jn) (10, 1.0), 0.26306151236874532070e-9L, DELTA1104, 0, 0); check_float ("jn (10, 2.0) == 0.25153862827167367096e-6", FUNC(jn) (10, 2.0), 0.25153862827167367096e-6L, DELTA1105, 0, 0); check_float ("jn (10, 10.0) == 0.20748610663335885770", FUNC(jn) (10, 10.0), 0.20748610663335885770L, DELTA1106, 0, 0); print_max_error ("jn", DELTAjn, 0); } static void ldexp_test (void) { check_float ("ldexp (0, 0) == 0", FUNC(ldexp) (0, 0), 0, 0, 0, 0); check_float ("ldexp (-0, 0) == -0", FUNC(ldexp) (minus_zero, 0), minus_zero, 0, 0, 0); check_float ("ldexp (inf, 1) == inf", FUNC(ldexp) (plus_infty, 1), plus_infty, 0, 0, 0); check_float ("ldexp (-inf, 1) == -inf", FUNC(ldexp) (minus_infty, 1), minus_infty, 0, 0, 0); check_float ("ldexp (NaN, 1) == NaN", FUNC(ldexp) (nan_value, 1), nan_value, 0, 0, 0); check_float ("ldexp (0.8, 4) == 12.8", FUNC(ldexp) (0.8L, 4), 12.8L, 0, 0, 0); check_float ("ldexp (-0.854375, 5) == -27.34", FUNC(ldexp) (-0.854375L, 5), -27.34L, 0, 0, 0); /* ldexp (x, 0) == x. */ check_float ("ldexp (1.0, 0) == 1.0", FUNC(ldexp) (1.0L, 0L), 1.0L, 0, 0, 0); } static void lgamma_test (void) { errno = 0; FUNC(lgamma) (0); if (errno == ENOSYS) /* Function not implemented. */ return; feclearexcept (FE_ALL_EXCEPT); init_max_error (); signgam = 0; check_float ("lgamma (inf) == inf", FUNC(lgamma) (plus_infty), plus_infty, 0, 0, 0); signgam = 0; check_float ("lgamma (0) == inf plus division by zero exception", FUNC(lgamma) (0), plus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); signgam = 0; check_float ("lgamma (NaN) == NaN", FUNC(lgamma) (nan_value), nan_value, 0, 0, 0); /* lgamma (x) == +inf plus divide by zero exception for integer x <= 0. */ signgam = 0; check_float ("lgamma (-3) == inf plus division by zero exception", FUNC(lgamma) (-3), plus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); signgam = 0; check_float ("lgamma (-inf) == inf", FUNC(lgamma) (minus_infty), plus_infty, 0, 0, 0); signgam = 0; check_float ("lgamma (1) == 0", FUNC(lgamma) (1), 0, 0, 0, 0); check_int ("lgamma (1) sets signgam to 1", signgam, 1, 0, 0, 0); signgam = 0; check_float ("lgamma (3) == M_LN2l", FUNC(lgamma) (3), M_LN2l, 0, 0, 0); check_int ("lgamma (3) sets signgam to 1", signgam, 1, 0, 0, 0); signgam = 0; check_float ("lgamma (0.5) == log(sqrt(pi))", FUNC(lgamma) (0.5), M_LOG_SQRT_PIl, 0, 0, 0); check_int ("lgamma (0.5) sets signgam to 1", signgam, 1, 0, 0, 0); signgam = 0; check_float ("lgamma (-0.5) == log(2*sqrt(pi))", FUNC(lgamma) (-0.5), M_LOG_2_SQRT_PIl, DELTA1126, 0, 0); check_int ("lgamma (-0.5) sets signgam to -1", signgam, -1, 0, 0, 0); signgam = 0; check_float ("lgamma (0.7) == 0.26086724653166651439", FUNC(lgamma) (0.7L), 0.26086724653166651439L, DELTA1128, 0, 0); check_int ("lgamma (0.7) sets signgam to 1", signgam, 1, 0, 0, 0); signgam = 0; check_float ("lgamma (1.2) == -0.853740900033158497197e-1", FUNC(lgamma) (1.2L), -0.853740900033158497197e-1L, DELTA1130, 0, 0); check_int ("lgamma (1.2) sets signgam to 1", signgam, 1, 0, 0, 0); print_max_error ("lgamma", DELTAlgamma, 0); } static void lrint_test (void) { /* XXX this test is incomplete. We need to have a way to specifiy the rounding method and test the critical cases. So far, only unproblematic numbers are tested. */ init_max_error (); check_long ("lrint (0.0) == 0", FUNC(lrint) (0.0), 0, 0, 0, 0); check_long ("lrint (-0) == 0", FUNC(lrint) (minus_zero), 0, 0, 0, 0); check_long ("lrint (0.2) == 0", FUNC(lrint) (0.2L), 0, 0, 0, 0); check_long ("lrint (-0.2) == 0", FUNC(lrint) (-0.2L), 0, 0, 0, 0); check_long ("lrint (1.4) == 1", FUNC(lrint) (1.4L), 1, 0, 0, 0); check_long ("lrint (-1.4) == -1", FUNC(lrint) (-1.4L), -1, 0, 0, 0); check_long ("lrint (8388600.3) == 8388600", FUNC(lrint) (8388600.3L), 8388600, 0, 0, 0); check_long ("lrint (-8388600.3) == -8388600", FUNC(lrint) (-8388600.3L), -8388600, 0, 0, 0); print_max_error ("lrint", 0, 0); } static void llrint_test (void) { /* XXX this test is incomplete. We need to have a way to specifiy the rounding method and test the critical cases. So far, only unproblematic numbers are tested. */ init_max_error (); check_longlong ("llrint (0.0) == 0", FUNC(llrint) (0.0), 0, 0, 0, 0); check_longlong ("llrint (-0) == 0", FUNC(llrint) (minus_zero), 0, 0, 0, 0); check_longlong ("llrint (0.2) == 0", FUNC(llrint) (0.2L), 0, 0, 0, 0); check_longlong ("llrint (-0.2) == 0", FUNC(llrint) (-0.2L), 0, 0, 0, 0); check_longlong ("llrint (1.4) == 1", FUNC(llrint) (1.4L), 1, 0, 0, 0); check_longlong ("llrint (-1.4) == -1", FUNC(llrint) (-1.4L), -1, 0, 0, 0); check_longlong ("llrint (8388600.3) == 8388600", FUNC(llrint) (8388600.3L), 8388600, 0, 0, 0); check_longlong ("llrint (-8388600.3) == -8388600", FUNC(llrint) (-8388600.3L), -8388600, 0, 0, 0); /* Test boundary conditions. */ /* 0x1FFFFF */ check_longlong ("llrint (2097151.0) == 2097151LL", FUNC(llrint) (2097151.0), 2097151LL, 0, 0, 0); /* 0x800000 */ check_longlong ("llrint (8388608.0) == 8388608LL", FUNC(llrint) (8388608.0), 8388608LL, 0, 0, 0); /* 0x1000000 */ check_longlong ("llrint (16777216.0) == 16777216LL", FUNC(llrint) (16777216.0), 16777216LL, 0, 0, 0); /* 0x20000000000 */ check_longlong ("llrint (2199023255552.0) == 2199023255552LL", FUNC(llrint) (2199023255552.0), 2199023255552LL, 0, 0, 0); /* 0x40000000000 */ check_longlong ("llrint (4398046511104.0) == 4398046511104LL", FUNC(llrint) (4398046511104.0), 4398046511104LL, 0, 0, 0); /* 0x10000000000000 */ check_longlong ("llrint (4503599627370496.0) == 4503599627370496LL", FUNC(llrint) (4503599627370496.0), 4503599627370496LL, 0, 0, 0); /* 0x10000080000000 */ check_longlong ("llrint (4503601774854144.0) == 4503601774854144LL", FUNC(llrint) (4503601774854144.0), 4503601774854144LL, 0, 0, 0); /* 0x20000000000000 */ check_longlong ("llrint (9007199254740992.0) == 9007199254740992LL", FUNC(llrint) (9007199254740992.0), 9007199254740992LL, 0, 0, 0); /* 0x80000000000000 */ check_longlong ("llrint (36028797018963968.0) == 36028797018963968LL", FUNC(llrint) (36028797018963968.0), 36028797018963968LL, 0, 0, 0); /* 0x100000000000000 */ check_longlong ("llrint (72057594037927936.0) == 72057594037927936LL", FUNC(llrint) (72057594037927936.0), 72057594037927936LL, 0, 0, 0); print_max_error ("llrint", 0, 0); } static void log_test (void) { errno = 0; FUNC(log) (1); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_float ("log (0) == -inf plus division by zero exception", FUNC(log) (0), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_float ("log (-0) == -inf plus division by zero exception", FUNC(log) (minus_zero), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_float ("log (1) == 0", FUNC(log) (1), 0, 0, 0, 0); check_float ("log (-1) == NaN plus invalid exception", FUNC(log) (-1), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("log (inf) == inf", FUNC(log) (plus_infty), plus_infty, 0, 0, 0); check_float ("log (e) == 1", FUNC(log) (M_El), 1, DELTA1163, 0, 0); check_float ("log (1.0 / M_El) == -1", FUNC(log) (1.0 / M_El), -1, DELTA1164, 0, 0); check_float ("log (2) == M_LN2l", FUNC(log) (2), M_LN2l, 0, 0, 0); check_float ("log (10) == M_LN10l", FUNC(log) (10), M_LN10l, 0, 0, 0); check_float ("log (0.7) == -0.35667494393873237891263871124118447", FUNC(log) (0.7L), -0.35667494393873237891263871124118447L, DELTA1167, 0, 0); print_max_error ("log", DELTAlog, 0); } static void log10_test (void) { errno = 0; FUNC(log10) (1); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_float ("log10 (0) == -inf plus division by zero exception", FUNC(log10) (0), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_float ("log10 (-0) == -inf plus division by zero exception", FUNC(log10) (minus_zero), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_float ("log10 (1) == 0", FUNC(log10) (1), 0, 0, 0, 0); /* log10 (x) == NaN plus invalid exception if x < 0. */ check_float ("log10 (-1) == NaN plus invalid exception", FUNC(log10) (-1), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("log10 (inf) == inf", FUNC(log10) (plus_infty), plus_infty, 0, 0, 0); check_float ("log10 (NaN) == NaN", FUNC(log10) (nan_value), nan_value, 0, 0, 0); check_float ("log10 (0.1) == -1", FUNC(log10) (0.1L), -1, 0, 0, 0); check_float ("log10 (10.0) == 1", FUNC(log10) (10.0), 1, 0, 0, 0); check_float ("log10 (100.0) == 2", FUNC(log10) (100.0), 2, 0, 0, 0); check_float ("log10 (10000.0) == 4", FUNC(log10) (10000.0), 4, 0, 0, 0); check_float ("log10 (e) == log10(e)", FUNC(log10) (M_El), M_LOG10El, DELTA1178, 0, 0); check_float ("log10 (0.7) == -0.15490195998574316929", FUNC(log10) (0.7L), -0.15490195998574316929L, DELTA1179, 0, 0); print_max_error ("log10", DELTAlog10, 0); } static void log1p_test (void) { errno = 0; FUNC(log1p) (0); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_float ("log1p (0) == 0", FUNC(log1p) (0), 0, 0, 0, 0); check_float ("log1p (-0) == -0", FUNC(log1p) (minus_zero), minus_zero, 0, 0, 0); check_float ("log1p (-1) == -inf plus division by zero exception", FUNC(log1p) (-1), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_float ("log1p (-2) == NaN plus invalid exception", FUNC(log1p) (-2), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("log1p (inf) == inf", FUNC(log1p) (plus_infty), plus_infty, 0, 0, 0); check_float ("log1p (NaN) == NaN", FUNC(log1p) (nan_value), nan_value, 0, 0, 0); check_float ("log1p (M_El - 1.0) == 1", FUNC(log1p) (M_El - 1.0), 1, DELTA1186, 0, 0); check_float ("log1p (-0.3) == -0.35667494393873237891263871124118447", FUNC(log1p) (-0.3L), -0.35667494393873237891263871124118447L, DELTA1187, 0, 0); print_max_error ("log1p", DELTAlog1p, 0); } static void log2_test (void) { errno = 0; FUNC(log2) (1); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_float ("log2 (0) == -inf plus division by zero exception", FUNC(log2) (0), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_float ("log2 (-0) == -inf plus division by zero exception", FUNC(log2) (minus_zero), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_float ("log2 (1) == 0", FUNC(log2) (1), 0, 0, 0, 0); check_float ("log2 (-1) == NaN plus invalid exception", FUNC(log2) (-1), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("log2 (inf) == inf", FUNC(log2) (plus_infty), plus_infty, 0, 0, 0); check_float ("log2 (NaN) == NaN", FUNC(log2) (nan_value), nan_value, 0, 0, 0); check_float ("log2 (e) == M_LOG2El", FUNC(log2) (M_El), M_LOG2El, 0, 0, 0); check_float ("log2 (2.0) == 1", FUNC(log2) (2.0), 1, 0, 0, 0); check_float ("log2 (16.0) == 4", FUNC(log2) (16.0), 4, 0, 0, 0); check_float ("log2 (256.0) == 8", FUNC(log2) (256.0), 8, 0, 0, 0); check_float ("log2 (0.7) == -0.51457317282975824043", FUNC(log2) (0.7L), -0.51457317282975824043L, DELTA1198, 0, 0); print_max_error ("log2", DELTAlog2, 0); } static void logb_test (void) { init_max_error (); check_float ("logb (inf) == inf", FUNC(logb) (plus_infty), plus_infty, 0, 0, 0); check_float ("logb (-inf) == inf", FUNC(logb) (minus_infty), plus_infty, 0, 0, 0); check_float ("logb (0) == -inf plus division by zero exception", FUNC(logb) (0), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_float ("logb (-0) == -inf plus division by zero exception", FUNC(logb) (minus_zero), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_float ("logb (NaN) == NaN", FUNC(logb) (nan_value), nan_value, 0, 0, 0); check_float ("logb (1) == 0", FUNC(logb) (1), 0, 0, 0, 0); check_float ("logb (e) == 1", FUNC(logb) (M_El), 1, 0, 0, 0); check_float ("logb (1024) == 10", FUNC(logb) (1024), 10, 0, 0, 0); check_float ("logb (-2000) == 10", FUNC(logb) (-2000), 10, 0, 0, 0); print_max_error ("logb", 0, 0); } static void lround_test (void) { init_max_error (); check_long ("lround (0) == 0", FUNC(lround) (0), 0, 0, 0, 0); check_long ("lround (-0) == 0", FUNC(lround) (minus_zero), 0, 0, 0, 0); check_long ("lround (0.2) == 0.0", FUNC(lround) (0.2L), 0.0, 0, 0, 0); check_long ("lround (-0.2) == 0", FUNC(lround) (-0.2L), 0, 0, 0, 0); check_long ("lround (0.5) == 1", FUNC(lround) (0.5), 1, 0, 0, 0); check_long ("lround (-0.5) == -1", FUNC(lround) (-0.5), -1, 0, 0, 0); check_long ("lround (0.8) == 1", FUNC(lround) (0.8L), 1, 0, 0, 0); check_long ("lround (-0.8) == -1", FUNC(lround) (-0.8L), -1, 0, 0, 0); check_long ("lround (1.5) == 2", FUNC(lround) (1.5), 2, 0, 0, 0); check_long ("lround (-1.5) == -2", FUNC(lround) (-1.5), -2, 0, 0, 0); check_long ("lround (22514.5) == 22515", FUNC(lround) (22514.5), 22515, 0, 0, 0); check_long ("lround (-22514.5) == -22515", FUNC(lround) (-22514.5), -22515, 0, 0, 0); #ifndef TEST_FLOAT check_long ("lround (2097152.5) == 2097153", FUNC(lround) (2097152.5), 2097153, 0, 0, 0); check_long ("lround (-2097152.5) == -2097153", FUNC(lround) (-2097152.5), -2097153, 0, 0, 0); #endif print_max_error ("lround", 0, 0); } static void llround_test (void) { init_max_error (); check_longlong ("llround (0) == 0", FUNC(llround) (0), 0, 0, 0, 0); check_longlong ("llround (-0) == 0", FUNC(llround) (minus_zero), 0, 0, 0, 0); check_longlong ("llround (0.2) == 0.0", FUNC(llround) (0.2L), 0.0, 0, 0, 0); check_longlong ("llround (-0.2) == 0", FUNC(llround) (-0.2L), 0, 0, 0, 0); check_longlong ("llround (0.5) == 1", FUNC(llround) (0.5), 1, 0, 0, 0); check_longlong ("llround (-0.5) == -1", FUNC(llround) (-0.5), -1, 0, 0, 0); check_longlong ("llround (0.8) == 1", FUNC(llround) (0.8L), 1, 0, 0, 0); check_longlong ("llround (-0.8) == -1", FUNC(llround) (-0.8L), -1, 0, 0, 0); check_longlong ("llround (1.5) == 2", FUNC(llround) (1.5), 2, 0, 0, 0); check_longlong ("llround (-1.5) == -2", FUNC(llround) (-1.5), -2, 0, 0, 0); check_longlong ("llround (22514.5) == 22515", FUNC(llround) (22514.5), 22515, 0, 0, 0); check_longlong ("llround (-22514.5) == -22515", FUNC(llround) (-22514.5), -22515, 0, 0, 0); #ifndef TEST_FLOAT check_longlong ("llround (2097152.5) == 2097153", FUNC(llround) (2097152.5), 2097153, 0, 0, 0); check_longlong ("llround (-2097152.5) == -2097153", FUNC(llround) (-2097152.5), -2097153, 0, 0, 0); check_longlong ("llround (34359738368.5) == 34359738369ll", FUNC(llround) (34359738368.5), 34359738369ll, 0, 0, 0); check_longlong ("llround (-34359738368.5) == -34359738369ll", FUNC(llround) (-34359738368.5), -34359738369ll, 0, 0, 0); #endif /* Test boundary conditions. */ /* 0x1FFFFF */ check_longlong ("llround (2097151.0) == 2097151LL", FUNC(llround) (2097151.0), 2097151LL, 0, 0, 0); /* 0x800000 */ check_longlong ("llround (8388608.0) == 8388608LL", FUNC(llround) (8388608.0), 8388608LL, 0, 0, 0); /* 0x1000000 */ check_longlong ("llround (16777216.0) == 16777216LL", FUNC(llround) (16777216.0), 16777216LL, 0, 0, 0); /* 0x20000000000 */ check_longlong ("llround (2199023255552.0) == 2199023255552LL", FUNC(llround) (2199023255552.0), 2199023255552LL, 0, 0, 0); /* 0x40000000000 */ check_longlong ("llround (4398046511104.0) == 4398046511104LL", FUNC(llround) (4398046511104.0), 4398046511104LL, 0, 0, 0); /* 0x10000000000000 */ check_longlong ("llround (4503599627370496.0) == 4503599627370496LL", FUNC(llround) (4503599627370496.0), 4503599627370496LL, 0, 0, 0); /* 0x10000080000000 */ check_longlong ("llrint (4503601774854144.0) == 4503601774854144LL", FUNC(llrint) (4503601774854144.0), 4503601774854144LL, 0, 0, 0); /* 0x20000000000000 */ check_longlong ("llround (9007199254740992.0) == 9007199254740992LL", FUNC(llround) (9007199254740992.0), 9007199254740992LL, 0, 0, 0); /* 0x80000000000000 */ check_longlong ("llround (36028797018963968.0) == 36028797018963968LL", FUNC(llround) (36028797018963968.0), 36028797018963968LL, 0, 0, 0); /* 0x100000000000000 */ check_longlong ("llround (72057594037927936.0) == 72057594037927936LL", FUNC(llround) (72057594037927936.0), 72057594037927936LL, 0, 0, 0); #ifndef TEST_FLOAT /* 0x100000000 */ check_longlong ("llround (4294967295.5) == 4294967296LL", FUNC(llround) (4294967295.5), 4294967296LL, 0, 0, 0); /* 0x200000000 */ check_longlong ("llround (8589934591.5) == 8589934592LL", FUNC(llround) (8589934591.5), 8589934592LL, 0, 0, 0); #endif print_max_error ("llround", 0, 0); } static void modf_test (void) { FLOAT x; init_max_error (); check_float ("modf (inf, &x) == 0", FUNC(modf) (plus_infty, &x), 0, 0, 0, 0); check_float ("modf (inf, &x) sets x to plus_infty", x, plus_infty, 0, 0, 0); check_float ("modf (-inf, &x) == -0", FUNC(modf) (minus_infty, &x), minus_zero, 0, 0, 0); check_float ("modf (-inf, &x) sets x to minus_infty", x, minus_infty, 0, 0, 0); check_float ("modf (NaN, &x) == NaN", FUNC(modf) (nan_value, &x), nan_value, 0, 0, 0); check_float ("modf (NaN, &x) sets x to nan_value", x, nan_value, 0, 0, 0); check_float ("modf (0, &x) == 0", FUNC(modf) (0, &x), 0, 0, 0, 0); check_float ("modf (0, &x) sets x to 0", x, 0, 0, 0, 0); check_float ("modf (1.5, &x) == 0.5", FUNC(modf) (1.5, &x), 0.5, 0, 0, 0); check_float ("modf (1.5, &x) sets x to 1", x, 1, 0, 0, 0); check_float ("modf (2.5, &x) == 0.5", FUNC(modf) (2.5, &x), 0.5, 0, 0, 0); check_float ("modf (2.5, &x) sets x to 2", x, 2, 0, 0, 0); check_float ("modf (-2.5, &x) == -0.5", FUNC(modf) (-2.5, &x), -0.5, 0, 0, 0); check_float ("modf (-2.5, &x) sets x to -2", x, -2, 0, 0, 0); check_float ("modf (20, &x) == 0", FUNC(modf) (20, &x), 0, 0, 0, 0); check_float ("modf (20, &x) sets x to 20", x, 20, 0, 0, 0); check_float ("modf (21, &x) == 0", FUNC(modf) (21, &x), 0, 0, 0, 0); check_float ("modf (21, &x) sets x to 21", x, 21, 0, 0, 0); check_float ("modf (89.5, &x) == 0.5", FUNC(modf) (89.5, &x), 0.5, 0, 0, 0); check_float ("modf (89.5, &x) sets x to 89", x, 89, 0, 0, 0); print_max_error ("modf", 0, 0); } static void nearbyint_test (void) { init_max_error (); check_float ("nearbyint (0.0) == 0.0", FUNC(nearbyint) (0.0), 0.0, 0, 0, 0); check_float ("nearbyint (-0) == -0", FUNC(nearbyint) (minus_zero), minus_zero, 0, 0, 0); check_float ("nearbyint (inf) == inf", FUNC(nearbyint) (plus_infty), plus_infty, 0, 0, 0); check_float ("nearbyint (-inf) == -inf", FUNC(nearbyint) (minus_infty), minus_infty, 0, 0, 0); check_float ("nearbyint (NaN) == NaN", FUNC(nearbyint) (nan_value), nan_value, 0, 0, 0); /* Default rounding mode is round to nearest. */ check_float ("nearbyint (0.5) == 0.0", FUNC(nearbyint) (0.5), 0.0, 0, 0, 0); check_float ("nearbyint (1.5) == 2.0", FUNC(nearbyint) (1.5), 2.0, 0, 0, 0); check_float ("nearbyint (-0.5) == -0", FUNC(nearbyint) (-0.5), minus_zero, 0, 0, 0); check_float ("nearbyint (-1.5) == -2.0", FUNC(nearbyint) (-1.5), -2.0, 0, 0, 0); print_max_error ("nearbyint", 0, 0); } static void nextafter_test (void) { init_max_error (); check_float ("nextafter (0, 0) == 0", FUNC(nextafter) (0, 0), 0, 0, 0, 0); check_float ("nextafter (-0, 0) == 0", FUNC(nextafter) (minus_zero, 0), 0, 0, 0, 0); check_float ("nextafter (0, -0) == -0", FUNC(nextafter) (0, minus_zero), minus_zero, 0, 0, 0); check_float ("nextafter (-0, -0) == -0", FUNC(nextafter) (minus_zero, minus_zero), minus_zero, 0, 0, 0); check_float ("nextafter (9, 9) == 9", FUNC(nextafter) (9, 9), 9, 0, 0, 0); check_float ("nextafter (-9, -9) == -9", FUNC(nextafter) (-9, -9), -9, 0, 0, 0); check_float ("nextafter (inf, inf) == inf", FUNC(nextafter) (plus_infty, plus_infty), plus_infty, 0, 0, 0); check_float ("nextafter (-inf, -inf) == -inf", FUNC(nextafter) (minus_infty, minus_infty), minus_infty, 0, 0, 0); check_float ("nextafter (NaN, 1.1) == NaN", FUNC(nextafter) (nan_value, 1.1L), nan_value, 0, 0, 0); check_float ("nextafter (1.1, NaN) == NaN", FUNC(nextafter) (1.1L, nan_value), nan_value, 0, 0, 0); check_float ("nextafter (NaN, NaN) == NaN", FUNC(nextafter) (nan_value, nan_value), nan_value, 0, 0, 0); /* XXX We need the hexadecimal FP number representation here for further tests. */ print_max_error ("nextafter", 0, 0); } #if 0 /* XXX scp XXX */ static void nexttoward_test (void) { init_max_error (); check_float ("nexttoward (0, 0) == 0", FUNC(nexttoward) (0, 0), 0, 0, 0, 0); check_float ("nexttoward (-0, 0) == 0", FUNC(nexttoward) (minus_zero, 0), 0, 0, 0, 0); check_float ("nexttoward (0, -0) == -0", FUNC(nexttoward) (0, minus_zero), minus_zero, 0, 0, 0); check_float ("nexttoward (-0, -0) == -0", FUNC(nexttoward) (minus_zero, minus_zero), minus_zero, 0, 0, 0); check_float ("nexttoward (9, 9) == 9", FUNC(nexttoward) (9, 9), 9, 0, 0, 0); check_float ("nexttoward (-9, -9) == -9", FUNC(nexttoward) (-9, -9), -9, 0, 0, 0); check_float ("nexttoward (inf, inf) == inf", FUNC(nexttoward) (plus_infty, plus_infty), plus_infty, 0, 0, 0); check_float ("nexttoward (-inf, -inf) == -inf", FUNC(nexttoward) (minus_infty, minus_infty), minus_infty, 0, 0, 0); check_float ("nexttoward (NaN, 1.1) == NaN", FUNC(nexttoward) (nan_value, 1.1L), nan_value, 0, 0, 0); check_float ("nexttoward (1.1, NaN) == NaN", FUNC(nexttoward) (1.1L, nan_value), nan_value, 0, 0, 0); check_float ("nexttoward (NaN, NaN) == NaN", FUNC(nexttoward) (nan_value, nan_value), nan_value, 0, 0, 0); /* XXX We need the hexadecimal FP number representation here for further tests. */ print_max_error ("nexttoward", 0, 0); } #endif static void pow_test (void) { errno = 0; FUNC(pow) (0, 0); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_float ("pow (0, 0) == 1", FUNC(pow) (0, 0), 1, 0, 0, 0); check_float ("pow (0, -0) == 1", FUNC(pow) (0, minus_zero), 1, 0, 0, 0); check_float ("pow (-0, 0) == 1", FUNC(pow) (minus_zero, 0), 1, 0, 0, 0); check_float ("pow (-0, -0) == 1", FUNC(pow) (minus_zero, minus_zero), 1, 0, 0, 0); check_float ("pow (10, 0) == 1", FUNC(pow) (10, 0), 1, 0, 0, 0); check_float ("pow (10, -0) == 1", FUNC(pow) (10, minus_zero), 1, 0, 0, 0); check_float ("pow (-10, 0) == 1", FUNC(pow) (-10, 0), 1, 0, 0, 0); check_float ("pow (-10, -0) == 1", FUNC(pow) (-10, minus_zero), 1, 0, 0, 0); check_float ("pow (NaN, 0) == 1", FUNC(pow) (nan_value, 0), 1, 0, 0, 0); check_float ("pow (NaN, -0) == 1", FUNC(pow) (nan_value, minus_zero), 1, 0, 0, 0); #ifndef TEST_INLINE check_float ("pow (1.1, inf) == inf", FUNC(pow) (1.1L, plus_infty), plus_infty, 0, 0, 0); check_float ("pow (inf, inf) == inf", FUNC(pow) (plus_infty, plus_infty), plus_infty, 0, 0, 0); check_float ("pow (-1.1, inf) == inf", FUNC(pow) (-1.1L, plus_infty), plus_infty, 0, 0, 0); check_float ("pow (-inf, inf) == inf", FUNC(pow) (minus_infty, plus_infty), plus_infty, 0, 0, 0); check_float ("pow (0.9, inf) == 0", FUNC(pow) (0.9L, plus_infty), 0, 0, 0, 0); check_float ("pow (1e-7, inf) == 0", FUNC(pow) (1e-7L, plus_infty), 0, 0, 0, 0); check_float ("pow (-0.9, inf) == 0", FUNC(pow) (-0.9L, plus_infty), 0, 0, 0, 0); check_float ("pow (-1e-7, inf) == 0", FUNC(pow) (-1e-7L, plus_infty), 0, 0, 0, 0); check_float ("pow (1.1, -inf) == 0", FUNC(pow) (1.1L, minus_infty), 0, 0, 0, 0); check_float ("pow (inf, -inf) == 0", FUNC(pow) (plus_infty, minus_infty), 0, 0, 0, 0); check_float ("pow (-1.1, -inf) == 0", FUNC(pow) (-1.1L, minus_infty), 0, 0, 0, 0); check_float ("pow (-inf, -inf) == 0", FUNC(pow) (minus_infty, minus_infty), 0, 0, 0, 0); check_float ("pow (0.9, -inf) == inf", FUNC(pow) (0.9L, minus_infty), plus_infty, 0, 0, 0); check_float ("pow (1e-7, -inf) == inf", FUNC(pow) (1e-7L, minus_infty), plus_infty, 0, 0, 0); check_float ("pow (-0.9, -inf) == inf", FUNC(pow) (-0.9L, minus_infty), plus_infty, 0, 0, 0); check_float ("pow (-1e-7, -inf) == inf", FUNC(pow) (-1e-7L, minus_infty), plus_infty, 0, 0, 0); check_float ("pow (inf, 1e-7) == inf", FUNC(pow) (plus_infty, 1e-7L), plus_infty, 0, 0, 0); check_float ("pow (inf, 1) == inf", FUNC(pow) (plus_infty, 1), plus_infty, 0, 0, 0); check_float ("pow (inf, 1e7) == inf", FUNC(pow) (plus_infty, 1e7L), plus_infty, 0, 0, 0); check_float ("pow (inf, -1e-7) == 0", FUNC(pow) (plus_infty, -1e-7L), 0, 0, 0, 0); check_float ("pow (inf, -1) == 0", FUNC(pow) (plus_infty, -1), 0, 0, 0, 0); check_float ("pow (inf, -1e7) == 0", FUNC(pow) (plus_infty, -1e7L), 0, 0, 0, 0); check_float ("pow (-inf, 1) == -inf", FUNC(pow) (minus_infty, 1), minus_infty, 0, 0, 0); check_float ("pow (-inf, 11) == -inf", FUNC(pow) (minus_infty, 11), minus_infty, 0, 0, 0); check_float ("pow (-inf, 1001) == -inf", FUNC(pow) (minus_infty, 1001), minus_infty, 0, 0, 0); check_float ("pow (-inf, 2) == inf", FUNC(pow) (minus_infty, 2), plus_infty, 0, 0, 0); check_float ("pow (-inf, 12) == inf", FUNC(pow) (minus_infty, 12), plus_infty, 0, 0, 0); check_float ("pow (-inf, 1002) == inf", FUNC(pow) (minus_infty, 1002), plus_infty, 0, 0, 0); check_float ("pow (-inf, 0.1) == inf", FUNC(pow) (minus_infty, 0.1L), plus_infty, 0, 0, 0); check_float ("pow (-inf, 1.1) == inf", FUNC(pow) (minus_infty, 1.1L), plus_infty, 0, 0, 0); check_float ("pow (-inf, 11.1) == inf", FUNC(pow) (minus_infty, 11.1L), plus_infty, 0, 0, 0); check_float ("pow (-inf, 1001.1) == inf", FUNC(pow) (minus_infty, 1001.1L), plus_infty, 0, 0, 0); check_float ("pow (-inf, -1) == -0", FUNC(pow) (minus_infty, -1), minus_zero, 0, 0, 0); check_float ("pow (-inf, -11) == -0", FUNC(pow) (minus_infty, -11), minus_zero, 0, 0, 0); check_float ("pow (-inf, -1001) == -0", FUNC(pow) (minus_infty, -1001), minus_zero, 0, 0, 0); check_float ("pow (-inf, -2) == 0", FUNC(pow) (minus_infty, -2), 0, 0, 0, 0); check_float ("pow (-inf, -12) == 0", FUNC(pow) (minus_infty, -12), 0, 0, 0, 0); check_float ("pow (-inf, -1002) == 0", FUNC(pow) (minus_infty, -1002), 0, 0, 0, 0); check_float ("pow (-inf, -0.1) == 0", FUNC(pow) (minus_infty, -0.1L), 0, 0, 0, 0); check_float ("pow (-inf, -1.1) == 0", FUNC(pow) (minus_infty, -1.1L), 0, 0, 0, 0); check_float ("pow (-inf, -11.1) == 0", FUNC(pow) (minus_infty, -11.1L), 0, 0, 0, 0); check_float ("pow (-inf, -1001.1) == 0", FUNC(pow) (minus_infty, -1001.1L), 0, 0, 0, 0); #endif check_float ("pow (NaN, NaN) == NaN", FUNC(pow) (nan_value, nan_value), nan_value, 0, 0, 0); check_float ("pow (0, NaN) == NaN", FUNC(pow) (0, nan_value), nan_value, 0, 0, 0); check_float ("pow (1, NaN) == 1", FUNC(pow) (1, nan_value), 1, 0, 0, 0); check_float ("pow (-1, NaN) == NaN", FUNC(pow) (-1, nan_value), nan_value, 0, 0, 0); check_float ("pow (NaN, 1) == NaN", FUNC(pow) (nan_value, 1), nan_value, 0, 0, 0); check_float ("pow (NaN, -1) == NaN", FUNC(pow) (nan_value, -1), nan_value, 0, 0, 0); /* pow (x, NaN) == NaN. */ check_float ("pow (3.0, NaN) == NaN", FUNC(pow) (3.0, nan_value), nan_value, 0, 0, 0); check_float ("pow (1, inf) == 1", FUNC(pow) (1, plus_infty), 1, 0, 0, 0); check_float ("pow (-1, inf) == 1", FUNC(pow) (-1, plus_infty), 1, 0, 0, 0); check_float ("pow (1, -inf) == 1", FUNC(pow) (1, minus_infty), 1, 0, 0, 0); check_float ("pow (-1, -inf) == 1", FUNC(pow) (-1, minus_infty), 1, 0, 0, 0); check_float ("pow (-0.1, 1.1) == NaN plus invalid exception", FUNC(pow) (-0.1L, 1.1L), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("pow (-0.1, -1.1) == NaN plus invalid exception", FUNC(pow) (-0.1L, -1.1L), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("pow (-10.1, 1.1) == NaN plus invalid exception", FUNC(pow) (-10.1L, 1.1L), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("pow (-10.1, -1.1) == NaN plus invalid exception", FUNC(pow) (-10.1L, -1.1L), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("pow (0, -1) == inf plus division by zero exception", FUNC(pow) (0, -1), plus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_float ("pow (0, -11) == inf plus division by zero exception", FUNC(pow) (0, -11), plus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_float ("pow (-0, -1) == -inf plus division by zero exception", FUNC(pow) (minus_zero, -1), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_float ("pow (-0, -11) == -inf plus division by zero exception", FUNC(pow) (minus_zero, -11), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_float ("pow (0, -2) == inf plus division by zero exception", FUNC(pow) (0, -2), plus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_float ("pow (0, -11.1) == inf plus division by zero exception", FUNC(pow) (0, -11.1L), plus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_float ("pow (-0, -2) == inf plus division by zero exception", FUNC(pow) (minus_zero, -2), plus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_float ("pow (-0, -11.1) == inf plus division by zero exception", FUNC(pow) (minus_zero, -11.1L), plus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_float ("pow (0, 1) == 0", FUNC(pow) (0, 1), 0, 0, 0, 0); check_float ("pow (0, 11) == 0", FUNC(pow) (0, 11), 0, 0, 0, 0); check_float ("pow (-0, 1) == -0", FUNC(pow) (minus_zero, 1), minus_zero, 0, 0, 0); check_float ("pow (-0, 11) == -0", FUNC(pow) (minus_zero, 11), minus_zero, 0, 0, 0); check_float ("pow (0, 2) == 0", FUNC(pow) (0, 2), 0, 0, 0, 0); check_float ("pow (0, 11.1) == 0", FUNC(pow) (0, 11.1L), 0, 0, 0, 0); check_float ("pow (-0, 2) == 0", FUNC(pow) (minus_zero, 2), 0, 0, 0, 0); check_float ("pow (-0, 11.1) == 0", FUNC(pow) (minus_zero, 11.1L), 0, 0, 0, 0); #ifndef TEST_INLINE /* pow (x, +inf) == +inf for |x| > 1. */ check_float ("pow (1.5, inf) == inf", FUNC(pow) (1.5, plus_infty), plus_infty, 0, 0, 0); /* pow (x, +inf) == +0 for |x| < 1. */ check_float ("pow (0.5, inf) == 0.0", FUNC(pow) (0.5, plus_infty), 0.0, 0, 0, 0); /* pow (x, -inf) == +0 for |x| > 1. */ check_float ("pow (1.5, -inf) == 0.0", FUNC(pow) (1.5, minus_infty), 0.0, 0, 0, 0); /* pow (x, -inf) == +inf for |x| < 1. */ check_float ("pow (0.5, -inf) == inf", FUNC(pow) (0.5, minus_infty), plus_infty, 0, 0, 0); #endif /* pow (+inf, y) == +inf for y > 0. */ check_float ("pow (inf, 2) == inf", FUNC(pow) (plus_infty, 2), plus_infty, 0, 0, 0); /* pow (+inf, y) == +0 for y < 0. */ check_float ("pow (inf, -1) == 0.0", FUNC(pow) (plus_infty, -1), 0.0, 0, 0, 0); /* pow (-inf, y) == -inf for y an odd integer > 0. */ check_float ("pow (-inf, 27) == -inf", FUNC(pow) (minus_infty, 27), minus_infty, 0, 0, 0); /* pow (-inf, y) == +inf for y > 0 and not an odd integer. */ check_float ("pow (-inf, 28) == inf", FUNC(pow) (minus_infty, 28), plus_infty, 0, 0, 0); /* pow (-inf, y) == -0 for y an odd integer < 0. */ check_float ("pow (-inf, -3) == -0", FUNC(pow) (minus_infty, -3), minus_zero, 0, 0, 0); /* pow (-inf, y) == +0 for y < 0 and not an odd integer. */ check_float ("pow (-inf, -2.0) == 0.0", FUNC(pow) (minus_infty, -2.0), 0.0, 0, 0, 0); /* pow (+0, y) == +0 for y an odd integer > 0. */ check_float ("pow (0.0, 27) == 0.0", FUNC(pow) (0.0, 27), 0.0, 0, 0, 0); /* pow (-0, y) == -0 for y an odd integer > 0. */ check_float ("pow (-0, 27) == -0", FUNC(pow) (minus_zero, 27), minus_zero, 0, 0, 0); /* pow (+0, y) == +0 for y > 0 and not an odd integer. */ check_float ("pow (0.0, 4) == 0.0", FUNC(pow) (0.0, 4), 0.0, 0, 0, 0); /* pow (-0, y) == +0 for y > 0 and not an odd integer. */ check_float ("pow (-0, 4) == 0.0", FUNC(pow) (minus_zero, 4), 0.0, 0, 0, 0); check_float ("pow (0.7, 1.2) == 0.65180494056638638188", FUNC(pow) (0.7L, 1.2L), 0.65180494056638638188L, DELTA1398, 0, 0); #if defined TEST_DOUBLE || defined TEST_LDOUBLE check_float ("pow (-7.49321e+133, -9.80818e+16) == 0", FUNC(pow) (-7.49321e+133, -9.80818e+16), 0, 0, 0, 0); #endif print_max_error ("pow", DELTApow, 0); } static void remainder_test (void) { errno = 0; FUNC(remainder) (1.625, 1.0); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_float ("remainder (1, 0) == NaN plus invalid exception", FUNC(remainder) (1, 0), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("remainder (1, -0) == NaN plus invalid exception", FUNC(remainder) (1, minus_zero), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("remainder (inf, 1) == NaN plus invalid exception", FUNC(remainder) (plus_infty, 1), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("remainder (-inf, 1) == NaN plus invalid exception", FUNC(remainder) (minus_infty, 1), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("remainder (NaN, NaN) == NaN", FUNC(remainder) (nan_value, nan_value), nan_value, 0, 0, 0); check_float ("remainder (1.625, 1.0) == -0.375", FUNC(remainder) (1.625, 1.0), -0.375, 0, 0, 0); check_float ("remainder (-1.625, 1.0) == 0.375", FUNC(remainder) (-1.625, 1.0), 0.375, 0, 0, 0); check_float ("remainder (1.625, -1.0) == -0.375", FUNC(remainder) (1.625, -1.0), -0.375, 0, 0, 0); check_float ("remainder (-1.625, -1.0) == 0.375", FUNC(remainder) (-1.625, -1.0), 0.375, 0, 0, 0); check_float ("remainder (5.0, 2.0) == 1.0", FUNC(remainder) (5.0, 2.0), 1.0, 0, 0, 0); check_float ("remainder (3.0, 2.0) == -1.0", FUNC(remainder) (3.0, 2.0), -1.0, 0, 0, 0); print_max_error ("remainder", 0, 0); } static void remquo_test (void) { /* x is needed. */ int x; errno = 0; FUNC(remquo) (1.625, 1.0, &x); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_float ("remquo (1, 0, &x) == NaN plus invalid exception", FUNC(remquo) (1, 0, &x), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("remquo (1, -0, &x) == NaN plus invalid exception", FUNC(remquo) (1, minus_zero, &x), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("remquo (inf, 1, &x) == NaN plus invalid exception", FUNC(remquo) (plus_infty, 1, &x), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("remquo (-inf, 1, &x) == NaN plus invalid exception", FUNC(remquo) (minus_infty, 1, &x), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("remquo (NaN, NaN, &x) == NaN", FUNC(remquo) (nan_value, nan_value, &x), nan_value, 0, 0, 0); check_float ("remquo (1.625, 1.0, &x) == -0.375", FUNC(remquo) (1.625, 1.0, &x), -0.375, 0, 0, 0); check_int ("remquo (1.625, 1.0, &x) sets x to 2", x, 2, 0, 0, 0); check_float ("remquo (-1.625, 1.0, &x) == 0.375", FUNC(remquo) (-1.625, 1.0, &x), 0.375, 0, 0, 0); check_int ("remquo (-1.625, 1.0, &x) sets x to -2", x, -2, 0, 0, 0); check_float ("remquo (1.625, -1.0, &x) == -0.375", FUNC(remquo) (1.625, -1.0, &x), -0.375, 0, 0, 0); check_int ("remquo (1.625, -1.0, &x) sets x to -2", x, -2, 0, 0, 0); check_float ("remquo (-1.625, -1.0, &x) == 0.375", FUNC(remquo) (-1.625, -1.0, &x), 0.375, 0, 0, 0); check_int ("remquo (-1.625, -1.0, &x) sets x to 2", x, 2, 0, 0, 0); check_float ("remquo (5, 2, &x) == 1", FUNC(remquo) (5, 2, &x), 1, 0, 0, 0); check_int ("remquo (5, 2, &x) sets x to 2", x, 2, 0, 0, 0); check_float ("remquo (3, 2, &x) == -1", FUNC(remquo) (3, 2, &x), -1, 0, 0, 0); check_int ("remquo (3, 2, &x) sets x to 2", x, 2, 0, 0, 0); print_max_error ("remquo", 0, 0); } static void rint_test (void) { init_max_error (); check_float ("rint (0.0) == 0.0", FUNC(rint) (0.0), 0.0, 0, 0, 0); check_float ("rint (-0) == -0", FUNC(rint) (minus_zero), minus_zero, 0, 0, 0); check_float ("rint (inf) == inf", FUNC(rint) (plus_infty), plus_infty, 0, 0, 0); check_float ("rint (-inf) == -inf", FUNC(rint) (minus_infty), minus_infty, 0, 0, 0); /* Default rounding mode is round to even. */ check_float ("rint (0.5) == 0.0", FUNC(rint) (0.5), 0.0, 0, 0, 0); check_float ("rint (1.5) == 2.0", FUNC(rint) (1.5), 2.0, 0, 0, 0); check_float ("rint (2.5) == 2.0", FUNC(rint) (2.5), 2.0, 0, 0, 0); check_float ("rint (3.5) == 4.0", FUNC(rint) (3.5), 4.0, 0, 0, 0); check_float ("rint (4.5) == 4.0", FUNC(rint) (4.5), 4.0, 0, 0, 0); check_float ("rint (-0.5) == -0.0", FUNC(rint) (-0.5), -0.0, 0, 0, 0); check_float ("rint (-1.5) == -2.0", FUNC(rint) (-1.5), -2.0, 0, 0, 0); check_float ("rint (-2.5) == -2.0", FUNC(rint) (-2.5), -2.0, 0, 0, 0); check_float ("rint (-3.5) == -4.0", FUNC(rint) (-3.5), -4.0, 0, 0, 0); check_float ("rint (-4.5) == -4.0", FUNC(rint) (-4.5), -4.0, 0, 0, 0); print_max_error ("rint", 0, 0); } static void round_test (void) { init_max_error (); check_float ("round (0) == 0", FUNC(round) (0), 0, 0, 0, 0); check_float ("round (-0) == -0", FUNC(round) (minus_zero), minus_zero, 0, 0, 0); check_float ("round (0.2) == 0.0", FUNC(round) (0.2L), 0.0, 0, 0, 0); check_float ("round (-0.2) == -0", FUNC(round) (-0.2L), minus_zero, 0, 0, 0); check_float ("round (0.5) == 1.0", FUNC(round) (0.5), 1.0, 0, 0, 0); check_float ("round (-0.5) == -1.0", FUNC(round) (-0.5), -1.0, 0, 0, 0); check_float ("round (0.8) == 1.0", FUNC(round) (0.8L), 1.0, 0, 0, 0); check_float ("round (-0.8) == -1.0", FUNC(round) (-0.8L), -1.0, 0, 0, 0); check_float ("round (1.5) == 2.0", FUNC(round) (1.5), 2.0, 0, 0, 0); check_float ("round (-1.5) == -2.0", FUNC(round) (-1.5), -2.0, 0, 0, 0); check_float ("round (2097152.5) == 2097153", FUNC(round) (2097152.5), 2097153, 0, 0, 0); check_float ("round (-2097152.5) == -2097153", FUNC(round) (-2097152.5), -2097153, 0, 0, 0); print_max_error ("round", 0, 0); } static void scalbn_test (void) { init_max_error (); check_float ("scalbn (0, 0) == 0", FUNC(scalbn) (0, 0), 0, 0, 0, 0); check_float ("scalbn (-0, 0) == -0", FUNC(scalbn) (minus_zero, 0), minus_zero, 0, 0, 0); check_float ("scalbn (inf, 1) == inf", FUNC(scalbn) (plus_infty, 1), plus_infty, 0, 0, 0); check_float ("scalbn (-inf, 1) == -inf", FUNC(scalbn) (minus_infty, 1), minus_infty, 0, 0, 0); check_float ("scalbn (NaN, 1) == NaN", FUNC(scalbn) (nan_value, 1), nan_value, 0, 0, 0); check_float ("scalbn (0.8, 4) == 12.8", FUNC(scalbn) (0.8L, 4), 12.8L, 0, 0, 0); check_float ("scalbn (-0.854375, 5) == -27.34", FUNC(scalbn) (-0.854375L, 5), -27.34L, 0, 0, 0); check_float ("scalbn (1, 0) == 1", FUNC(scalbn) (1, 0L), 1, 0, 0, 0); print_max_error ("scalbn", 0, 0); } static void scalbln_test (void) { init_max_error (); check_float ("scalbln (0, 0) == 0", FUNC(scalbln) (0, 0), 0, 0, 0, 0); check_float ("scalbln (-0, 0) == -0", FUNC(scalbln) (minus_zero, 0), minus_zero, 0, 0, 0); check_float ("scalbln (inf, 1) == inf", FUNC(scalbln) (plus_infty, 1), plus_infty, 0, 0, 0); check_float ("scalbln (-inf, 1) == -inf", FUNC(scalbln) (minus_infty, 1), minus_infty, 0, 0, 0); check_float ("scalbln (NaN, 1) == NaN", FUNC(scalbln) (nan_value, 1), nan_value, 0, 0, 0); check_float ("scalbln (0.8, 4) == 12.8", FUNC(scalbln) (0.8L, 4), 12.8L, 0, 0, 0); check_float ("scalbln (-0.854375, 5) == -27.34", FUNC(scalbln) (-0.854375L, 5), -27.34L, 0, 0, 0); check_float ("scalbln (1, 0) == 1", FUNC(scalbln) (1, 0L), 1, 0, 0, 0); print_max_error ("scalbn", 0, 0); } static void signbit_test (void) { init_max_error (); check_bool ("signbit (0) == false", signbit (0.0), 0, 0, 0, 0); check_bool ("signbit (-0) == true", signbit (minus_zero), 1, 0, 0, 0); check_bool ("signbit (inf) == false", signbit (plus_infty), 0, 0, 0, 0); check_bool ("signbit (-inf) == true", signbit (minus_infty), 1, 0, 0, 0); /* signbit (x) != 0 for x < 0. */ check_bool ("signbit (-1) == true", signbit (-1.0), 1, 0, 0, 0); /* signbit (x) == 0 for x >= 0. */ check_bool ("signbit (1) == false", signbit (1.0), 0, 0, 0, 0); print_max_error ("signbit", 0, 0); } static void sin_test (void) { errno = 0; FUNC(sin) (0); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_float ("sin (0) == 0", FUNC(sin) (0), 0, 0, 0, 0); check_float ("sin (-0) == -0", FUNC(sin) (minus_zero), minus_zero, 0, 0, 0); check_float ("sin (inf) == NaN plus invalid exception", FUNC(sin) (plus_infty), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("sin (-inf) == NaN plus invalid exception", FUNC(sin) (minus_infty), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("sin (NaN) == NaN", FUNC(sin) (nan_value), nan_value, 0, 0, 0); check_float ("sin (pi/6) == 0.5", FUNC(sin) (M_PI_6l), 0.5, 0, 0, 0); check_float ("sin (-pi/6) == -0.5", FUNC(sin) (-M_PI_6l), -0.5, 0, 0, 0); check_float ("sin (pi/2) == 1", FUNC(sin) (M_PI_2l), 1, 0, 0, 0); check_float ("sin (-pi/2) == -1", FUNC(sin) (-M_PI_2l), -1, 0, 0, 0); check_float ("sin (0.7) == 0.64421768723769105367261435139872014", FUNC(sin) (0.7L), 0.64421768723769105367261435139872014L, DELTA1524, 0, 0); print_max_error ("sin", DELTAsin, 0); } static void sincos_test (void) { FLOAT sin_res, cos_res; errno = 0; FUNC(sincos) (0, &sin_res, &cos_res); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); /* sincos is treated differently because it returns void. */ FUNC (sincos) (0, &sin_res, &cos_res); check_float ("sincos (0, &sin_res, &cos_res) puts 0 in sin_res", sin_res, 0, 0, 0, 0); check_float ("sincos (0, &sin_res, &cos_res) puts 1 in cos_res", cos_res, 1, 0, 0, 0); FUNC (sincos) (minus_zero, &sin_res, &cos_res); check_float ("sincos (-0, &sin_res, &cos_res) puts -0 in sin_res", sin_res, minus_zero, 0, 0, 0); check_float ("sincos (-0, &sin_res, &cos_res) puts 1 in cos_res", cos_res, 1, 0, 0, 0); FUNC (sincos) (plus_infty, &sin_res, &cos_res); check_float ("sincos (inf, &sin_res, &cos_res) puts NaN in sin_res plus invalid exception", sin_res, nan_value, 0, 0, INVALID_EXCEPTION); check_float ("sincos (inf, &sin_res, &cos_res) puts NaN in cos_res", cos_res, nan_value, 0, 0, 0); FUNC (sincos) (minus_infty, &sin_res, &cos_res); check_float ("sincos (-inf, &sin_res, &cos_res) puts NaN in sin_res plus invalid exception", sin_res, nan_value, 0, 0, INVALID_EXCEPTION); check_float ("sincos (-inf, &sin_res, &cos_res) puts NaN in cos_res", cos_res, nan_value, 0, 0, 0); FUNC (sincos) (nan_value, &sin_res, &cos_res); check_float ("sincos (NaN, &sin_res, &cos_res) puts NaN in sin_res", sin_res, nan_value, 0, 0, 0); check_float ("sincos (NaN, &sin_res, &cos_res) puts NaN in cos_res", cos_res, nan_value, 0, 0, 0); FUNC (sincos) (M_PI_2l, &sin_res, &cos_res); check_float ("sincos (pi/2, &sin_res, &cos_res) puts 1 in sin_res", sin_res, 1, 0, 0, 0); check_float ("sincos (pi/2, &sin_res, &cos_res) puts 0 in cos_res", cos_res, 0, DELTA1536, 0, 0); FUNC (sincos) (M_PI_6l, &sin_res, &cos_res); check_float ("sincos (pi/6, &sin_res, &cos_res) puts 0.5 in sin_res", sin_res, 0.5, 0, 0, 0); check_float ("sincos (pi/6, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in cos_res", cos_res, 0.86602540378443864676372317075293616L, 0, 0, 0); FUNC (sincos) (M_PI_6l*2.0, &sin_res, &cos_res); check_float ("sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in sin_res", sin_res, 0.86602540378443864676372317075293616L, DELTA1539, 0, 0); check_float ("sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res", cos_res, 0.5, DELTA1540, 0, 0); FUNC (sincos) (0.7L, &sin_res, &cos_res); check_float ("sincos (0.7, &sin_res, &cos_res) puts 0.64421768723769105367261435139872014 in sin_res", sin_res, 0.64421768723769105367261435139872014L, DELTA1541, 0, 0); check_float ("sincos (0.7, &sin_res, &cos_res) puts 0.76484218728448842625585999019186495 in cos_res", cos_res, 0.76484218728448842625585999019186495L, DELTA1542, 0, 0); print_max_error ("sincos", DELTAsincos, 0); } static void sinh_test (void) { errno = 0; FUNC(sinh) (0.7L); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_float ("sinh (0) == 0", FUNC(sinh) (0), 0, 0, 0, 0); check_float ("sinh (-0) == -0", FUNC(sinh) (minus_zero), minus_zero, 0, 0, 0); #ifndef TEST_INLINE check_float ("sinh (inf) == inf", FUNC(sinh) (plus_infty), plus_infty, 0, 0, 0); check_float ("sinh (-inf) == -inf", FUNC(sinh) (minus_infty), minus_infty, 0, 0, 0); #endif check_float ("sinh (NaN) == NaN", FUNC(sinh) (nan_value), nan_value, 0, 0, 0); check_float ("sinh (0.7) == 0.75858370183953350346", FUNC(sinh) (0.7L), 0.75858370183953350346L, DELTA1548, 0, 0); #if 0 /* XXX scp XXX */ check_float ("sinh (0x8p-32) == 1.86264514923095703232705808926175479e-9", FUNC(sinh) (0x8p-32L), 1.86264514923095703232705808926175479e-9L, 0, 0, 0); #endif print_max_error ("sinh", DELTAsinh, 0); } static void sqrt_test (void) { errno = 0; FUNC(sqrt) (1); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_float ("sqrt (0) == 0", FUNC(sqrt) (0), 0, 0, 0, 0); check_float ("sqrt (NaN) == NaN", FUNC(sqrt) (nan_value), nan_value, 0, 0, 0); check_float ("sqrt (inf) == inf", FUNC(sqrt) (plus_infty), plus_infty, 0, 0, 0); check_float ("sqrt (-0) == -0", FUNC(sqrt) (minus_zero), minus_zero, 0, 0, 0); /* sqrt (x) == NaN plus invalid exception for x < 0. */ check_float ("sqrt (-1) == NaN plus invalid exception", FUNC(sqrt) (-1), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("sqrt (-inf) == NaN plus invalid exception", FUNC(sqrt) (minus_infty), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("sqrt (NaN) == NaN", FUNC(sqrt) (nan_value), nan_value, 0, 0, 0); check_float ("sqrt (2209) == 47", FUNC(sqrt) (2209), 47, 0, 0, 0); check_float ("sqrt (4) == 2", FUNC(sqrt) (4), 2, 0, 0, 0); check_float ("sqrt (2) == M_SQRT2l", FUNC(sqrt) (2), M_SQRT2l, 0, 0, 0); check_float ("sqrt (0.25) == 0.5", FUNC(sqrt) (0.25), 0.5, 0, 0, 0); check_float ("sqrt (6642.25) == 81.5", FUNC(sqrt) (6642.25), 81.5, 0, 0, 0); check_float ("sqrt (15239.9025) == 123.45", FUNC(sqrt) (15239.9025L), 123.45L, DELTA1562, 0, 0); check_float ("sqrt (0.7) == 0.83666002653407554797817202578518747", FUNC(sqrt) (0.7L), 0.83666002653407554797817202578518747L, 0, 0, 0); print_max_error ("sqrt", DELTAsqrt, 0); } static void tan_test (void) { errno = 0; FUNC(tan) (0); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_float ("tan (0) == 0", FUNC(tan) (0), 0, 0, 0, 0); check_float ("tan (-0) == -0", FUNC(tan) (minus_zero), minus_zero, 0, 0, 0); check_float ("tan (inf) == NaN plus invalid exception", FUNC(tan) (plus_infty), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("tan (-inf) == NaN plus invalid exception", FUNC(tan) (minus_infty), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("tan (NaN) == NaN", FUNC(tan) (nan_value), nan_value, 0, 0, 0); check_float ("tan (pi/4) == 1", FUNC(tan) (M_PI_4l), 1, DELTA1569, 0, 0); check_float ("tan (0.7) == 0.84228838046307944812813500221293775", FUNC(tan) (0.7L), 0.84228838046307944812813500221293775L, DELTA1570, 0, 0); print_max_error ("tan", DELTAtan, 0); } static void tanh_test (void) { errno = 0; FUNC(tanh) (0.7L); if (errno == ENOSYS) /* Function not implemented. */ return; init_max_error (); check_float ("tanh (0) == 0", FUNC(tanh) (0), 0, 0, 0, 0); check_float ("tanh (-0) == -0", FUNC(tanh) (minus_zero), minus_zero, 0, 0, 0); #ifndef TEST_INLINE check_float ("tanh (inf) == 1", FUNC(tanh) (plus_infty), 1, 0, 0, 0); check_float ("tanh (-inf) == -1", FUNC(tanh) (minus_infty), -1, 0, 0, 0); #endif check_float ("tanh (NaN) == NaN", FUNC(tanh) (nan_value), nan_value, 0, 0, 0); check_float ("tanh (0.7) == 0.60436777711716349631", FUNC(tanh) (0.7L), 0.60436777711716349631L, DELTA1576, 0, 0); check_float ("tanh (-0.7) == -0.60436777711716349631", FUNC(tanh) (-0.7L), -0.60436777711716349631L, DELTA1577, 0, 0); check_float ("tanh (1.0) == 0.7615941559557648881194582826047935904", FUNC(tanh) (1.0L), 0.7615941559557648881194582826047935904L, 0, 0, 0); check_float ("tanh (-1.0) == -0.7615941559557648881194582826047935904", FUNC(tanh) (-1.0L), -0.7615941559557648881194582826047935904L, 0, 0, 0); /* 2^-57 */ check_float ("tanh (6.938893903907228377647697925567626953125e-18) == 6.938893903907228377647697925567626953125e-18", FUNC(tanh) (6.938893903907228377647697925567626953125e-18L), 6.938893903907228377647697925567626953125e-18L, 0, 0, 0); print_max_error ("tanh", DELTAtanh, 0); } static void tgamma_test (void) { errno = 0; FUNC(tgamma) (1); if (errno == ENOSYS) /* Function not implemented. */ return; feclearexcept (FE_ALL_EXCEPT); init_max_error (); check_float ("tgamma (inf) == inf", FUNC(tgamma) (plus_infty), plus_infty, 0, 0, 0); check_float ("tgamma (0) == inf plus divide-by-zero", FUNC(tgamma) (0), plus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_float ("tgamma (-0) == inf plus divide-by-zero", FUNC(tgamma) (minus_zero), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); /* tgamma (x) == NaN plus invalid exception for integer x <= 0. */ check_float ("tgamma (-2) == NaN plus invalid exception", FUNC(tgamma) (-2), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("tgamma (-inf) == NaN plus invalid exception", FUNC(tgamma) (minus_infty), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("tgamma (NaN) == NaN", FUNC(tgamma) (nan_value), nan_value, 0, 0, 0); check_float ("tgamma (0.5) == sqrt (pi)", FUNC(tgamma) (0.5), M_SQRT_PIl, DELTA1587, 0, 0); check_float ("tgamma (-0.5) == -2 sqrt (pi)", FUNC(tgamma) (-0.5), -M_2_SQRT_PIl, DELTA1588, 0, 0); check_float ("tgamma (1) == 1", FUNC(tgamma) (1), 1, 0, 0, 0); check_float ("tgamma (4) == 6", FUNC(tgamma) (4), 6, DELTA1590, 0, 0); check_float ("tgamma (0.7) == 1.29805533264755778568", FUNC(tgamma) (0.7L), 1.29805533264755778568L, DELTA1591, 0, 0); check_float ("tgamma (1.2) == 0.91816874239976061064", FUNC(tgamma) (1.2L), 0.91816874239976061064L, 0, 0, 0); print_max_error ("tgamma", DELTAtgamma, 0); } static void trunc_test (void) { init_max_error (); check_float ("trunc (inf) == inf", FUNC(trunc) (plus_infty), plus_infty, 0, 0, 0); check_float ("trunc (-inf) == -inf", FUNC(trunc) (minus_infty), minus_infty, 0, 0, 0); check_float ("trunc (NaN) == NaN", FUNC(trunc) (nan_value), nan_value, 0, 0, 0); check_float ("trunc (0) == 0", FUNC(trunc) (0), 0, 0, 0, 0); check_float ("trunc (-0) == -0", FUNC(trunc) (minus_zero), minus_zero, 0, 0, 0); check_float ("trunc (0.625) == 0", FUNC(trunc) (0.625), 0, 0, 0, 0); check_float ("trunc (-0.625) == -0", FUNC(trunc) (-0.625), minus_zero, 0, 0, 0); check_float ("trunc (1) == 1", FUNC(trunc) (1), 1, 0, 0, 0); check_float ("trunc (-1) == -1", FUNC(trunc) (-1), -1, 0, 0, 0); check_float ("trunc (1.625) == 1", FUNC(trunc) (1.625), 1, 0, 0, 0); check_float ("trunc (-1.625) == -1", FUNC(trunc) (-1.625), -1, 0, 0, 0); check_float ("trunc (1048580.625) == 1048580", FUNC(trunc) (1048580.625L), 1048580L, 0, 0, 0); check_float ("trunc (-1048580.625) == -1048580", FUNC(trunc) (-1048580.625L), -1048580L, 0, 0, 0); check_float ("trunc (8388610.125) == 8388610.0", FUNC(trunc) (8388610.125L), 8388610.0L, 0, 0, 0); check_float ("trunc (-8388610.125) == -8388610.0", FUNC(trunc) (-8388610.125L), -8388610.0L, 0, 0, 0); check_float ("trunc (4294967296.625) == 4294967296.0", FUNC(trunc) (4294967296.625L), 4294967296.0L, 0, 0, 0); check_float ("trunc (-4294967296.625) == -4294967296.0", FUNC(trunc) (-4294967296.625L), -4294967296.0L, 0, 0, 0); print_max_error ("trunc", 0, 0); } static void y0_test (void) { FLOAT s, c; errno = 0; FUNC (sincos) (0, &s, &c); if (errno == ENOSYS) /* Required function not implemented. */ return; FUNC(y0) (1); if (errno == ENOSYS) /* Function not implemented. */ return; /* y0 is the Bessel function of the second kind of order 0 */ init_max_error (); check_float ("y0 (-1.0) == NaN", FUNC(y0) (-1.0), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("y0 (0.0) == -inf", FUNC(y0) (0.0), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_float ("y0 (NaN) == NaN", FUNC(y0) (nan_value), nan_value, 0, 0, 0); check_float ("y0 (inf) == 0", FUNC(y0) (plus_infty), 0, 0, 0, 0); check_float ("y0 (0.1) == -1.5342386513503668441", FUNC(y0) (0.1L), -1.5342386513503668441L, DELTA1614, 0, 0); check_float ("y0 (0.7) == -0.19066492933739506743", FUNC(y0) (0.7L), -0.19066492933739506743L, DELTA1615, 0, 0); check_float ("y0 (1.0) == 0.088256964215676957983", FUNC(y0) (1.0), 0.088256964215676957983L, DELTA1616, 0, 0); check_float ("y0 (1.5) == 0.38244892379775884396", FUNC(y0) (1.5), 0.38244892379775884396L, DELTA1617, 0, 0); check_float ("y0 (2.0) == 0.51037567264974511960", FUNC(y0) (2.0), 0.51037567264974511960L, DELTA1618, 0, 0); check_float ("y0 (8.0) == 0.22352148938756622053", FUNC(y0) (8.0), 0.22352148938756622053L, DELTA1619, 0, 0); check_float ("y0 (10.0) == 0.055671167283599391424", FUNC(y0) (10.0), 0.055671167283599391424L, DELTA1620, 0, 0); print_max_error ("y0", DELTAy0, 0); } static void y1_test (void) { FLOAT s, c; errno = 0; FUNC (sincos) (0, &s, &c); if (errno == ENOSYS) /* Required function not implemented. */ return; FUNC(y1) (1); if (errno == ENOSYS) /* Function not implemented. */ return; /* y1 is the Bessel function of the second kind of order 1 */ init_max_error (); check_float ("y1 (-1.0) == NaN", FUNC(y1) (-1.0), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("y1 (0.0) == -inf", FUNC(y1) (0.0), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_float ("y1 (inf) == 0", FUNC(y1) (plus_infty), 0, 0, 0, 0); check_float ("y1 (NaN) == NaN", FUNC(y1) (nan_value), nan_value, 0, 0, 0); check_float ("y1 (0.1) == -6.4589510947020269877", FUNC(y1) (0.1L), -6.4589510947020269877L, DELTA1625, 0, 0); check_float ("y1 (0.7) == -1.1032498719076333697", FUNC(y1) (0.7L), -1.1032498719076333697L, DELTA1626, 0, 0); check_float ("y1 (1.0) == -0.78121282130028871655", FUNC(y1) (1.0), -0.78121282130028871655L, DELTA1627, 0, 0); check_float ("y1 (1.5) == -0.41230862697391129595", FUNC(y1) (1.5), -0.41230862697391129595L, DELTA1628, 0, 0); check_float ("y1 (2.0) == -0.10703243154093754689", FUNC(y1) (2.0), -0.10703243154093754689L, DELTA1629, 0, 0); check_float ("y1 (8.0) == -0.15806046173124749426", FUNC(y1) (8.0), -0.15806046173124749426L, DELTA1630, 0, 0); check_float ("y1 (10.0) == 0.24901542420695388392", FUNC(y1) (10.0), 0.24901542420695388392L, DELTA1631, 0, 0); print_max_error ("y1", DELTAy1, 0); } static void yn_test (void) { FLOAT s, c; errno = 0; FUNC (sincos) (0, &s, &c); if (errno == ENOSYS) /* Required function not implemented. */ return; FUNC(yn) (1, 1); if (errno == ENOSYS) /* Function not implemented. */ return; /* yn is the Bessel function of the second kind of order n */ init_max_error (); /* yn (0, x) == y0 (x) */ check_float ("yn (0, -1.0) == NaN", FUNC(yn) (0, -1.0), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("yn (0, 0.0) == -inf", FUNC(yn) (0, 0.0), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_float ("yn (0, NaN) == NaN", FUNC(yn) (0, nan_value), nan_value, 0, 0, 0); check_float ("yn (0, inf) == 0", FUNC(yn) (0, plus_infty), 0, 0, 0, 0); check_float ("yn (0, 0.1) == -1.5342386513503668441", FUNC(yn) (0, 0.1L), -1.5342386513503668441L, DELTA1636, 0, 0); check_float ("yn (0, 0.7) == -0.19066492933739506743", FUNC(yn) (0, 0.7L), -0.19066492933739506743L, DELTA1637, 0, 0); check_float ("yn (0, 1.0) == 0.088256964215676957983", FUNC(yn) (0, 1.0), 0.088256964215676957983L, DELTA1638, 0, 0); check_float ("yn (0, 1.5) == 0.38244892379775884396", FUNC(yn) (0, 1.5), 0.38244892379775884396L, DELTA1639, 0, 0); check_float ("yn (0, 2.0) == 0.51037567264974511960", FUNC(yn) (0, 2.0), 0.51037567264974511960L, DELTA1640, 0, 0); check_float ("yn (0, 8.0) == 0.22352148938756622053", FUNC(yn) (0, 8.0), 0.22352148938756622053L, DELTA1641, 0, 0); check_float ("yn (0, 10.0) == 0.055671167283599391424", FUNC(yn) (0, 10.0), 0.055671167283599391424L, DELTA1642, 0, 0); /* yn (1, x) == y1 (x) */ check_float ("yn (1, -1.0) == NaN", FUNC(yn) (1, -1.0), nan_value, 0, 0, INVALID_EXCEPTION); check_float ("yn (1, 0.0) == -inf", FUNC(yn) (1, 0.0), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); check_float ("yn (1, inf) == 0", FUNC(yn) (1, plus_infty), 0, 0, 0, 0); check_float ("yn (1, NaN) == NaN", FUNC(yn) (1, nan_value), nan_value, 0, 0, 0); check_float ("yn (1, 0.1) == -6.4589510947020269877", FUNC(yn) (1, 0.1L), -6.4589510947020269877L, DELTA1647, 0, 0); check_float ("yn (1, 0.7) == -1.1032498719076333697", FUNC(yn) (1, 0.7L), -1.1032498719076333697L, DELTA1648, 0, 0); check_float ("yn (1, 1.0) == -0.78121282130028871655", FUNC(yn) (1, 1.0), -0.78121282130028871655L, DELTA1649, 0, 0); check_float ("yn (1, 1.5) == -0.41230862697391129595", FUNC(yn) (1, 1.5), -0.41230862697391129595L, DELTA1650, 0, 0); check_float ("yn (1, 2.0) == -0.10703243154093754689", FUNC(yn) (1, 2.0), -0.10703243154093754689L, DELTA1651, 0, 0); check_float ("yn (1, 8.0) == -0.15806046173124749426", FUNC(yn) (1, 8.0), -0.15806046173124749426L, DELTA1652, 0, 0); check_float ("yn (1, 10.0) == 0.24901542420695388392", FUNC(yn) (1, 10.0), 0.24901542420695388392L, DELTA1653, 0, 0); /* yn (3, x) */ check_float ("yn (3, inf) == 0", FUNC(yn) (3, plus_infty), 0, 0, 0, 0); check_float ("yn (3, NaN) == NaN", FUNC(yn) (3, nan_value), nan_value, 0, 0, 0); check_float ("yn (3, 0.1) == -5099.3323786129048894", FUNC(yn) (3, 0.1L), -5099.3323786129048894L, DELTA1656, 0, 0); check_float ("yn (3, 0.7) == -15.819479052819633505", FUNC(yn) (3, 0.7L), -15.819479052819633505L, DELTA1657, 0, 0); check_float ("yn (3, 1.0) == -5.8215176059647288478", FUNC(yn) (3, 1.0), -5.8215176059647288478L, 0, 0, 0); check_float ("yn (3, 2.0) == -1.1277837768404277861", FUNC(yn) (3, 2.0), -1.1277837768404277861L, DELTA1659, 0, 0); check_float ("yn (3, 10.0) == -0.25136265718383732978", FUNC(yn) (3, 10.0), -0.25136265718383732978L, DELTA1660, 0, 0); /* yn (10, x) */ check_float ("yn (10, inf) == 0", FUNC(yn) (10, plus_infty), 0, 0, 0, 0); check_float ("yn (10, NaN) == NaN", FUNC(yn) (10, nan_value), nan_value, 0, 0, 0); check_float ("yn (10, 0.1) == -0.11831335132045197885e19", FUNC(yn) (10, 0.1L), -0.11831335132045197885e19L, DELTA1663, 0, 0); check_float ("yn (10, 0.7) == -0.42447194260703866924e10", FUNC(yn) (10, 0.7L), -0.42447194260703866924e10L, DELTA1664, 0, 0); check_float ("yn (10, 1.0) == -0.12161801427868918929e9", FUNC(yn) (10, 1.0), -0.12161801427868918929e9L, DELTA1665, 0, 0); check_float ("yn (10, 2.0) == -129184.54220803928264", FUNC(yn) (10, 2.0), -129184.54220803928264L, DELTA1666, 0, 0); check_float ("yn (10, 10.0) == -0.35981415218340272205", FUNC(yn) (10, 10.0), -0.35981415218340272205L, DELTA1667, 0, 0); print_max_error ("yn", DELTAyn, 0); } static void initialize (void) { plus_zero = 0.0; nan_value = plus_zero / plus_zero; /* Suppress GCC warning */ minus_zero = FUNC(copysign) (0.0, -1.0); plus_infty = CHOOSE (HUGE_VALL, HUGE_VAL, HUGE_VALF, HUGE_VALL, HUGE_VAL, HUGE_VALF); minus_infty = CHOOSE (-HUGE_VALL, -HUGE_VAL, -HUGE_VALF, -HUGE_VALL, -HUGE_VAL, -HUGE_VALF); (void) &plus_zero; (void) &nan_value; (void) &minus_zero; (void) &plus_infty; (void) &minus_infty; /* Clear all exceptions. From now on we must not get random exceptions. */ feclearexcept (FE_ALL_EXCEPT); } #if 0 /* XXX scp XXX */ /* Definitions of arguments for argp functions. */ static const struct argp_option options[] = { { "verbose", 'v', "NUMBER", 0, "Level of verbosity (0..3)"}, { "ulps-file", 'u', NULL, 0, "Output ulps to file ULPs"}, { "no-max-error", 'f', NULL, 0, "Don't output maximal errors of functions"}, { "no-points", 'p', NULL, 0, "Don't output results of functions invocations"}, { "ignore-max-ulp", 'i', "yes/no", 0, "Ignore given maximal errors"}, { NULL, 0, NULL, 0, NULL } }; /* Short description of program. */ static const char doc[] = "Math test suite: " TEST_MSG ; /* Prototype for option handler. */ static error_t parse_opt (int key, char *arg, struct argp_state *state); /* Data structure to communicate with argp functions. */ static struct argp argp = { options, parse_opt, NULL, doc, }; /* Handle program arguments. */ static error_t parse_opt (int key, char *arg, struct argp_state *state) { switch (key) { case 'f': output_max_error = 0; break; case 'i': if (strcmp (arg, "yes") == 0) ignore_max_ulp = 1; else if (strcmp (arg, "no") == 0) ignore_max_ulp = 0; break; case 'p': output_points = 0; break; case 'u': output_ulps = 1; break; case 'v': if (optarg) verbose = (unsigned int) strtoul (optarg, NULL, 0); else verbose = 3; break; default: return ARGP_ERR_UNKNOWN; } return 0; } #endif #if 0 /* function to check our ulp calculation. */ void check_ulp (void) { int i; FLOAT u, diff, ulp; /* This gives one ulp. */ u = FUNC(nextafter) (10, 20); check_equal (10.0, u, 1, &diff, &ulp); printf ("One ulp: % .4" PRINTF_NEXPR "\n", ulp); /* This gives one more ulp. */ u = FUNC(nextafter) (u, 20); check_equal (10.0, u, 2, &diff, &ulp); printf ("two ulp: % .4" PRINTF_NEXPR "\n", ulp); /* And now calculate 100 ulp. */ for (i = 2; i < 100; i++) u = FUNC(nextafter) (u, 20); check_equal (10.0, u, 100, &diff, &ulp); printf ("100 ulp: % .4" PRINTF_NEXPR "\n", ulp); } #endif int main (int argc, char **argv) { #if 0 /* XXX scp XXX */ int remaining; #endif verbose = 1; output_ulps = 0; output_max_error = 1; output_points = 1; /* XXX set to 0 for releases. */ ignore_max_ulp = 0; #if 0 /* XXX scp XXX */ /* Parse and process arguments. */ argp_parse (&argp, argc, argv, 0, &remaining, NULL); if (remaining != argc) { fprintf (stderr, "wrong number of arguments"); argp_help (&argp, stdout, ARGP_HELP_SEE, program_invocation_short_name); exit (EXIT_FAILURE); } #endif if (output_ulps) { ulps_file = fopen ("ULPs", "a"); if (ulps_file == NULL) { perror ("can't open file `ULPs' for writing: "); exit (1); } } initialize (); printf (TEST_MSG); #if 0 check_ulp (); #endif /* Keep the tests a wee bit ordered (according to ISO C99). */ /* Classification macros: */ fpclassify_test (); isfinite_test (); isnormal_test (); signbit_test (); /* Trigonometric functions: */ acos_test (); asin_test (); atan_test (); atan2_test (); cos_test (); sin_test (); sincos_test (); tan_test (); /* Hyperbolic functions: */ acosh_test (); asinh_test (); atanh_test (); cosh_test (); sinh_test (); tanh_test (); /* Exponential and logarithmic functions: */ exp_test (); #if 0 /* XXX scp XXX */ exp10_test (); #endif exp2_test (); expm1_test (); frexp_test (); ldexp_test (); log_test (); log10_test (); log1p_test (); log2_test (); logb_test (); modf_test (); ilogb_test (); scalbn_test (); scalbln_test (); /* Power and absolute value functions: */ cbrt_test (); fabs_test (); hypot_test (); pow_test (); sqrt_test (); /* Error and gamma functions: */ erf_test (); erfc_test (); gamma_test (); lgamma_test (); tgamma_test (); /* Nearest integer functions: */ ceil_test (); floor_test (); nearbyint_test (); rint_test (); lrint_test (); llrint_test (); round_test (); lround_test (); llround_test (); trunc_test (); /* Remainder functions: */ fmod_test (); remainder_test (); remquo_test (); /* Manipulation functions: */ copysign_test (); nextafter_test (); #if 0 /* XXX scp XXX */ nexttoward_test (); #endif /* maximum, minimum and positive difference functions */ fdim_test (); fmax_test (); fmin_test (); /* Multiply and add: */ fma_test (); #if 0 /* XXX scp XXX */ /* Complex functions: */ cabs_test (); cacos_test (); cacosh_test (); carg_test (); casin_test (); casinh_test (); catan_test (); catanh_test (); ccos_test (); ccosh_test (); cexp_test (); cimag_test (); clog10_test (); clog_test (); conj_test (); cpow_test (); cproj_test (); creal_test (); csin_test (); csinh_test (); csqrt_test (); ctan_test (); ctanh_test (); #endif /* Bessel functions: */ j0_test (); j1_test (); jn_test (); y0_test (); y1_test (); yn_test (); if (output_ulps) fclose (ulps_file); printf ("\nTest suite completed:\n"); printf (" %d test cases plus %d tests for exception flags executed.\n", noTests, noExcTests); if (noXFails) printf (" %d expected failures occurred.\n", noXFails); if (noXPasses) printf (" %d unexpected passes occurred.\n", noXPasses); if (noErrors) { printf (" %d errors occurred.\n", noErrors); return 1; } printf (" All tests passed successfully.\n"); return 0; } /* * Local Variables: * mode:c * End: */ openlibm-0.5.0/test/test-double.c000066400000000000000000000024561266752446200167200ustar00rootroot00000000000000/* Copyright (C) 1997, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Andreas Jaeger , 1997. 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #define FUNC(function) function #define FLOAT double #define TEST_MSG "testing double (without inline functions)\n" #define MATHCONST(x) x #define CHOOSE(Clongdouble,Cdouble,Cfloat,Cinlinelongdouble,Cinlinedouble,Cinlinefloat) Cdouble #define PRINTF_EXPR "e" #define PRINTF_XEXPR "a" #define PRINTF_NEXPR "f" #define TEST_DOUBLE 1 #ifndef __NO_MATH_INLINES # define __NO_MATH_INLINES #endif #include "libm-test.c" openlibm-0.5.0/test/test-float.c000066400000000000000000000024571266752446200165540ustar00rootroot00000000000000/* Copyright (C) 1997, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Andreas Jaeger , 1997. 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #define FUNC(function) function ## f #define FLOAT float #define TEST_MSG "testing float (without inline functions)\n" #define MATHCONST(x) x #define CHOOSE(Clongdouble,Cdouble,Cfloat,Cinlinelongdouble,Cinlinedouble,Cinlinefloat) Cfloat #define PRINTF_EXPR "e" #define PRINTF_XEXPR "a" #define PRINTF_NEXPR "f" #define TEST_FLOAT 1 #ifndef __NO_MATH_INLINES # define __NO_MATH_INLINES #endif #include "libm-test.c"