summaryrefslogtreecommitdiffstats
path: root/luni/src/main/native/java_lang_StrictMath.c
blob: 7d335f77645ead7e6b31787ab351e139eee92d32 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
/*
 * Copyright 2006 The Android Open Source Project 
 *
 * Native functions for java.lang.StrictMath.
 */
#include "jni.h"
#include "JNIHelp.h"

#include <stdlib.h>
/* This static way is the "best" way to integrate fdlibm without a conflict
 * into the android envoirement 
 */

/* #include "fltconst.h" */

#if defined(__P)
#undef __P
#endif /* defined(__P) */

#include "../../external/fdlibm/fdlibm.h"
_LIB_VERSION_TYPE _LIB_VERSION = _IEEE_;

/* native public static double sin(double a); */
static jdouble jsin(JNIEnv* env, jclass clazz, jdouble a)
{
    return ieee_sin(a);
}

/* native public static double cos(double a); */
static jdouble jcos(JNIEnv* env, jclass clazz, jdouble a)
{
    return ieee_cos(a);
}

/* native public static double tan(double a); */
static jdouble jtan(JNIEnv* env, jclass clazz, jdouble a)
{
    return ieee_tan(a);
}

/* native public static double asin(double a); */
static jdouble jasin(JNIEnv* env, jclass clazz, jdouble a)
{
    return ieee_asin(a);
}

/* native public static double acos(double a); */
static jdouble jacos(JNIEnv* env, jclass clazz, jdouble a)
{
    return ieee_acos(a);
}

/* native public static double atan(double a); */
static jdouble jatan(JNIEnv* env, jclass clazz, jdouble a)
{
    return ieee_atan(a);
}

/* native public static double exp(double a); */
static jdouble jexp(JNIEnv* env, jclass clazz, jdouble a)
{
    return ieee_exp(a);
}

/* native public static double log(double a); */
static jdouble jlog(JNIEnv* env, jclass clazz, jdouble a)
{
    return ieee_log(a);
}

/* native public static double sqrt(double a); */
static jdouble jsqrt2(JNIEnv* env, jclass clazz, jdouble a)
{
    return ieee_sqrt(a);
}

/* native public static double IEEEremainder(double a, double b); */
static jdouble jieee_remainder(JNIEnv* env, jclass clazz, jdouble a, jdouble b)
{
    return ieee_remainder(a, b);
}

/* native public static double floor(double a); */
static jdouble jfloor(JNIEnv* env, jclass clazz, jdouble a)
{
    return ieee_floor(a);
}

/* native public static double ceil(double a); */
static jdouble jceil(JNIEnv* env, jclass clazz, jdouble a)
{
    return ieee_ceil(a);
}

/* native public static double rint(double a); */
static jdouble jrint(JNIEnv* env, jclass clazz, jdouble a)
{
    return ieee_rint(a);
}

/* native public static double atan2(double a, double b); */
static jdouble jatan2(JNIEnv* env, jclass clazz, jdouble a, jdouble b)
{
    return ieee_atan2(a, b);
}

/* native public static double pow(double a, double b); */
static jdouble jpow(JNIEnv* env, jclass clazz, jdouble a, jdouble b)
{
    return ieee_pow(a,b);
}

/* native public static double sinh(double a); */
static jdouble jsinh(JNIEnv* env, jclass clazz, jdouble a)
{
    return ieee_sinh(a);
}

/* native public static double tanh(double a); */
static jdouble jtanh(JNIEnv* env, jclass clazz, jdouble a)
{
    return ieee_tanh(a);
}

/* native public static double cosh(double a); */
static jdouble jcosh(JNIEnv* env, jclass clazz, jdouble a)
{
    return ieee_cosh(a);
}

/* native public static double log10(double a); */
static jdouble jlog10(JNIEnv* env, jclass clazz, jdouble a)
{
    return ieee_log10(a);
}

/* native public static double cbrt(double a); */
static jdouble jcbrt(JNIEnv* env, jclass clazz, jdouble a)
{
    return ieee_cbrt(a);
}

/* native public static double expm1(double a); */
static jdouble jexpm1(JNIEnv* env, jclass clazz, jdouble a)
{
    return ieee_expm1(a);
}

/* native public static double hypot(double a, double b); */
static jdouble jhypot(JNIEnv* env, jclass clazz, jdouble a, jdouble b)
{
    return ieee_hypot(a, b);
}

/* native public static double log1p(double a); */
static jdouble jlog1p(JNIEnv* env, jclass clazz, jdouble a)
{
    return ieee_log1p(a);
}

/* native public static double nextafter(double a, double b); */
static jdouble jnextafter(JNIEnv* env, jclass clazz, jdouble a, jdouble b)
{
    return ieee_nextafter(a, b);
}

/* native public static float nextafterf(float a, float b); */
static jfloat jnextafterf(JNIEnv* env, jclass clazz, jfloat arg1, jfloat arg2)
{
    jint hx = *(jint*)&arg1;
    jint hy = *(jint*)&arg2;

    if (!(hx&0x7fffffff)) { /* arg1 == 0 */
      *(jint*)&arg1 = (hy & 0x80000000) | 0x1;
      return arg1;
    }

    if((hx > 0) ^ (hx > hy)) { /* |arg1| < |arg2| */
        hx += 1;
    } else {
        hx -= 1;
    }
    *(jint*)&arg1 = hx;
    return arg1;
}

/*
 * JNI registration.
 */
static JNINativeMethod gMethods[] = {
    /* name, signature, funcPtr */
    { "sin",    "(D)D", jsin },
    { "cos",    "(D)D", jcos },
    { "tan",    "(D)D", jtan },

    { "asin",   "(D)D", jasin },
    { "acos",   "(D)D", jacos },
    { "atan",   "(D)D", jatan },

    { "exp",    "(D)D", jexp },
    { "log",    "(D)D", jlog },
    { "sqrt",   "(D)D", jsqrt2 },

    { "IEEEremainder", "(DD)D", jieee_remainder },

    { "floor",  "(D)D", jfloor },
    { "ceil",   "(D)D", jceil },
    { "rint",   "(D)D", jrint },

    { "atan2",  "(DD)D", jatan2 },
    { "pow",    "(DD)D", jpow },

    { "sinh",   "(D)D", jsinh },
    { "cosh",   "(D)D", jcosh },
    { "tanh",   "(D)D", jtanh },
    { "log10",  "(D)D", jlog10 },
    { "cbrt",   "(D)D", jcbrt },
    { "expm1",  "(D)D", jexpm1 },
    { "hypot",  "(DD)D", jhypot },
    { "log1p",  "(D)D", jlog1p },
    { "nextafter",  "(DD)D", jnextafter },
    { "nextafterf",  "(FF)F", jnextafterf },
};

int register_java_lang_StrictMath(JNIEnv* env)
{
    return jniRegisterNativeMethods(env, "java/lang/StrictMath", gMethods,
        NELEM(gMethods));
}