mirror of
https://github.com/2003scape/deep-c-rsc.git
synced 2024-03-22 05:49:51 -04:00
352 lines
9.3 KiB
C
352 lines
9.3 KiB
C
|
/*
|
||
|
* @(#) $(JCGO)/include/jcgofp.c --
|
||
|
* a part of the JCGO runtime subsystem.
|
||
|
**
|
||
|
* Project: JCGO (http://www.ivmaisoft.com/jcgo/)
|
||
|
* Copyright (C) 2001-2012 Ivan Maidanski <ivmai@ivmaisoft.com>
|
||
|
* All rights reserved.
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* This file is compiled together with the files produced by the JCGO
|
||
|
* translator (do not include and/or compile this file directly).
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* Used control macros: FPINIT, JCGO_FASTMATH, JCGO_FPFAST, JCGO_LONGDBL,
|
||
|
* JCGO_MATHEXT, JCGO_NOFP, JCGO_REVFLOAT.
|
||
|
* Macros for tuning: FPINIT.
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* This is free software; you can redistribute it and/or modify
|
||
|
* it under the terms of the GNU General Public License as published by
|
||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||
|
* any later version.
|
||
|
**
|
||
|
* This software 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
|
||
|
* General Public License (GPL) for more details.
|
||
|
**
|
||
|
* Linking this library statically or dynamically with other modules is
|
||
|
* making a combined work based on this library. Thus, the terms and
|
||
|
* conditions of the GNU General Public License cover the whole
|
||
|
* combination.
|
||
|
**
|
||
|
* As a special exception, the copyright holders of this library give you
|
||
|
* permission to link this library with independent modules to produce an
|
||
|
* executable, regardless of the license terms of these independent
|
||
|
* modules, and to copy and distribute the resulting executable under
|
||
|
* terms of your choice, provided that you also meet, for each linked
|
||
|
* independent module, the terms and conditions of the license of that
|
||
|
* module. An independent module is a module which is not derived from
|
||
|
* or based on this library. If you modify this library, you may extend
|
||
|
* this exception to your version of the library, but you are not
|
||
|
* obligated to do so. If you do not wish to do so, delete this
|
||
|
* exception statement from your version.
|
||
|
*/
|
||
|
|
||
|
#ifdef JCGO_VER
|
||
|
|
||
|
#ifndef JCGO_NOFP
|
||
|
|
||
|
STATICDATA jdouble jcgo_fpInf;
|
||
|
|
||
|
STATICDATA jdouble jcgo_fpNaN;
|
||
|
|
||
|
#ifdef JCGO_SEPARATED
|
||
|
|
||
|
jdouble jcgo_fpZero;
|
||
|
|
||
|
jfloat jcgo_fpZeroF;
|
||
|
|
||
|
#endif /* JCGO_SEPARATED */
|
||
|
|
||
|
#ifndef jcgo_dblWordSwap
|
||
|
#ifdef JCGO_NATCLASS_java_lang_VMDouble
|
||
|
STATICDATA int jcgo_dblWordSwap = 0;
|
||
|
#else
|
||
|
#define jcgo_dblWordSwap 0
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
#endif /* ! JCGO_NOFP */
|
||
|
|
||
|
JCGO_NOSEP_INLINE void JCGO_INLFRW_FASTCALL jcgo_initFP( void )
|
||
|
{
|
||
|
#ifdef FPINIT
|
||
|
FPINIT;
|
||
|
#endif
|
||
|
#ifndef JCGO_NOFP
|
||
|
jcgo_fpZero = (jdouble)0.0;
|
||
|
jcgo_fpZeroF = (jfloat)0.0;
|
||
|
#ifdef INFINITY
|
||
|
jcgo_fpInf = (jdouble)INFINITY;
|
||
|
#else
|
||
|
#ifdef HUGE_VAL
|
||
|
jcgo_fpInf = (jdouble)HUGE_VAL;
|
||
|
#else
|
||
|
jcgo_fpInf = (jdouble)1.0 / *(volatile jdouble *)&jcgo_fpZero;
|
||
|
#endif
|
||
|
#endif
|
||
|
#ifdef NAN
|
||
|
jcgo_fpNaN = (jdouble)NAN;
|
||
|
#else
|
||
|
jcgo_fpNaN = *(volatile jdouble *)&jcgo_fpInf *
|
||
|
*(volatile jdouble *)&jcgo_fpZero;
|
||
|
#endif
|
||
|
#ifndef jcgo_dblWordSwap
|
||
|
if ((sizeof(int) << 1) <= sizeof(double))
|
||
|
{
|
||
|
double minusOne = -1.0;
|
||
|
if ((*((volatile signed char *)&minusOne + ((sizeof(double) >> 1) - 1)) |
|
||
|
*((volatile signed char *)&minusOne + (sizeof(double) >> 1))) < 0)
|
||
|
jcgo_dblWordSwap = 1;
|
||
|
}
|
||
|
#endif
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
#ifdef JCGO_NOFP
|
||
|
|
||
|
JCGO_NOSEP_STATIC jdouble CFASTCALL jcgo_fdiv( jdouble d1, jdouble d2 )
|
||
|
{
|
||
|
if (JCGO_EXPECT_FALSE(d2 == (jdouble)0))
|
||
|
return d1 < (jdouble)0 ? (jdouble)((jlong)(~(((u_jlong)-1L) >> 1))) :
|
||
|
d1 > (jdouble)0 ? (jdouble)(jlong)(((u_jlong)-1L) >> 1) : d2;
|
||
|
if (JCGO_EXPECT_FALSE(d2 == (jdouble)-1) &&
|
||
|
JCGO_EXPECT_FALSE(d1 == (jdouble)((jlong)(~(((u_jlong)-1L) >> 1)))))
|
||
|
return (jdouble)(jlong)(((u_jlong)-1L) >> 1);
|
||
|
return d1 / d2;
|
||
|
}
|
||
|
|
||
|
JCGO_NOSEP_STATIC jfloat CFASTCALL jcgo_fdivf( jfloat f1, jfloat f2 )
|
||
|
{
|
||
|
if (JCGO_EXPECT_FALSE(f2 == (jfloat)0))
|
||
|
return f1 < (jfloat)0 ? (jfloat)((jint)(~(((u_jint)-1) >> 1))) :
|
||
|
f1 > (jfloat)0 ? (jfloat)(((u_jint)-1) >> 1) : f2;
|
||
|
if (JCGO_EXPECT_FALSE(f2 == (jfloat)-1) &&
|
||
|
JCGO_EXPECT_FALSE(f1 == (jfloat)((jint)(~(((u_jint)-1) >> 1)))))
|
||
|
return (jfloat)(((u_jint)-1) >> 1);
|
||
|
return f1 / f2;
|
||
|
}
|
||
|
|
||
|
#else /* JCGO_NOFP */
|
||
|
|
||
|
JCGO_NOSEP_EXTRASTATIC jint CFASTCALL jcgo_jfloat2jint( jfloat f )
|
||
|
{
|
||
|
if (JCGO_FP_NOTNANF(f))
|
||
|
return f < (jfloat)0.0 ?
|
||
|
(JCGO_EXPECT_FALSE(f <= (jfloat)((jint)(~(((u_jint)-1) >> 1)))) ?
|
||
|
(jint)(~(((u_jint)-1) >> 1)) : (jint)(-JCGO_FP_FLOORF(-f))) :
|
||
|
JCGO_EXPECT_TRUE(f < -(jfloat)(-(jint)(((u_jint)-1) >> 1))) ?
|
||
|
(jint)JCGO_FP_FLOORF(f) : (jint)(((u_jint)-1) >> 1);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
JCGO_NOSEP_EXTRASTATIC jlong CFASTCALL jcgo_jfloat2jlong( jfloat f )
|
||
|
{
|
||
|
if (JCGO_FP_NOTNANF(f))
|
||
|
return f < (jfloat)0.0 ?
|
||
|
(JCGO_EXPECT_FALSE(f <= (jfloat)((jlong)(~(((u_jlong)-1L) >> 1)))) ?
|
||
|
(jlong)(~(((u_jlong)-1L) >> 1)) : (jlong)(-JCGO_FP_FLOORF(-f))) :
|
||
|
JCGO_EXPECT_TRUE(f < -(jfloat)(-(jlong)(((u_jlong)-1L) >> 1))) ?
|
||
|
(jlong)JCGO_FP_FLOORF(f) : (jlong)(((u_jlong)-1L) >> 1);
|
||
|
return (jlong)0L;
|
||
|
}
|
||
|
|
||
|
JCGO_NOSEP_EXTRASTATIC jint CFASTCALL jcgo_jdouble2jint( jdouble d )
|
||
|
{
|
||
|
if (JCGO_FP_NOTNAN(d))
|
||
|
return d < (jdouble)0.0 ?
|
||
|
(JCGO_EXPECT_FALSE(d <= (jdouble)((jint)(~(((u_jint)-1) >> 1)))) ?
|
||
|
(jint)(~(((u_jint)-1) >> 1)) : (jint)(-JCGO_FP_FLOOR(-d))) :
|
||
|
JCGO_EXPECT_TRUE(d < (jdouble)(jint)(((u_jint)-1) >> 1)) ?
|
||
|
(jint)JCGO_FP_FLOOR(d) : (jint)(((u_jint)-1) >> 1);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
JCGO_NOSEP_EXTRASTATIC jlong CFASTCALL jcgo_jdouble2jlong( jdouble d )
|
||
|
{
|
||
|
if (JCGO_FP_NOTNAN(d))
|
||
|
return d < (jdouble)0.0 ? (JCGO_EXPECT_FALSE(d <=
|
||
|
(jdouble)((jlong)(~(((u_jlong)-1L) >> 1)))) ?
|
||
|
(jlong)(~(((u_jlong)-1L) >> 1)) : (jlong)(-JCGO_FP_FLOOR(-d))) :
|
||
|
JCGO_EXPECT_TRUE(d < -(jdouble)(-(jlong)(((u_jlong)-1L) >> 1))) ?
|
||
|
(jlong)JCGO_FP_FLOOR(d) : (jlong)(((u_jlong)-1L) >> 1);
|
||
|
return (jlong)0L;
|
||
|
}
|
||
|
|
||
|
JCGO_NOSEP_INLINE jfloat JCGO_INLFRW_FASTCALL jcgo_jdouble2jfloat( jdouble d )
|
||
|
{
|
||
|
jfloat f;
|
||
|
f = (jfloat)d;
|
||
|
return f;
|
||
|
}
|
||
|
|
||
|
#ifndef JCGO_FPFAST
|
||
|
|
||
|
JCGO_NOSEP_STATIC int CFASTCALL jcgo_fequal( jdouble d1, jdouble d2 )
|
||
|
{
|
||
|
return d1 == d2 && JCGO_FP_NOTNAN(d1) && JCGO_FP_NOTNAN(d2);
|
||
|
}
|
||
|
|
||
|
JCGO_NOSEP_STATIC int CFASTCALL jcgo_fequalf( jfloat f1, jfloat f2 )
|
||
|
{
|
||
|
return f1 == f2 && JCGO_FP_NOTNANF(f1) && JCGO_FP_NOTNANF(f2);
|
||
|
}
|
||
|
|
||
|
JCGO_NOSEP_STATIC int CFASTCALL jcgo_flessequ( jdouble d1, jdouble d2 )
|
||
|
{
|
||
|
return d1 <= d2 && JCGO_FP_NOTNAN(d1) && JCGO_FP_NOTNAN(d2);
|
||
|
}
|
||
|
|
||
|
JCGO_NOSEP_STATIC int CFASTCALL jcgo_flessequf( jfloat f1, jfloat f2 )
|
||
|
{
|
||
|
return f1 <= f2 && JCGO_FP_NOTNANF(f1) && JCGO_FP_NOTNANF(f2);
|
||
|
}
|
||
|
|
||
|
JCGO_NOSEP_STATIC int CFASTCALL jcgo_flessthan( jdouble d1, jdouble d2 )
|
||
|
{
|
||
|
return d1 < d2 && JCGO_FP_NOTNAN(d1) && JCGO_FP_NOTNAN(d2);
|
||
|
}
|
||
|
|
||
|
JCGO_NOSEP_STATIC int CFASTCALL jcgo_flessthanf( jfloat f1, jfloat f2 )
|
||
|
{
|
||
|
return f1 < f2 && JCGO_FP_NOTNANF(f1) && JCGO_FP_NOTNANF(f2);
|
||
|
}
|
||
|
|
||
|
JCGO_NOSEP_STATIC jdouble CFASTCALL jcgo_fdiv( jdouble d1, jdouble d2 )
|
||
|
{
|
||
|
if (JCGO_EXPECT_FALSE(d2 >= (jdouble)-0.0 && d2 <= (jdouble)0.0))
|
||
|
{
|
||
|
if (d1 == (jdouble)0.0)
|
||
|
return jcgo_fpNaN;
|
||
|
if (JCGO_FP_ZEROISNEG(d2))
|
||
|
d1 = -d1;
|
||
|
return jcgo_fpInf * d1;
|
||
|
}
|
||
|
return d1 / d2;
|
||
|
}
|
||
|
|
||
|
JCGO_NOSEP_STATIC jfloat CFASTCALL jcgo_fdivf( jfloat f1, jfloat f2 )
|
||
|
{
|
||
|
if (JCGO_EXPECT_FALSE(f2 >= (jfloat)-0.0 && f2 <= (jfloat)0.0))
|
||
|
{
|
||
|
if (f1 == (jfloat)0.0)
|
||
|
return (jfloat)jcgo_fpNaN;
|
||
|
if (JCGO_FP_ZEROISNEG(f2))
|
||
|
f1 = -f1;
|
||
|
return (jfloat)jcgo_fpInf * f1;
|
||
|
}
|
||
|
return f1 / f2;
|
||
|
}
|
||
|
|
||
|
#endif /* ! JCGO_FPFAST */
|
||
|
|
||
|
#endif /* ! JCGO_NOFP */
|
||
|
|
||
|
#ifdef JCGO_NOFP
|
||
|
JCGO_NOSEP_INLINE jdouble JCGO_INLFRW_FASTCALL
|
||
|
#else
|
||
|
#ifdef JCGO_FASTMATH
|
||
|
JCGO_NOSEP_INLINE jdouble JCGO_INLFRW_FASTCALL
|
||
|
#else
|
||
|
JCGO_NOSEP_STATIC jdouble CFASTCALL
|
||
|
#endif
|
||
|
#endif
|
||
|
jcgo_fmod( jdouble d1, jdouble d2 )
|
||
|
{
|
||
|
#ifdef JCGO_NOFP
|
||
|
return (u_jlong)(d2 + (jdouble)1) > (u_jlong)1L ?
|
||
|
(jdouble)((jlong)d1 % (jlong)d2) : (jdouble)0;
|
||
|
#else
|
||
|
#ifdef JCGO_FASTMATH
|
||
|
#ifdef JCGO_LONGDBL
|
||
|
return fmodl(d1, d2);
|
||
|
#else
|
||
|
return fmod(d1, d2);
|
||
|
#endif
|
||
|
#else
|
||
|
jdouble d;
|
||
|
if (JCGO_EXPECT_TRUE(d2 != (jdouble)0.0) && JCGO_FP_FINITE(d1))
|
||
|
{
|
||
|
if (JCGO_FP_FINITE(d2))
|
||
|
{
|
||
|
d = d1;
|
||
|
if (d1 < (jdouble)0.0)
|
||
|
d1 = -d1;
|
||
|
if (d2 < (jdouble)0.0)
|
||
|
d2 = -d2;
|
||
|
if (JCGO_EXPECT_TRUE(d1 >= d2))
|
||
|
{
|
||
|
#ifdef JCGO_LONGDBL
|
||
|
d1 = fmodl(d1, d2);
|
||
|
#else
|
||
|
d1 = JCGO_EXPECT_FALSE(d1 < DBL_MIN) ||
|
||
|
(JCGO_EXPECT_FALSE(d2 < DBL_MIN) && d1 <= 1.0) ?
|
||
|
fmod(d1 * ((double)(1L << ((DBL_MANT_DIG - 1) / 2)) *
|
||
|
(1L << (DBL_MANT_DIG / 2))),
|
||
|
d2 * ((double)(1L << ((DBL_MANT_DIG - 1) / 2)) *
|
||
|
(1L << (DBL_MANT_DIG / 2)))) /
|
||
|
((double)(1L << ((DBL_MANT_DIG - 1) / 2)) *
|
||
|
(1L << (DBL_MANT_DIG / 2))) : fmod(d1, d2);
|
||
|
#endif
|
||
|
}
|
||
|
if (d < (jdouble)0.0)
|
||
|
d1 = -d1;
|
||
|
return d1;
|
||
|
}
|
||
|
if (JCGO_FP_NOTNAN(d2))
|
||
|
return d1;
|
||
|
}
|
||
|
return jcgo_fpNaN;
|
||
|
#endif
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
#ifdef JCGO_NOFP
|
||
|
JCGO_NOSEP_INLINE jfloat JCGO_INLFRW_FASTCALL
|
||
|
#else
|
||
|
#ifdef JCGO_FASTMATH
|
||
|
JCGO_NOSEP_INLINE jfloat JCGO_INLFRW_FASTCALL
|
||
|
#else
|
||
|
JCGO_NOSEP_STATIC jfloat CFASTCALL
|
||
|
#endif
|
||
|
#endif
|
||
|
jcgo_fmodf( jfloat f1, jfloat f2 )
|
||
|
{
|
||
|
#ifdef JCGO_NOFP
|
||
|
return (u_jint)(f2 + (jfloat)1) > (u_jint)1 ?
|
||
|
(jfloat)((jint)f1 % (jint)f2) : (jfloat)0;
|
||
|
#else
|
||
|
#ifdef JCGO_FASTMATH
|
||
|
return (jfloat)JCGO_FP_FMODF(f1, f2);
|
||
|
#else
|
||
|
jfloat f;
|
||
|
if (JCGO_EXPECT_TRUE(f2 != (jfloat)0.0) && JCGO_FP_FINITEF(f1))
|
||
|
{
|
||
|
if (JCGO_FP_FINITEF(f2))
|
||
|
{
|
||
|
f = f1;
|
||
|
if (f1 < (jfloat)0.0)
|
||
|
f1 = -f1;
|
||
|
if (f2 < (jfloat)0.0)
|
||
|
f2 = -f2;
|
||
|
if (JCGO_EXPECT_TRUE(f1 >= f2))
|
||
|
f1 = (jfloat)JCGO_FP_FMODF(f1, f2);
|
||
|
if (f < (jfloat)0.0)
|
||
|
f1 = -f1;
|
||
|
return f1;
|
||
|
}
|
||
|
if (JCGO_FP_NOTNANF(f2))
|
||
|
return f1;
|
||
|
}
|
||
|
return (jfloat)jcgo_fpNaN;
|
||
|
#endif
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
#endif
|