Path: blob/master/src/java.base/share/native/libfdlibm/k_standard.c
41149 views
/*1* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#include "fdlibm.h"26#include <errno.h>2728#ifndef _USE_WRITE29#include <stdio.h> /* fputs(), stderr */30#define WRITE2(u,v) fputs(u, stderr)31#else /* !defined(_USE_WRITE) */32#include <unistd.h> /* write */33#define WRITE2(u,v) write(2, u, v)34#undef fflush35#endif /* !defined(_USE_WRITE) */3637static double zero = 0.0; /* used as const */3839/*40* Standard conformance (non-IEEE) on exception cases.41* Mapping:42* 1 -- acos(|x|>1)43* 2 -- asin(|x|>1)44* 3 -- atan2(+-0,+-0)45* 4 -- hypot overflow46* 5 -- cosh overflow47* 6 -- exp overflow48* 7 -- exp underflow49* 8 -- y0(0)50* 9 -- y0(-ve)51* 10-- y1(0)52* 11-- y1(-ve)53* 12-- yn(0)54* 13-- yn(-ve)55* 14-- lgamma(finite) overflow56* 15-- lgamma(-integer)57* 16-- log(0)58* 17-- log(x<0)59* 18-- log10(0)60* 19-- log10(x<0)61* 20-- pow(0.0,0.0)62* 21-- pow(x,y) overflow63* 22-- pow(x,y) underflow64* 23-- pow(0,negative)65* 24-- pow(neg,non-integral)66* 25-- sinh(finite) overflow67* 26-- sqrt(negative)68* 27-- fmod(x,0)69* 28-- remainder(x,0)70* 29-- acosh(x<1)71* 30-- atanh(|x|>1)72* 31-- atanh(|x|=1)73* 32-- scalb overflow74* 33-- scalb underflow75* 34-- j0(|x|>X_TLOSS)76* 35-- y0(x>X_TLOSS)77* 36-- j1(|x|>X_TLOSS)78* 37-- y1(x>X_TLOSS)79* 38-- jn(|x|>X_TLOSS, n)80* 39-- yn(x>X_TLOSS, n)81* 40-- gamma(finite) overflow82* 41-- gamma(-integer)83* 42-- pow(NaN,0.0)84*/858687#ifdef __STDC__88double __kernel_standard(double x, double y, int type)89#else90double __kernel_standard(x,y,type)91double x,y; int type;92#endif93{94struct exception exc;95#ifndef HUGE_VAL /* this is the only routine that uses HUGE_VAL */96#define HUGE_VAL inf97double inf = 0.0;9899__HI(inf) = 0x7ff00000; /* set inf to infinite */100#endif101102#ifdef _USE_WRITE103(void) fflush(stdout);104#endif105exc.arg1 = x;106exc.arg2 = y;107switch(type) {108case 1:109/* acos(|x|>1) */110exc.type = DOMAIN;111exc.name = "acos";112exc.retval = zero;113if (_LIB_VERSION == _POSIX_)114errno = EDOM;115else if (!matherr(&exc)) {116if(_LIB_VERSION == _SVID_) {117(void) WRITE2("acos: DOMAIN error\n", 19);118}119errno = EDOM;120}121break;122case 2:123/* asin(|x|>1) */124exc.type = DOMAIN;125exc.name = "asin";126exc.retval = zero;127if(_LIB_VERSION == _POSIX_)128errno = EDOM;129else if (!matherr(&exc)) {130if(_LIB_VERSION == _SVID_) {131(void) WRITE2("asin: DOMAIN error\n", 19);132}133errno = EDOM;134}135break;136case 3:137/* atan2(+-0,+-0) */138exc.arg1 = y;139exc.arg2 = x;140exc.type = DOMAIN;141exc.name = "atan2";142exc.retval = zero;143if(_LIB_VERSION == _POSIX_)144errno = EDOM;145else if (!matherr(&exc)) {146if(_LIB_VERSION == _SVID_) {147(void) WRITE2("atan2: DOMAIN error\n", 20);148}149errno = EDOM;150}151break;152case 4:153/* hypot(finite,finite) overflow */154exc.type = OVERFLOW;155exc.name = "hypot";156if (_LIB_VERSION == _SVID_)157exc.retval = HUGE;158else159exc.retval = HUGE_VAL;160if (_LIB_VERSION == _POSIX_)161errno = ERANGE;162else if (!matherr(&exc)) {163errno = ERANGE;164}165break;166case 5:167/* cosh(finite) overflow */168exc.type = OVERFLOW;169exc.name = "cosh";170if (_LIB_VERSION == _SVID_)171exc.retval = HUGE;172else173exc.retval = HUGE_VAL;174if (_LIB_VERSION == _POSIX_)175errno = ERANGE;176else if (!matherr(&exc)) {177errno = ERANGE;178}179break;180case 6:181/* exp(finite) overflow */182exc.type = OVERFLOW;183exc.name = "exp";184if (_LIB_VERSION == _SVID_)185exc.retval = HUGE;186else187exc.retval = HUGE_VAL;188if (_LIB_VERSION == _POSIX_)189errno = ERANGE;190else if (!matherr(&exc)) {191errno = ERANGE;192}193break;194case 7:195/* exp(finite) underflow */196exc.type = UNDERFLOW;197exc.name = "exp";198exc.retval = zero;199if (_LIB_VERSION == _POSIX_)200errno = ERANGE;201else if (!matherr(&exc)) {202errno = ERANGE;203}204break;205case 8:206/* y0(0) = -inf */207exc.type = DOMAIN; /* should be SING for IEEE */208exc.name = "y0";209if (_LIB_VERSION == _SVID_)210exc.retval = -HUGE;211else212exc.retval = -HUGE_VAL;213if (_LIB_VERSION == _POSIX_)214errno = EDOM;215else if (!matherr(&exc)) {216if (_LIB_VERSION == _SVID_) {217(void) WRITE2("y0: DOMAIN error\n", 17);218}219errno = EDOM;220}221break;222case 9:223/* y0(x<0) = NaN */224exc.type = DOMAIN;225exc.name = "y0";226if (_LIB_VERSION == _SVID_)227exc.retval = -HUGE;228else229exc.retval = -HUGE_VAL;230if (_LIB_VERSION == _POSIX_)231errno = EDOM;232else if (!matherr(&exc)) {233if (_LIB_VERSION == _SVID_) {234(void) WRITE2("y0: DOMAIN error\n", 17);235}236errno = EDOM;237}238break;239case 10:240/* y1(0) = -inf */241exc.type = DOMAIN; /* should be SING for IEEE */242exc.name = "y1";243if (_LIB_VERSION == _SVID_)244exc.retval = -HUGE;245else246exc.retval = -HUGE_VAL;247if (_LIB_VERSION == _POSIX_)248errno = EDOM;249else if (!matherr(&exc)) {250if (_LIB_VERSION == _SVID_) {251(void) WRITE2("y1: DOMAIN error\n", 17);252}253errno = EDOM;254}255break;256case 11:257/* y1(x<0) = NaN */258exc.type = DOMAIN;259exc.name = "y1";260if (_LIB_VERSION == _SVID_)261exc.retval = -HUGE;262else263exc.retval = -HUGE_VAL;264if (_LIB_VERSION == _POSIX_)265errno = EDOM;266else if (!matherr(&exc)) {267if (_LIB_VERSION == _SVID_) {268(void) WRITE2("y1: DOMAIN error\n", 17);269}270errno = EDOM;271}272break;273case 12:274/* yn(n,0) = -inf */275exc.type = DOMAIN; /* should be SING for IEEE */276exc.name = "yn";277if (_LIB_VERSION == _SVID_)278exc.retval = -HUGE;279else280exc.retval = -HUGE_VAL;281if (_LIB_VERSION == _POSIX_)282errno = EDOM;283else if (!matherr(&exc)) {284if (_LIB_VERSION == _SVID_) {285(void) WRITE2("yn: DOMAIN error\n", 17);286}287errno = EDOM;288}289break;290case 13:291/* yn(x<0) = NaN */292exc.type = DOMAIN;293exc.name = "yn";294if (_LIB_VERSION == _SVID_)295exc.retval = -HUGE;296else297exc.retval = -HUGE_VAL;298if (_LIB_VERSION == _POSIX_)299errno = EDOM;300else if (!matherr(&exc)) {301if (_LIB_VERSION == _SVID_) {302(void) WRITE2("yn: DOMAIN error\n", 17);303}304errno = EDOM;305}306break;307case 14:308/* lgamma(finite) overflow */309exc.type = OVERFLOW;310exc.name = "lgamma";311if (_LIB_VERSION == _SVID_)312exc.retval = HUGE;313else314exc.retval = HUGE_VAL;315if (_LIB_VERSION == _POSIX_)316errno = ERANGE;317else if (!matherr(&exc)) {318errno = ERANGE;319}320break;321case 15:322/* lgamma(-integer) or lgamma(0) */323exc.type = SING;324exc.name = "lgamma";325if (_LIB_VERSION == _SVID_)326exc.retval = HUGE;327else328exc.retval = HUGE_VAL;329if (_LIB_VERSION == _POSIX_)330errno = EDOM;331else if (!matherr(&exc)) {332if (_LIB_VERSION == _SVID_) {333(void) WRITE2("lgamma: SING error\n", 19);334}335errno = EDOM;336}337break;338case 16:339/* log(0) */340exc.type = SING;341exc.name = "log";342if (_LIB_VERSION == _SVID_)343exc.retval = -HUGE;344else345exc.retval = -HUGE_VAL;346if (_LIB_VERSION == _POSIX_)347errno = ERANGE;348else if (!matherr(&exc)) {349if (_LIB_VERSION == _SVID_) {350(void) WRITE2("log: SING error\n", 16);351}352errno = EDOM;353}354break;355case 17:356/* log(x<0) */357exc.type = DOMAIN;358exc.name = "log";359if (_LIB_VERSION == _SVID_)360exc.retval = -HUGE;361else362exc.retval = -HUGE_VAL;363if (_LIB_VERSION == _POSIX_)364errno = EDOM;365else if (!matherr(&exc)) {366if (_LIB_VERSION == _SVID_) {367(void) WRITE2("log: DOMAIN error\n", 18);368}369errno = EDOM;370}371break;372case 18:373/* log10(0) */374exc.type = SING;375exc.name = "log10";376if (_LIB_VERSION == _SVID_)377exc.retval = -HUGE;378else379exc.retval = -HUGE_VAL;380if (_LIB_VERSION == _POSIX_)381errno = ERANGE;382else if (!matherr(&exc)) {383if (_LIB_VERSION == _SVID_) {384(void) WRITE2("log10: SING error\n", 18);385}386errno = EDOM;387}388break;389case 19:390/* log10(x<0) */391exc.type = DOMAIN;392exc.name = "log10";393if (_LIB_VERSION == _SVID_)394exc.retval = -HUGE;395else396exc.retval = -HUGE_VAL;397if (_LIB_VERSION == _POSIX_)398errno = EDOM;399else if (!matherr(&exc)) {400if (_LIB_VERSION == _SVID_) {401(void) WRITE2("log10: DOMAIN error\n", 20);402}403errno = EDOM;404}405break;406case 20:407/* pow(0.0,0.0) */408/* error only if _LIB_VERSION == _SVID_ */409exc.type = DOMAIN;410exc.name = "pow";411exc.retval = zero;412if (_LIB_VERSION != _SVID_) exc.retval = 1.0;413else if (!matherr(&exc)) {414(void) WRITE2("pow(0,0): DOMAIN error\n", 23);415errno = EDOM;416}417break;418case 21:419/* pow(x,y) overflow */420exc.type = OVERFLOW;421exc.name = "pow";422if (_LIB_VERSION == _SVID_) {423exc.retval = HUGE;424y *= 0.5;425if(x<zero&&rint(y)!=y) exc.retval = -HUGE;426} else {427exc.retval = HUGE_VAL;428y *= 0.5;429if(x<zero&&rint(y)!=y) exc.retval = -HUGE_VAL;430}431if (_LIB_VERSION == _POSIX_)432errno = ERANGE;433else if (!matherr(&exc)) {434errno = ERANGE;435}436break;437case 22:438/* pow(x,y) underflow */439exc.type = UNDERFLOW;440exc.name = "pow";441exc.retval = zero;442if (_LIB_VERSION == _POSIX_)443errno = ERANGE;444else if (!matherr(&exc)) {445errno = ERANGE;446}447break;448case 23:449/* 0**neg */450exc.type = DOMAIN;451exc.name = "pow";452if (_LIB_VERSION == _SVID_)453exc.retval = zero;454else455exc.retval = -HUGE_VAL;456if (_LIB_VERSION == _POSIX_)457errno = EDOM;458else if (!matherr(&exc)) {459if (_LIB_VERSION == _SVID_) {460(void) WRITE2("pow(0,neg): DOMAIN error\n", 25);461}462errno = EDOM;463}464break;465case 24:466/* neg**non-integral */467exc.type = DOMAIN;468exc.name = "pow";469if (_LIB_VERSION == _SVID_)470exc.retval = zero;471else472exc.retval = zero/zero; /* X/Open allow NaN */473if (_LIB_VERSION == _POSIX_)474errno = EDOM;475else if (!matherr(&exc)) {476if (_LIB_VERSION == _SVID_) {477(void) WRITE2("neg**non-integral: DOMAIN error\n", 32);478}479errno = EDOM;480}481break;482case 25:483/* sinh(finite) overflow */484exc.type = OVERFLOW;485exc.name = "sinh";486if (_LIB_VERSION == _SVID_)487exc.retval = ( (x>zero) ? HUGE : -HUGE);488else489exc.retval = ( (x>zero) ? HUGE_VAL : -HUGE_VAL);490if (_LIB_VERSION == _POSIX_)491errno = ERANGE;492else if (!matherr(&exc)) {493errno = ERANGE;494}495break;496case 26:497/* sqrt(x<0) */498exc.type = DOMAIN;499exc.name = "sqrt";500if (_LIB_VERSION == _SVID_)501exc.retval = zero;502else503exc.retval = zero/zero;504if (_LIB_VERSION == _POSIX_)505errno = EDOM;506else if (!matherr(&exc)) {507if (_LIB_VERSION == _SVID_) {508(void) WRITE2("sqrt: DOMAIN error\n", 19);509}510errno = EDOM;511}512break;513case 27:514/* fmod(x,0) */515exc.type = DOMAIN;516exc.name = "fmod";517if (_LIB_VERSION == _SVID_)518exc.retval = x;519else520exc.retval = zero/zero;521if (_LIB_VERSION == _POSIX_)522errno = EDOM;523else if (!matherr(&exc)) {524if (_LIB_VERSION == _SVID_) {525(void) WRITE2("fmod: DOMAIN error\n", 20);526}527errno = EDOM;528}529break;530case 28:531/* remainder(x,0) */532exc.type = DOMAIN;533exc.name = "remainder";534exc.retval = zero/zero;535if (_LIB_VERSION == _POSIX_)536errno = EDOM;537else if (!matherr(&exc)) {538if (_LIB_VERSION == _SVID_) {539(void) WRITE2("remainder: DOMAIN error\n", 24);540}541errno = EDOM;542}543break;544case 29:545/* acosh(x<1) */546exc.type = DOMAIN;547exc.name = "acosh";548exc.retval = zero/zero;549if (_LIB_VERSION == _POSIX_)550errno = EDOM;551else if (!matherr(&exc)) {552if (_LIB_VERSION == _SVID_) {553(void) WRITE2("acosh: DOMAIN error\n", 20);554}555errno = EDOM;556}557break;558case 30:559/* atanh(|x|>1) */560exc.type = DOMAIN;561exc.name = "atanh";562exc.retval = zero/zero;563if (_LIB_VERSION == _POSIX_)564errno = EDOM;565else if (!matherr(&exc)) {566if (_LIB_VERSION == _SVID_) {567(void) WRITE2("atanh: DOMAIN error\n", 20);568}569errno = EDOM;570}571break;572case 31:573/* atanh(|x|=1) */574exc.type = SING;575exc.name = "atanh";576exc.retval = x/zero; /* sign(x)*inf */577if (_LIB_VERSION == _POSIX_)578errno = EDOM;579else if (!matherr(&exc)) {580if (_LIB_VERSION == _SVID_) {581(void) WRITE2("atanh: SING error\n", 18);582}583errno = EDOM;584}585break;586case 32:587/* scalb overflow; SVID also returns +-HUGE_VAL */588exc.type = OVERFLOW;589exc.name = "scalb";590exc.retval = x > zero ? HUGE_VAL : -HUGE_VAL;591if (_LIB_VERSION == _POSIX_)592errno = ERANGE;593else if (!matherr(&exc)) {594errno = ERANGE;595}596break;597case 33:598/* scalb underflow */599exc.type = UNDERFLOW;600exc.name = "scalb";601exc.retval = copysign(zero,x);602if (_LIB_VERSION == _POSIX_)603errno = ERANGE;604else if (!matherr(&exc)) {605errno = ERANGE;606}607break;608case 34:609/* j0(|x|>X_TLOSS) */610exc.type = TLOSS;611exc.name = "j0";612exc.retval = zero;613if (_LIB_VERSION == _POSIX_)614errno = ERANGE;615else if (!matherr(&exc)) {616if (_LIB_VERSION == _SVID_) {617(void) WRITE2(exc.name, 2);618(void) WRITE2(": TLOSS error\n", 14);619}620errno = ERANGE;621}622break;623case 35:624/* y0(x>X_TLOSS) */625exc.type = TLOSS;626exc.name = "y0";627exc.retval = zero;628if (_LIB_VERSION == _POSIX_)629errno = ERANGE;630else if (!matherr(&exc)) {631if (_LIB_VERSION == _SVID_) {632(void) WRITE2(exc.name, 2);633(void) WRITE2(": TLOSS error\n", 14);634}635errno = ERANGE;636}637break;638case 36:639/* j1(|x|>X_TLOSS) */640exc.type = TLOSS;641exc.name = "j1";642exc.retval = zero;643if (_LIB_VERSION == _POSIX_)644errno = ERANGE;645else if (!matherr(&exc)) {646if (_LIB_VERSION == _SVID_) {647(void) WRITE2(exc.name, 2);648(void) WRITE2(": TLOSS error\n", 14);649}650errno = ERANGE;651}652break;653case 37:654/* y1(x>X_TLOSS) */655exc.type = TLOSS;656exc.name = "y1";657exc.retval = zero;658if (_LIB_VERSION == _POSIX_)659errno = ERANGE;660else if (!matherr(&exc)) {661if (_LIB_VERSION == _SVID_) {662(void) WRITE2(exc.name, 2);663(void) WRITE2(": TLOSS error\n", 14);664}665errno = ERANGE;666}667break;668case 38:669/* jn(|x|>X_TLOSS) */670exc.type = TLOSS;671exc.name = "jn";672exc.retval = zero;673if (_LIB_VERSION == _POSIX_)674errno = ERANGE;675else if (!matherr(&exc)) {676if (_LIB_VERSION == _SVID_) {677(void) WRITE2(exc.name, 2);678(void) WRITE2(": TLOSS error\n", 14);679}680errno = ERANGE;681}682break;683case 39:684/* yn(x>X_TLOSS) */685exc.type = TLOSS;686exc.name = "yn";687exc.retval = zero;688if (_LIB_VERSION == _POSIX_)689errno = ERANGE;690else if (!matherr(&exc)) {691if (_LIB_VERSION == _SVID_) {692(void) WRITE2(exc.name, 2);693(void) WRITE2(": TLOSS error\n", 14);694}695errno = ERANGE;696}697break;698case 40:699/* gamma(finite) overflow */700exc.type = OVERFLOW;701exc.name = "gamma";702if (_LIB_VERSION == _SVID_)703exc.retval = HUGE;704else705exc.retval = HUGE_VAL;706if (_LIB_VERSION == _POSIX_)707errno = ERANGE;708else if (!matherr(&exc)) {709errno = ERANGE;710}711break;712case 41:713/* gamma(-integer) or gamma(0) */714exc.type = SING;715exc.name = "gamma";716if (_LIB_VERSION == _SVID_)717exc.retval = HUGE;718else719exc.retval = HUGE_VAL;720if (_LIB_VERSION == _POSIX_)721errno = EDOM;722else if (!matherr(&exc)) {723if (_LIB_VERSION == _SVID_) {724(void) WRITE2("gamma: SING error\n", 18);725}726errno = EDOM;727}728break;729case 42:730/* pow(NaN,0.0) */731/* error only if _LIB_VERSION == _SVID_ & _XOPEN_ */732exc.type = DOMAIN;733exc.name = "pow";734exc.retval = x;735if (_LIB_VERSION == _IEEE_ ||736_LIB_VERSION == _POSIX_) exc.retval = 1.0;737else if (!matherr(&exc)) {738errno = EDOM;739}740break;741default:742exc.retval = zero / zero;743errno = EINVAL;744break;745}746return exc.retval;747}748749750