Created
January 4, 2012 21:09
-
-
Save cab1729/1562150 to your computer and use it in GitHub Desktop.
MPFloat
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <limits.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include "MPFloat.h" | |
#include "jcl.h" | |
#include <gmp.h> | |
static jfieldID native_ptr; | |
#if DEBUG | |
#define TRACE(msg) fprintf (stderr, "%s(%s:%d) -- %s\n", __FUNCTION__, __FILE__, __LINE__, msg) | |
#else | |
#define TRACE(msg) | |
#endif | |
/* | |
* Initialize the native library. Specifically this method: | |
* | |
* a. Pass NULLs to the mp_set_memory_functions implying that GMP should use | |
* malloc, realloc and free for memory allocation, and if they fail GMP | |
* will print a message to the standard error output and terminates the | |
* program. | |
* b. Find out and store the reference to the NativeMPF class's 'native_ptr' | |
* field. This is done so later in the method invocations we can access that | |
* field and acquire the native value associated with that Pointer instance. | |
*/ | |
JNIEXPORT void JNICALL | |
Java_jgmp_MPFloat_mpfInitializeLibrary (JNIEnv *env, jclass nativeMPF) | |
{ | |
mp_set_memory_functions (NULL, NULL, NULL); | |
native_ptr = (*env)->GetFieldID (env, nativeMPF, "native_ptr", "Ljgmp/Pointer;"); | |
} | |
/* | |
* Allocate and initialize the data structure for an instance of a nativeMPF. | |
* | |
* @param jthis an instance of nativeMPF. | |
*/ | |
JNIEXPORT void JNICALL | |
Java_jgmp_MPFloat_mpfInitialize__ (JNIEnv *env, jobject jthis) | |
{ | |
mpf_ptr _this; | |
jobject native_ptr_fld; | |
_this = (mpf_ptr)JCL_malloc (env, sizeof (mpf_t)); | |
//initialize --GMP sets the value to zero. | |
mpf_init (_this); | |
//instantiate the Pointer instance for this nativeMPF. | |
native_ptr_fld = JCL_NewRawDataObject (env, _this); | |
//... and assign it to the native_ptr field. | |
(*env)->SetObjectField (env, jthis, native_ptr, native_ptr_fld); | |
} | |
/* | |
* Allocate and initialize the data structure for an instance of a nativeMPF | |
* and set default precision. | |
* | |
* @param jthis an instance of nativeMPF. | |
* @param defaultPrec default precision to set | |
*/ | |
JNIEXPORT void JNICALL | |
Java_jgmp_MPFloat_mpfInitialize__I (JNIEnv *env, jobject jthis, jint defaultPrec) | |
{ | |
mpf_ptr _this; | |
jobject native_ptr_fld; | |
_this = (mpf_ptr)JCL_malloc (env, sizeof (mpf_t)); | |
//initialize --GMP sets the value to zero. | |
mpf_init2 (_this, (int)defaultPrec); | |
//instantiate the Pointer instance for this nativeMPF. | |
native_ptr_fld = JCL_NewRawDataObject (env, _this); | |
//... and assign it to the native_ptr field. | |
(*env)->SetObjectField (env, jthis, native_ptr, native_ptr_fld); | |
} | |
JNIEXPORT void JNICALL | |
Java_jgmp_MPFloat_mpfFinalize (JNIEnv *env, jobject jthis) | |
{ | |
mpf_ptr _this; | |
TRACE("begin"); | |
_this = (mpf_ptr)JCL_GetRawData (env, (*env)->GetObjectField (env, jthis, native_ptr)); | |
if (_this != NULL) | |
{ | |
mpf_clear (_this); | |
free (_this); | |
_this = NULL; | |
} | |
else | |
{ | |
TRACE("WARNING: Already cleared + freed"); | |
} | |
TRACE("end"); | |
} | |
JNIEXPORT void JNICALL | |
Java_jgmp_MPFloat_mpfFromLong (JNIEnv *env, jobject jthis, jlong n) | |
{ | |
mpf_ptr _this; | |
TRACE("begin"); | |
_this = (mpf_ptr)JCL_GetRawData (env, (*env)->GetObjectField (env, jthis, native_ptr)); | |
//the size of jlong (64-bit) is either the same as a long, or that of a long long. | |
//if it's the former, we use as is. | |
if (sizeof (jlong) == sizeof (long)) | |
{ | |
mpf_set_si (_this, (signed long)n); | |
} | |
else | |
{ | |
/*...otherwise, we operate on the two halves of the long long, each half | |
* being 32-bit wide. for simplicity, we work with positive | |
* values negating, if necessary, the final outcome. | |
*/ | |
const int isnegative = n < 0 ? 1 : 0; | |
if (isnegative) | |
{ | |
n = -n; | |
} | |
mpf_set_ui (_this, (unsigned long)(((unsigned long long)n) >> 32)); | |
mpf_mul_2exp (_this, _this, 32); //shift left by 32 bits | |
mpf_add_ui (_this, _this, (unsigned long)n); | |
if (isnegative) | |
{ | |
mpf_neg (_this, _this); | |
} | |
} | |
TRACE("end"); | |
} | |
JNIEXPORT void JNICALL | |
Java_jgmp_MPFloat_mpfFromDouble (JNIEnv *env, jobject jthis, jdouble n) | |
{ | |
mpf_ptr _this; | |
TRACE("begin"); | |
_this = (mpf_ptr)JCL_GetRawData (env, (*env)->GetObjectField (env, jthis, native_ptr)); | |
mpf_set_d (_this, (double)n); | |
TRACE("end"); | |
} | |
/* | |
* @param jthis an instance of nativeMPF. On exit, this will have the same | |
* value as x. | |
* @param x an instance of a nativeMPF's native pointer. | |
*/ | |
JNIEXPORT void JNICALL | |
Java_jgmp_MPFloat_mpfFromMPF (JNIEnv *env, jobject jthis, jobject x) | |
{ | |
mpf_ptr _this; | |
mpf_srcptr _x; | |
TRACE("begin"); | |
_this = (mpf_ptr)JCL_GetRawData (env, (*env)->GetObjectField (env, jthis, native_ptr)); | |
_x = (mpf_srcptr)JCL_GetRawData (env, x); | |
mpf_set (_this, _x); | |
TRACE("end"); | |
} | |
/* | |
* @param jthis an instance of nativeMPF. On exit, this will have the value | |
* represented by the s Java string. | |
* @param s a Java string containing, a possibly signed, value to assign to | |
* this. | |
* @param rdx the base in which the symbols, in s, are represented. | |
* @return 0 if the entire string is a valid number in base rdx. Otherwise it | |
* returns -1. | |
*/ | |
JNIEXPORT jint JNICALL | |
Java_jgmp_MPFloat_mpfFromString (JNIEnv *env, jobject jthis, jstring s, jint rdx) | |
{ | |
mpf_ptr _this; | |
const char *_s; | |
int result; | |
TRACE("begin"); | |
_this = (mpf_ptr)JCL_GetRawData (env, (*env)->GetObjectField (env, jthis, native_ptr)); | |
_s = (*env)->GetStringUTFChars (env, s, NULL); | |
result = mpf_set_str (_this, _s, (int)rdx); | |
JCL_free_cstring (env, s, _s); | |
TRACE("end"); | |
return (result); | |
} | |
/* | |
* @param jthis an instance of nativeMPF. On exit, this will have the value | |
* represented by the m Java byte array (most significant byte at | |
* index position 0). It will be positive, or negative, depending on | |
* the value of isnegative. | |
* @param m a Java byte array containing the byte representation of the | |
* absolute value (most significant byte being at index position 0) | |
* to assign to this. | |
* @param isnegative true if this should be negative and false if it should | |
* be positive. | |
*/ | |
JNIEXPORT void JNICALL | |
Java_jgmp_MPFloat_mpfFromSignedMagnitude (JNIEnv *env, jobject jthis, jbyteArray m, jboolean isnegative) | |
{ | |
mpf_ptr _this; | |
jbyte *_m; | |
int mlength, i; | |
TRACE("begin"); | |
_this = (mpf_ptr)JCL_GetRawData (env, (*env)->GetObjectField (env, jthis, native_ptr)); | |
_m = (*env)->GetByteArrayElements (env, m, NULL); | |
mlength = (*env)->GetArrayLength (env, m); | |
mpf_set_ui (_this, 0); | |
for (i = 0; i < mlength; i++) | |
{ | |
mpf_mul_2exp (_this, _this, 8); | |
mpf_add_ui (_this, _this, (unsigned long)(_m[i] & 0xFF)); | |
} | |
(*env)->ReleaseByteArrayElements (env, m, _m, JNI_ABORT); | |
if (isnegative == JNI_TRUE) | |
{ | |
mpf_neg (_this, _this); | |
} | |
TRACE("end"); | |
} | |
/* | |
* @param jthis an instance of nativeMPF. | |
* @param n the base in which to represent this. | |
* @return the Java string representing the value of this in base n. | |
* fix: changed to get string with gmp_snprintf no longer requires base value | |
*/ | |
JNIEXPORT jstring JNICALL | |
Java_jgmp_MPFloat_mpfToString (JNIEnv *env, jobject jthis, jint n) | |
{ | |
mpf_srcptr _this; | |
char buf[10 * GMP_LIMB_BITS + 5]; | |
int p; | |
jstring result; | |
TRACE("begin"); | |
_this = (mpf_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, jthis, native_ptr)); | |
p = mpf_get_prec(_this)/2; | |
gmp_snprintf (buf, sizeof(buf), "%.*Fe", p, _this, p); | |
result = (*env)->NewStringUTF (env, buf); | |
TRACE("end"); | |
return (result); | |
} | |
/* | |
* @param jthis an instance of nativeMPF. | |
* @return the, eventually truncated, double value of this nativeMPF. | |
*/ | |
JNIEXPORT jdouble JNICALL | |
Java_jgmp_MPFloat_mpfDoubleValue (JNIEnv *env, jobject jthis) | |
{ | |
mpf_srcptr _this; | |
TRACE("begin"); | |
_this = (mpf_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, jthis, native_ptr)); | |
TRACE("end"); | |
return ((jdouble)mpf_get_d (_this)); | |
} | |
/* | |
* @param jthis an instance of nativeMPF. | |
* @return the signed long integer value of this nativeMPF. | |
*/ | |
JNIEXPORT jlong JNICALL | |
Java_jgmp_MPFloat_mpfLongValue (JNIEnv *env, jobject jthis) | |
{ | |
mpf_srcptr _this; | |
TRACE("begin"); | |
_this = (mpf_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, jthis, native_ptr)); | |
TRACE("end"); | |
return ((jlong)mpf_get_si (_this)); | |
} | |
/* | |
* @param jthis an instance of nativeMPF. | |
* @return the possibly truncated float value of this nativeMPF. | |
*/ | |
JNIEXPORT jfloat JNICALL | |
Java_jgmp_MPFloat_mpfFloatValue (JNIEnv *env, jobject jthis) | |
{ | |
mpf_srcptr _this; | |
TRACE("begin"); | |
_this = (mpf_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, jthis, native_ptr)); | |
TRACE("end"); | |
return ((jfloat)mpf_get_si (_this)); | |
} | |
JNIEXPORT jint JNICALL | |
Java_jgmp_MPFloat_mpfGetDefaultPrec (JNIEnv *env, jclass nativeMPF) | |
{ | |
return ((jint) mpf_get_default_prec ()); | |
} | |
JNIEXPORT void JNICALL | |
Java_jgmp_MPFloat_mpfSetDefaultPrec (JNIEnv *env, jclass nativeMPF, jint p) | |
{ | |
mpf_set_default_prec ((int)p); | |
} | |
JNIEXPORT jint JNICALL | |
Java_jgmp_MPFloat_mpfGetCurrentPrec (JNIEnv *env, jobject jthis) | |
{ | |
mpf_srcptr _this; | |
TRACE("begin"); | |
_this = (mpf_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, jthis, native_ptr)); | |
TRACE("end"); | |
return ((jint) mpf_get_prec (_this)); | |
} | |
JNIEXPORT jint JNICALL | |
Java_jgmp_MPFloat_mpfCompare (JNIEnv *env, jobject jthis, jobject x) | |
{ | |
mpf_ptr _this, _x; | |
int res; | |
TRACE("begin"); | |
_this = (mpf_ptr)JCL_GetRawData (env, (*env)->GetObjectField (env, jthis, native_ptr)); | |
_x = (mpf_ptr)JCL_GetRawData (env, x); | |
res = mpf_cmp (_this, _x); | |
TRACE("end"); | |
if (res == 0) | |
return ((jint)0); | |
else if (res < 0) | |
return ((jint)-1); | |
else | |
return ((jint)1); | |
} | |
/* @param jthis an instance of nativeMPF. | |
* @param x an instance of nativeMPF's Pointer. | |
* output: | |
* @param r a nativeMPF's Pointer such that r = this + x. | |
*/ | |
JNIEXPORT void JNICALL | |
Java_jgmp_MPFloat_mpfAdd (JNIEnv *env, jobject jthis, jobject x, jobject r) | |
{ | |
mpf_srcptr _this, _x; | |
mpf_ptr _r; | |
TRACE("begin"); | |
_this = (mpf_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, jthis, native_ptr)); | |
_x = (mpf_srcptr)JCL_GetRawData (env, x); | |
_r = (mpf_ptr)JCL_GetRawData (env, r); | |
mpf_add (_r, _this, _x); | |
TRACE("end"); | |
} | |
/* | |
* @param jthis an instance of nativeMPF. | |
* @param n a non-negative number to add to this. | |
* | |
* output: | |
* @param r a nativeMPF's Pointer such that r = this + n. | |
*/ | |
JNIEXPORT void JNICALL | |
Java_jgmp_MPFloat_mpfAddUI (JNIEnv *env, jobject jthis, jint n, jobject r) | |
{ | |
mpf_srcptr _this; | |
mpf_ptr _r; | |
TRACE("begin"); | |
_this = (mpf_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, jthis, native_ptr)); | |
_r = (mpf_ptr)JCL_GetRawData (env, r); | |
mpf_add_ui (_r, _this, (unsigned long)n); | |
TRACE("end"); | |
} | |
/* @param jthis an instance of nativeMPF. */ | |
/* @param x an instance of nativeMPF's Pointer. */ | |
/* output: */ | |
/* @param r a nativeMPF's Pointer such that r = this - x. */ | |
JNIEXPORT void JNICALL | |
Java_jgmp_MPFloat_mpfSubtract (JNIEnv *env, jobject jthis, jobject x, jobject r) | |
{ | |
mpf_srcptr _this, _x; | |
mpf_ptr _r; | |
TRACE("begin"); | |
_this = (mpf_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, jthis, native_ptr)); | |
_x = (mpf_srcptr)JCL_GetRawData (env, x); | |
_r = (mpf_ptr)JCL_GetRawData (env, r); | |
mpf_sub (_r, _this, _x); | |
TRACE("end"); | |
} | |
/* | |
* @param jthis an instance of nativeMPF. | |
* @param n a non-negative number to subtract from this. | |
* | |
* output: | |
* @param r a nativeMPF's Pointer such that r = this - n. | |
*/ | |
JNIEXPORT void JNICALL | |
Java_jgmp_MPFloat_mpfSubUI (JNIEnv *env, jobject jthis, jint n, jobject r) | |
{ | |
mpf_srcptr _this; | |
mpf_ptr _r; | |
TRACE("begin"); | |
_this = (mpf_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, jthis, native_ptr)); | |
_r = (mpf_ptr)JCL_GetRawData (env, r); | |
mpf_sub_ui (_r, _this, (unsigned long)n); | |
TRACE("end"); | |
} | |
/* | |
* @param jthis an instance of nativeMPF. | |
* @param x an instance of nativeMPF's Pointer. | |
* output: | |
* @param r a nativeMPF's Pointer such that r = this * x. | |
*/ | |
JNIEXPORT void JNICALL | |
Java_jgmp_MPFloat_mpfMultiply (JNIEnv *env, jobject jthis, jobject x, jobject r) | |
{ | |
mpf_srcptr _this, _x; | |
mpf_ptr _r; | |
TRACE("begin"); | |
_this = (mpf_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, jthis, native_ptr)); | |
_x = (mpf_srcptr)JCL_GetRawData (env, x); | |
_r = (mpf_ptr)JCL_GetRawData (env, r); | |
mpf_mul (_r, _this, _x); | |
TRACE("end"); | |
} | |
/* | |
* @param jthis an instance of nativeMPF. | |
* @param n a non-negative number to multiply this by. | |
* | |
* output: | |
* @param r a nativeMPF's Pointer such that r = this * n. | |
*/ | |
JNIEXPORT void JNICALL | |
Java_jgmp_MPFloat_mpfMultUI (JNIEnv *env, jobject jthis, jint n, jobject r) | |
{ | |
mpf_srcptr _this; | |
mpf_ptr _r; | |
TRACE("begin"); | |
_this = (mpf_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, jthis, native_ptr)); | |
_r = (mpf_ptr)JCL_GetRawData (env, r); | |
mpf_mul_ui (_r, _this, (unsigned long)n); | |
TRACE("end"); | |
} | |
/* | |
* @param jthis an instance of nativeMPF. | |
* @param n a non-negative number to raise this to. | |
* | |
* output: | |
* @param r a nativeMPF's Pointer such that r = this ** n. | |
*/ | |
JNIEXPORT void JNICALL | |
Java_jgmp_MPFloat_mpfPow (JNIEnv *env, jobject jthis, jint n, jobject r) | |
{ | |
mpf_srcptr _this; | |
mpf_ptr _r; | |
TRACE("begin"); | |
_this = (mpf_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, jthis, native_ptr)); | |
_r = (mpf_ptr)JCL_GetRawData (env, r); | |
mpf_pow_ui (_r, _this, (unsigned long)n); | |
TRACE("end"); | |
} | |
/* | |
* @param jthis an instance of nativeMPF. | |
* @param n a nativeMPF to divide this by. | |
* | |
* output: | |
* @param r a NativeMPF's Pointer such that r = this / n. | |
*/ | |
JNIEXPORT void JNICALL | |
Java_jgmp_MPFloat_mpfDiv (JNIEnv *env, jobject jthis, jobject x, jobject r) | |
{ | |
mpf_srcptr _this, _x; | |
mpf_ptr _r; | |
TRACE("begin"); | |
_this = (mpf_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, jthis, native_ptr)); | |
_x = (mpf_srcptr)JCL_GetRawData (env, x); | |
_r = (mpf_ptr)JCL_GetRawData (env, r); | |
mpf_div (_r, _this, _x); | |
TRACE("end"); | |
} | |
/* | |
* @param jthis an instance of nativeMPF. | |
* @param n a non-negative number to divide this by. | |
* | |
* output: | |
* @param r a nativeMPF's Pointer such that r = this / n. | |
*/ | |
JNIEXPORT void JNICALL | |
Java_jgmp_MPFloat_mpfDivUI (JNIEnv *env, jobject jthis, jint n, jobject r) | |
{ | |
mpf_srcptr _this; | |
mpf_ptr _r; | |
TRACE("begin"); | |
_this = (mpf_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, jthis, native_ptr)); | |
_r = (mpf_ptr)JCL_GetRawData (env, r); | |
mpf_div_ui (_r, _this, (unsigned long)n); | |
TRACE("end"); | |
} | |
/* | |
* @param jthis an instance of NativeMPF. | |
* | |
* output: | |
* @param r a NativeMPF's Pointer such that r = absolute value of this. | |
*/ | |
JNIEXPORT void JNICALL | |
Java_jgmp_MPFloat_mpfAbs (JNIEnv *env, jobject jthis, jobject r) | |
{ | |
mpf_srcptr _this; | |
mpf_ptr _r; | |
TRACE("begin"); | |
_this = (mpf_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, jthis, native_ptr)); | |
_r = (mpf_ptr)JCL_GetRawData (env, r); | |
mpf_abs (_r, _this); | |
TRACE("end"); | |
} | |
/* | |
* @param jthis an instance of NativeMPF. | |
* | |
* output: | |
* @param r a NativeMPF's Pointer such that r = -this. | |
*/ | |
JNIEXPORT void JNICALL | |
Java_jgmp_MPFloat_mpfNegate (JNIEnv *env, jobject jthis, jobject r) | |
{ | |
mpf_srcptr _this; | |
mpf_ptr _r; | |
TRACE("begin"); | |
_this = (mpf_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, jthis, native_ptr)); | |
_r = (mpf_ptr)JCL_GetRawData (env, r); | |
mpf_neg (_r, _this); | |
TRACE("end"); | |
} | |
/* | |
* @param jthis an instance of NativeMPF. | |
* | |
* output: | |
* @param r a NativeMPF's Pointer such that r = square root of this. | |
*/ | |
JNIEXPORT void JNICALL | |
Java_jgmp_MPFloat_mpfSqrt (JNIEnv *env, jobject jthis, jobject r) | |
{ | |
mpf_srcptr _this; | |
mpf_ptr _r; | |
TRACE("begin"); | |
_this = (mpf_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, jthis, native_ptr)); | |
_r = (mpf_ptr)JCL_GetRawData (env, r); | |
mpf_sqrt (_r, _this); | |
TRACE("end"); | |
} | |
/* | |
* @param jthis an instance of nativeMPF. | |
* | |
* output: | |
* @param r a nativeMPF's Pointer such that r = this rounded to the next lower integer. | |
*/ | |
JNIEXPORT void JNICALL | |
Java_jgmp_MPFloat_mpfFloor (JNIEnv *env, jobject jthis, jobject r) | |
{ | |
mpf_srcptr _this; | |
mpf_ptr _r; | |
TRACE("begin"); | |
_this = (mpf_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, jthis, native_ptr)); | |
_r = (mpf_ptr)JCL_GetRawData (env, r); | |
mpf_floor (_r, _this); | |
TRACE("end"); | |
} | |
/* | |
* @param jthis an instance of nativeMPF. | |
* | |
* output: | |
* @param r a nativeMPF's Pointer such that r = this rounded to the next higher integer. | |
*/ | |
JNIEXPORT void JNICALL | |
Java_jgmp_MPFloat_mpfCeil (JNIEnv *env, jobject jthis, jobject r) | |
{ | |
mpf_srcptr _this; | |
mpf_ptr _r; | |
TRACE("begin"); | |
_this = (mpf_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, jthis, native_ptr)); | |
_r = (mpf_ptr)JCL_GetRawData (env, r); | |
mpf_ceil (_r, _this); | |
TRACE("end"); | |
} | |
/* | |
* @param jthis an instance of nativeMPF. | |
* | |
* output: | |
* @param r a nativeMPF's Pointer such that r = this rounded to the integer towards zero. | |
*/ | |
JNIEXPORT void JNICALL | |
Java_jgmp_MPFloat_mpfTrunc (JNIEnv *env, jobject jthis, jobject r) | |
{ | |
mpf_srcptr _this; | |
mpf_ptr _r; | |
TRACE("begin"); | |
_this = (mpf_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, jthis, native_ptr)); | |
_r = (mpf_ptr)JCL_GetRawData (env, r); | |
mpf_trunc (_r, _this); | |
TRACE("end"); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* DO NOT EDIT THIS FILE - it is machine generated */ | |
#include <jni.h> | |
/* Header for class jgmp_MPFloat */ | |
#ifndef _Included_jgmp_MPFloat | |
#define _Included_jgmp_MPFloat | |
#ifdef __cplusplus | |
extern "C" { | |
#endif | |
#undef jgmp_MPFloat_serialVersionUID | |
#define jgmp_MPFloat_serialVersionUID -8742448824652078965i64 | |
#undef jgmp_MPFloat_serialVersionUID | |
#define jgmp_MPFloat_serialVersionUID 6326861026105157637i64 | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfInitializeLibrary | |
* Signature: ()V | |
*/ | |
JNIEXPORT void JNICALL Java_jgmp_MPFloat_mpfInitializeLibrary | |
(JNIEnv *, jclass); | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfInitialize | |
* Signature: ()V | |
*/ | |
JNIEXPORT void JNICALL Java_jgmp_MPFloat_mpfInitialize__ | |
(JNIEnv *, jobject); | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfInitialize | |
* Signature: (I)V | |
*/ | |
JNIEXPORT void JNICALL Java_jgmp_MPFloat_mpfInitialize__I | |
(JNIEnv *, jobject, jint); | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfFinalize | |
* Signature: ()V | |
*/ | |
JNIEXPORT void JNICALL Java_jgmp_MPFloat_mpfFinalize | |
(JNIEnv *, jobject); | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfFromLong | |
* Signature: (J)V | |
*/ | |
JNIEXPORT void JNICALL Java_jgmp_MPFloat_mpfFromLong | |
(JNIEnv *, jobject, jlong); | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfFromDouble | |
* Signature: (D)V | |
*/ | |
JNIEXPORT void JNICALL Java_jgmp_MPFloat_mpfFromDouble | |
(JNIEnv *, jobject, jdouble); | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfFromMPF | |
* Signature: (Ljgmp/Pointer;)V | |
*/ | |
JNIEXPORT void JNICALL Java_jgmp_MPFloat_mpfFromMPF | |
(JNIEnv *, jobject, jobject); | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfFromString | |
* Signature: (Ljava/lang/String;I)I | |
*/ | |
JNIEXPORT jint JNICALL Java_jgmp_MPFloat_mpfFromString | |
(JNIEnv *, jobject, jstring, jint); | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfFromSignedMagnitude | |
* Signature: ([BZ)V | |
*/ | |
JNIEXPORT void JNICALL Java_jgmp_MPFloat_mpfFromSignedMagnitude | |
(JNIEnv *, jobject, jbyteArray, jboolean); | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfToString | |
* Signature: (I)Ljava/lang/String; | |
*/ | |
JNIEXPORT jstring JNICALL Java_jgmp_MPFloat_mpfToString | |
(JNIEnv *, jobject, jint); | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfDoubleValue | |
* Signature: ()D | |
*/ | |
JNIEXPORT jdouble JNICALL Java_jgmp_MPFloat_mpfDoubleValue | |
(JNIEnv *, jobject); | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfLongValue | |
* Signature: ()J | |
*/ | |
JNIEXPORT jlong JNICALL Java_jgmp_MPFloat_mpfLongValue | |
(JNIEnv *, jobject); | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfFloatValue | |
* Signature: ()F | |
*/ | |
JNIEXPORT jfloat JNICALL Java_jgmp_MPFloat_mpfFloatValue | |
(JNIEnv *, jobject); | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfGetDefaultPrec | |
* Signature: ()I | |
*/ | |
JNIEXPORT jint JNICALL Java_jgmp_MPFloat_mpfGetDefaultPrec | |
(JNIEnv *, jclass); | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfSetDefaultPrec | |
* Signature: (I)V | |
*/ | |
JNIEXPORT void JNICALL Java_jgmp_MPFloat_mpfSetDefaultPrec | |
(JNIEnv *, jclass, jint); | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfGetCurrentPrec | |
* Signature: ()I | |
*/ | |
JNIEXPORT jint JNICALL Java_jgmp_MPFloat_mpfGetCurrentPrec | |
(JNIEnv *, jobject); | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfCompare | |
* Signature: (Ljgmp/Pointer;)I | |
*/ | |
JNIEXPORT jint JNICALL Java_jgmp_MPFloat_mpfCompare | |
(JNIEnv *, jobject, jobject); | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfAdd | |
* Signature: (Ljgmp/Pointer;Ljgmp/Pointer;)V | |
*/ | |
JNIEXPORT void JNICALL Java_jgmp_MPFloat_mpfAdd | |
(JNIEnv *, jobject, jobject, jobject); | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfAddUI | |
* Signature: (ILjgmp/Pointer;)V | |
*/ | |
JNIEXPORT void JNICALL Java_jgmp_MPFloat_mpfAddUI | |
(JNIEnv *, jobject, jint, jobject); | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfSubtract | |
* Signature: (Ljgmp/Pointer;Ljgmp/Pointer;)V | |
*/ | |
JNIEXPORT void JNICALL Java_jgmp_MPFloat_mpfSubtract | |
(JNIEnv *, jobject, jobject, jobject); | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfSubUI | |
* Signature: (ILjgmp/Pointer;)V | |
*/ | |
JNIEXPORT void JNICALL Java_jgmp_MPFloat_mpfSubUI | |
(JNIEnv *, jobject, jint, jobject); | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfMultiply | |
* Signature: (Ljgmp/Pointer;Ljgmp/Pointer;)V | |
*/ | |
JNIEXPORT void JNICALL Java_jgmp_MPFloat_mpfMultiply | |
(JNIEnv *, jobject, jobject, jobject); | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfMultUI | |
* Signature: (ILjgmp/Pointer;)V | |
*/ | |
JNIEXPORT void JNICALL Java_jgmp_MPFloat_mpfMultUI | |
(JNIEnv *, jobject, jint, jobject); | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfPow | |
* Signature: (ILjgmp/Pointer;)V | |
*/ | |
JNIEXPORT void JNICALL Java_jgmp_MPFloat_mpfPow | |
(JNIEnv *, jobject, jint, jobject); | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfDiv | |
* Signature: (Ljgmp/Pointer;Ljgmp/Pointer;)V | |
*/ | |
JNIEXPORT void JNICALL Java_jgmp_MPFloat_mpfDiv | |
(JNIEnv *, jobject, jobject, jobject); | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfDivUI | |
* Signature: (ILjgmp/Pointer;)V | |
*/ | |
JNIEXPORT void JNICALL Java_jgmp_MPFloat_mpfDivUI | |
(JNIEnv *, jobject, jint, jobject); | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfAbs | |
* Signature: (Ljgmp/Pointer;)V | |
*/ | |
JNIEXPORT void JNICALL Java_jgmp_MPFloat_mpfAbs | |
(JNIEnv *, jobject, jobject); | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfNegate | |
* Signature: (Ljgmp/Pointer;)V | |
*/ | |
JNIEXPORT void JNICALL Java_jgmp_MPFloat_mpfNegate | |
(JNIEnv *, jobject, jobject); | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfSqrt | |
* Signature: (Ljgmp/Pointer;)V | |
*/ | |
JNIEXPORT void JNICALL Java_jgmp_MPFloat_mpfSqrt | |
(JNIEnv *, jobject, jobject); | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfFloor | |
* Signature: (Ljgmp/Pointer;)V | |
*/ | |
JNIEXPORT void JNICALL Java_jgmp_MPFloat_mpfFloor | |
(JNIEnv *, jobject, jobject); | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfCeil | |
* Signature: (Ljgmp/Pointer;)V | |
*/ | |
JNIEXPORT void JNICALL Java_jgmp_MPFloat_mpfCeil | |
(JNIEnv *, jobject, jobject); | |
/* | |
* Class: jgmp_MPFloat | |
* Method: mpfTrunc | |
* Signature: (Ljgmp/Pointer;)V | |
*/ | |
JNIEXPORT void JNICALL Java_jgmp_MPFloat_mpfTrunc | |
(JNIEnv *, jobject, jobject); | |
#ifdef __cplusplus | |
} | |
#endif | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package jgmp; | |
/** | |
* @author jmenes | |
* Implement arbitrary precision float using GMP | |
* based on code from GNU Classpath (GMP & Pointer classes) | |
* | |
*/ | |
public final class MPFloat extends Number implements Comparable<MPFloat> { | |
private static final long serialVersionUID = 6326861026105157637L; | |
private int refCount = 1; | |
private static int defaultPrec = 64; // precision bit count - if not given, set from default | |
private Pointer native_ptr; | |
static { | |
System.loadLibrary("libgmp-3.dll"); | |
System.loadLibrary("jgmp"); | |
mpfInitializeLibrary(); | |
} | |
// special values conforming to IEEE-754 float definitions | |
// TODO need to fix representation - using Double values crashes | |
public static final MPFloat NaN = | |
// (Double.longBitsToDouble(0x7ff8000000000000L)); | |
//new MPFloat(0.0).mult(new MPFloat("1e400", 10)); | |
new MPFloat("-10000000000000000000000e11111111", 2); | |
public static final MPFloat NEGATIVE_INFINITY = | |
// (Double.longBitsToDouble(0xfff0000000000000L)); | |
new MPFloat("-1e400", 10); | |
//new MPFloat("-00000000000000000000000e11111111", 2); | |
public static final MPFloat POSITIVE_INFINITY = | |
// (Double.longBitsToDouble(0x7ff0000000000000L)); | |
new MPFloat("1e400", 10); | |
//new MPFloat("00000000000000000000000e11111111", 2); | |
public MPFloat() { | |
super(); | |
mpfInitialize(); | |
defaultPrec = mpfGetDefaultPrec(); | |
} | |
public MPFloat(int prec) { | |
super(); | |
mpfInitialize(prec); | |
defaultPrec = mpfGetDefaultPrec(); | |
} | |
public MPFloat(String s, int base, int prec) | |
{ | |
this(prec); | |
fromString(s,base); | |
} | |
public MPFloat(String s, int base) | |
{ | |
this(); | |
fromString(s,base); | |
} | |
public MPFloat(String s) | |
{ | |
this(s, 10); | |
} | |
public MPFloat(long n, int prec) | |
{ | |
this(prec); | |
fromLong(n); | |
} | |
public MPFloat(long n) | |
{ | |
this(); | |
fromLong(n); | |
} | |
public MPFloat(double n) | |
{ | |
this(); | |
fromDouble(n); | |
} | |
public void fromMPF(MPFloat x) | |
{ | |
acquireRef(); | |
x.acquireRef(); | |
mpfFromMPF(x.native_ptr); | |
x.releaseRef(); | |
releaseRef(); | |
} | |
public void fromLong(long n) | |
{ | |
acquireRef(); | |
mpfFromLong(n); | |
releaseRef(); | |
} | |
public void fromDouble(double n) | |
{ | |
// TODO implement a native mpfFromDouble | |
acquireRef(); | |
mpfFromDouble(n); | |
releaseRef(); | |
} | |
public int fromString(String s, int rdx) | |
{ | |
acquireRef(); | |
int result = mpfFromString(s, rdx); | |
releaseRef(); | |
return result; | |
} | |
public void fromSignedMagnitude(byte[] m, boolean isNegative) | |
{ | |
acquireRef(); | |
mpfFromSignedMagnitude(m, isNegative); | |
releaseRef(); | |
} | |
public String toString(int b) | |
{ | |
acquireRef(); | |
String result = mpfToString(b); | |
//String result = String.valueOf(mpfDoubleValue()); | |
releaseRef(); | |
return result; | |
} | |
public String toString() | |
{ | |
return toString(10); | |
} | |
@Override | |
public int compareTo(MPFloat x) { | |
acquireRef(); | |
x.acquireRef(); | |
int result = mpfCompare(x.native_ptr); | |
x.releaseRef(); | |
releaseRef(); | |
return result; | |
} | |
@Override | |
public int intValue() { | |
acquireRef(); | |
double result = mpfDoubleValue(); | |
releaseRef(); | |
return Double.valueOf(result).intValue(); | |
} | |
@Override | |
public long longValue() { | |
acquireRef(); | |
long result = mpfLongValue(); | |
releaseRef(); | |
return result; | |
} | |
@Override | |
public float floatValue() { | |
acquireRef(); | |
double result = mpfDoubleValue(); | |
releaseRef(); | |
return Double.valueOf(result).floatValue(); | |
} | |
@Override | |
public double doubleValue() { | |
acquireRef(); | |
double result = mpfDoubleValue(); | |
releaseRef(); | |
return result; | |
} | |
/** | |
* @return default precision bits count | |
*/ | |
public static int getDefaultPrec() { | |
defaultPrec = mpfGetDefaultPrec(); | |
return defaultPrec; | |
} | |
/** | |
* @param prec default precision bit count to set | |
*/ | |
public static void setDefaultPrec(int prec) { | |
defaultPrec = prec; | |
mpfSetDefaultPrec(defaultPrec); | |
} | |
/** | |
* @param x MPFloat object to add | |
* @return MPFloat object set to this + x | |
*/ | |
public MPFloat add(MPFloat x) { | |
MPFloat r = new MPFloat(defaultPrec); | |
acquireRef(); | |
r.acquireRef(); | |
x.acquireRef(); | |
mpfAdd(x.native_ptr, r.native_ptr); | |
x.releaseRef(); | |
r.releaseRef(); | |
releaseRef(); | |
return r; | |
} | |
/** | |
* @param x MPFloat value to add | |
* @param r MPFloat object to hold result of this + x | |
*/ | |
public void add(MPFloat x, MPFloat r) { | |
acquireRef(); | |
r.acquireRef(); | |
x.acquireRef(); | |
mpfAdd(x.native_ptr, r.native_ptr); | |
x.releaseRef(); | |
r.releaseRef(); | |
releaseRef(); | |
return; | |
} | |
/** | |
* @param x double object to add | |
* @return MPFloat object set to this + x | |
*/ | |
public MPFloat add(double x) { | |
MPFloat r = new MPFloat(defaultPrec); | |
MPFloat s = new MPFloat(x); | |
acquireRef(); | |
r.acquireRef(); | |
s.acquireRef(); | |
mpfAdd(s.native_ptr, r.native_ptr); | |
s.releaseRef(); | |
r.releaseRef(); | |
releaseRef(); | |
return r; | |
} | |
/** | |
* @param x double value to add | |
* @param r MPFloat object to hold result of this + x | |
*/ | |
public void add(double x, MPFloat r) { | |
MPFloat s = new MPFloat(x); | |
acquireRef(); | |
r.acquireRef(); | |
s.acquireRef(); | |
mpfAdd(s.native_ptr, r.native_ptr); | |
s.releaseRef(); | |
r.releaseRef(); | |
releaseRef(); | |
return; | |
} | |
/** | |
* @param n integer value to add to this | |
* return r MPFloat object to hold result of this + n | |
*/ | |
public MPFloat add(int n) { | |
MPFloat r = new MPFloat(defaultPrec); | |
acquireRef(); | |
r.acquireRef(); | |
mpfAddUI(n, r.native_ptr); | |
r.releaseRef(); | |
releaseRef(); | |
return r; | |
} | |
/** | |
* @param n integer value to add to this | |
* @param r MPFloat object to hold result of this + n | |
*/ | |
public void add(int n, MPFloat r) { | |
acquireRef(); | |
r.acquireRef(); | |
mpfAddUI(n, r.native_ptr); | |
r.releaseRef(); | |
releaseRef(); | |
return; | |
} | |
/** | |
* @param x MPFloat object to subtract from this | |
* @return MPFloat object set to this - x | |
*/ | |
public MPFloat sub(MPFloat x) { | |
MPFloat r = new MPFloat(defaultPrec); | |
acquireRef(); | |
r.acquireRef(); | |
x.acquireRef(); | |
mpfSubtract(x.native_ptr, r.native_ptr); | |
x.releaseRef(); | |
r.releaseRef(); | |
releaseRef(); | |
return r; | |
} | |
/** | |
* @param x MPFloat object to subtract from this | |
* @param r MPFloat object to hold result of to this - x | |
*/ | |
public void sub(MPFloat x, MPFloat r) { | |
acquireRef(); | |
r.acquireRef(); | |
x.acquireRef(); | |
mpfSubtract(x.native_ptr, r.native_ptr); | |
x.releaseRef(); | |
r.releaseRef(); | |
releaseRef(); | |
return; | |
} | |
/** | |
* @param x double value to subtract from this | |
* @return MPFloat object set to this - x | |
*/ | |
public MPFloat sub(double x) { | |
MPFloat r = new MPFloat(defaultPrec); | |
MPFloat s = new MPFloat(x); | |
acquireRef(); | |
r.acquireRef(); | |
s.acquireRef(); | |
mpfSubtract(s.native_ptr, r.native_ptr); | |
s.releaseRef(); | |
r.releaseRef(); | |
releaseRef(); | |
return r; | |
} | |
/** | |
* @param x double value to subtract from this | |
* @param r MPFloat object to hold result of to this - x | |
*/ | |
public void sub(double x, MPFloat r) { | |
MPFloat s = new MPFloat(x); | |
acquireRef(); | |
r.acquireRef(); | |
s.acquireRef(); | |
mpfSubtract(s.native_ptr, r.native_ptr); | |
s.releaseRef(); | |
r.releaseRef(); | |
releaseRef(); | |
return; | |
} | |
/** | |
* @param n integer value to subtract from this | |
* return r MPFloat object to hold result of this - n | |
*/ | |
public MPFloat sub(int n) { | |
MPFloat r = new MPFloat(defaultPrec); | |
acquireRef(); | |
r.acquireRef(); | |
mpfSubUI(n, r.native_ptr); | |
r.releaseRef(); | |
releaseRef(); | |
return r; | |
} | |
/** | |
* @param n integer value to subtract from this | |
* @param r MPFloat object to hold result of this - n | |
*/ | |
public void sub(int n, MPFloat r) { | |
acquireRef(); | |
r.acquireRef(); | |
mpfSubUI(n, r.native_ptr); | |
r.releaseRef(); | |
releaseRef(); | |
return; | |
} | |
/** | |
* @param x MPFloat object to multiply by this | |
* @return MPfloat object set to this * x | |
*/ | |
public MPFloat mult(MPFloat x) { | |
MPFloat r = new MPFloat(defaultPrec); | |
acquireRef(); | |
r.acquireRef(); | |
x.acquireRef(); | |
mpfMultiply(x.native_ptr, r.native_ptr); | |
x.releaseRef(); | |
r.releaseRef(); | |
releaseRef(); | |
return r; | |
} | |
/** | |
* @param x MPFloat object to multiply by this | |
* @param r MPFloat object to hold result of this * x | |
*/ | |
public void mult(MPFloat x, MPFloat r) { | |
acquireRef(); | |
r.acquireRef(); | |
x.acquireRef(); | |
mpfMultiply(x.native_ptr, r.native_ptr); | |
x.releaseRef(); | |
r.releaseRef(); | |
releaseRef(); | |
return; | |
} | |
/** | |
* @param n integer value to multiply by this | |
* return r MPFloat object to hold result of this * n | |
*/ | |
public MPFloat mult(int n) { | |
MPFloat r = new MPFloat(defaultPrec); | |
acquireRef(); | |
r.acquireRef(); | |
mpfMultUI(n, r.native_ptr); | |
r.releaseRef(); | |
releaseRef(); | |
return r; | |
} | |
/** | |
* @param n integer value to multiply by this | |
* @param r MPFloat object to hold result of this * n | |
*/ | |
public void mult(int n, MPFloat r) { | |
acquireRef(); | |
r.acquireRef(); | |
mpfMultUI(n, r.native_ptr); | |
r.releaseRef(); | |
releaseRef(); | |
return; | |
} | |
/** | |
* @param x double value to multiply by this | |
* return r MPFloat object to hold result of this * n | |
*/ | |
public MPFloat mult(double x) { | |
MPFloat r = new MPFloat(defaultPrec); | |
MPFloat m = new MPFloat(x); | |
acquireRef(); | |
r.acquireRef(); | |
m.acquireRef(); | |
mpfMultiply(m.native_ptr, r.native_ptr); | |
r.releaseRef(); | |
m.releaseRef(); | |
releaseRef(); | |
return r; | |
} | |
/** | |
* @param x double value to multiply by this | |
* @param r MPFloat object to hold result of this * n | |
*/ | |
public void mult(double x, MPFloat r) { | |
MPFloat m = new MPFloat(x); | |
acquireRef(); | |
r.acquireRef(); | |
m.acquireRef(); | |
mpfMultiply(m.native_ptr, r.native_ptr); | |
r.releaseRef(); | |
m.releaseRef(); | |
releaseRef(); | |
return; | |
} | |
/** | |
* @param x MPFloat object to divide this by | |
* @return MPfloat object set to this / x | |
*/ | |
public MPFloat div(MPFloat x) { | |
MPFloat r = new MPFloat(defaultPrec); | |
acquireRef(); | |
r.acquireRef(); | |
x.acquireRef(); | |
mpfDiv(x.native_ptr, r.native_ptr); | |
x.releaseRef(); | |
r.releaseRef(); | |
releaseRef(); | |
return r; | |
} | |
/** | |
* @param x MPFloat object to divide this by | |
* @param r MPfloat object to hold result of this / x | |
*/ | |
public void div(MPFloat x, MPFloat r) { | |
acquireRef(); | |
r.acquireRef(); | |
x.acquireRef(); | |
mpfDiv(x.native_ptr, r.native_ptr); | |
x.releaseRef(); | |
r.releaseRef(); | |
releaseRef(); | |
return; | |
} | |
/** | |
* @param n integer value to divide this by | |
* return r MPFloat object to hold result of this / n | |
*/ | |
public MPFloat div(int n) { | |
MPFloat r = new MPFloat(defaultPrec); | |
acquireRef(); | |
r.acquireRef(); | |
mpfDivUI(n, r.native_ptr); | |
r.releaseRef(); | |
releaseRef(); | |
return r; | |
} | |
/** | |
* @param n integer value to divide this by | |
* @param r MPFloat object to hold result of this / n | |
*/ | |
public void div(int n, MPFloat r) { | |
acquireRef(); | |
r.acquireRef(); | |
mpfDivUI(n, r.native_ptr); | |
r.releaseRef(); | |
releaseRef(); | |
return; | |
} | |
/** | |
* @param x double value to divide this by | |
* @return MPfloat object set to this / x | |
*/ | |
public MPFloat div(double x) { | |
MPFloat r = new MPFloat(defaultPrec); | |
MPFloat d = new MPFloat(x); | |
acquireRef(); | |
r.acquireRef(); | |
d.acquireRef(); | |
mpfDiv(d.native_ptr, r.native_ptr); | |
d.releaseRef(); | |
r.releaseRef(); | |
releaseRef(); | |
return r; | |
} | |
/** | |
* @param x double value to divide this by | |
* @param r MPfloat object to hold result of this / x | |
*/ | |
public void div(double x, MPFloat r) { | |
MPFloat d = new MPFloat(x); | |
acquireRef(); | |
r.acquireRef(); | |
d.acquireRef(); | |
mpfDiv(d.native_ptr, r.native_ptr); | |
d.releaseRef(); | |
r.releaseRef(); | |
releaseRef(); | |
return; | |
} | |
/** | |
* @return MPfloat object set to the absolute value of this | |
*/ | |
public MPFloat abs() { | |
MPFloat r = new MPFloat(defaultPrec); | |
acquireRef(); | |
r.acquireRef(); | |
mpfAbs(r.native_ptr); | |
r.releaseRef(); | |
releaseRef(); | |
return r; | |
} | |
/** | |
* @param MPfloat object set to the absolute value of this | |
*/ | |
public void abs(MPFloat r) { | |
acquireRef(); | |
r.acquireRef(); | |
mpfAbs(r.native_ptr); | |
r.releaseRef(); | |
releaseRef(); | |
return; | |
} | |
/** | |
* @return MPfloat object set to the square root value of this | |
*/ | |
public MPFloat sqrt() { | |
MPFloat r = new MPFloat(defaultPrec); | |
acquireRef(); | |
r.acquireRef(); | |
mpfSqrt(r.native_ptr); | |
r.releaseRef(); | |
releaseRef(); | |
return r; | |
} | |
/** | |
* @param MPfloat object set to the square root value of this | |
*/ | |
public void sqrt(MPFloat r) { | |
acquireRef(); | |
r.acquireRef(); | |
mpfSqrt(r.native_ptr); | |
r.releaseRef(); | |
releaseRef(); | |
return; | |
} | |
/** | |
* @param n power | |
* @return MPfloat object set to the n power of this | |
*/ | |
public MPFloat pow(int n) { | |
MPFloat r = new MPFloat(defaultPrec); | |
acquireRef(); | |
r.acquireRef(); | |
r.fromMPF(this); | |
mpfPow(n, r.native_ptr); | |
r.releaseRef(); | |
releaseRef(); | |
return r; | |
} | |
/** | |
* @param n power | |
* @param MPfloat object set to the n power of this | |
*/ | |
public void pow(int n, MPFloat r) { | |
acquireRef(); | |
r.acquireRef(); | |
r.fromMPF(this); | |
mpfPow(n, r.native_ptr); | |
r.releaseRef(); | |
releaseRef(); | |
return; | |
} | |
/** | |
* @return MPfloat object set to the -value of this | |
*/ | |
public MPFloat neg() { | |
MPFloat r = new MPFloat(defaultPrec); | |
acquireRef(); | |
r.acquireRef(); | |
mpfNegate(r.native_ptr); | |
r.releaseRef(); | |
releaseRef(); | |
return r; | |
} | |
/** | |
* @return MPfloat object set to the -value of this | |
*/ | |
public void neg(MPFloat r) { | |
acquireRef(); | |
r.acquireRef(); | |
mpfNegate(r.native_ptr); | |
r.releaseRef(); | |
releaseRef(); | |
return; | |
} | |
/** | |
* @return MPfloat object set to the value of this rounded up to the next higher integer | |
*/ | |
public MPFloat ceil() { | |
MPFloat r = new MPFloat(defaultPrec); | |
acquireRef(); | |
r.acquireRef(); | |
mpfCeil(r.native_ptr); | |
r.releaseRef(); | |
releaseRef(); | |
return r; | |
} | |
/** | |
* @param MPfloat object set to the value of this rounded up to the next higher integer | |
*/ | |
public void ceil(MPFloat r) { | |
acquireRef(); | |
r.acquireRef(); | |
mpfCeil(r.native_ptr); | |
r.releaseRef(); | |
releaseRef(); | |
return; | |
} | |
/** | |
* @return MPfloat object set to the absolute value of this rounded down the next lower integer | |
*/ | |
public MPFloat floor() { | |
MPFloat r = new MPFloat(defaultPrec); | |
acquireRef(); | |
r.acquireRef(); | |
mpfFloor(r.native_ptr); | |
r.releaseRef(); | |
releaseRef(); | |
return r; | |
} | |
/** | |
* @param MPfloat object set to the absolute value of this rounded down the next lower integer | |
*/ | |
public void floor(MPFloat r) { | |
acquireRef(); | |
r.acquireRef(); | |
mpfFloor(r.native_ptr); | |
r.releaseRef(); | |
releaseRef(); | |
return; | |
} | |
/** | |
* @return MPfloat object set to the absolute value of this rounded to the integer towards zero | |
*/ | |
public MPFloat trunc() { | |
MPFloat r = new MPFloat(defaultPrec); | |
acquireRef(); | |
r.acquireRef(); | |
mpfTrunc(r.native_ptr); | |
r.releaseRef(); | |
releaseRef(); | |
return r; | |
} | |
/** | |
* @param MPfloat object set to the absolute value of this rounded to the integer towards zero | |
*/ | |
public void trunc(MPFloat r) { | |
acquireRef(); | |
r.acquireRef(); | |
mpfTrunc(r.native_ptr); | |
r.releaseRef(); | |
releaseRef(); | |
return; | |
} | |
/** | |
* return current precision for this object | |
*/ | |
public int getPrecision() { | |
return mpfGetCurrentPrec(); | |
} | |
/** | |
* this is not strictly a NaN test. A NaN should not be equal to anything, even itself. | |
* (a proper NaN test would be r != r is true) | |
*/ | |
public static boolean isNan(MPFloat r) { | |
return (r.toString() == NaN.toString()); | |
} | |
public static boolean isInfinite(MPFloat r) { | |
return (r.toString() == POSITIVE_INFINITY.toString()) || | |
(r.toString() == NEGATIVE_INFINITY.toString()); | |
} | |
public static boolean isPositiveInfinite(MPFloat r) { | |
return (r.toString() == POSITIVE_INFINITY.toString()); | |
} | |
public static boolean isNegativeInfinite(MPFloat r) { | |
return (r.toString() == NEGATIVE_INFINITY.toString()); | |
} | |
private void acquireRef() { | |
// TODO synchronized keyword removed until wait issue resolved | |
refCount++; | |
} | |
private void releaseRef() { | |
// TODO synchronized keyword removed until wait issue resolved | |
refCount--; | |
if (refCount == 0) | |
{ | |
mpfFinalize(); | |
native_ptr = null; | |
} | |
} | |
//Native methods | |
public static native void mpfInitializeLibrary(); | |
// -- init/set | |
private native void mpfInitialize(); | |
private native void mpfInitialize(int prec); | |
private native void mpfFinalize(); | |
private native void mpfFromLong(long n); | |
private native void mpfFromDouble(double n); | |
private native void mpfFromMPF(Pointer x); | |
private native int mpfFromString(String s, int rdx); | |
private native void mpfFromSignedMagnitude(byte[] m, boolean isNegative); | |
// -- conversions | |
private native String mpfToString(int base); | |
private native double mpfDoubleValue(); | |
private native long mpfLongValue(); | |
private native float mpfFloatValue(); | |
// -- precision | |
private static native int mpfGetDefaultPrec(); | |
private static native void mpfSetDefaultPrec(int prec); | |
private native int mpfGetCurrentPrec(); | |
// -- comparison | |
private native int mpfCompare(Pointer y); | |
// -- arithmetic | |
private native void mpfAdd(Pointer x, Pointer r); | |
private native void mpfAddUI(int n, Pointer r); | |
private native void mpfSubtract(Pointer x, Pointer r); | |
private native void mpfSubUI(int n, Pointer r); | |
private native void mpfMultiply(Pointer x, Pointer r); | |
private native void mpfMultUI(int n, Pointer r); | |
private native void mpfPow(int n, Pointer r); | |
private native void mpfDiv(Pointer d, Pointer r); | |
private native void mpfDivUI(int n, Pointer r); | |
private native void mpfAbs(Pointer r); | |
private native void mpfNegate(Pointer r); | |
private native void mpfSqrt(Pointer r); | |
// -- misc | |
private native void mpfFloor(Pointer r); | |
private native void mpfCeil(Pointer r); | |
private native void mpfTrunc(Pointer r); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.BufferedReader; | |
import java.io.FileNotFoundException; | |
import java.io.FileReader; | |
import java.io.IOException; | |
import jgmp.MPFloat; | |
import de.luschny.math.factorial.FactorialPoorMans; | |
/** | |
* @author jmenes | |
* additional functions for MPFloat | |
* | |
*/ | |
public class mpfunctions { | |
// constants computed with PARI/GP | |
protected static final MPFloat PI = | |
new MPFloat( | |
"3.14159265358979323846264338327950288419716939937510582097494459230781640628620899" + | |
"8628034825342117067982148086513282306647093844609550582231725359408128481117450e+00", | |
10, 512); | |
protected static final MPFloat e = | |
new MPFloat( | |
"2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642742746" + | |
"639193200305992181741359662904357290033429526059563073813232862794349076323382988075319525101901157383418793070" + | |
"2154089149934884167509244761460668082265e+00", | |
10, 512 ); | |
protected static final MPFloat EM = | |
new MPFloat( | |
"0.57721566490153286060651209008240243104215933593992359880576723488486772677766467093694706329174674951463" + | |
"144724980708248096050401448654283622417399764492353625350033374293733773767394279259525824709491600873520394816" + | |
"56708532331517766115286211995015079847937e+00", | |
10, 512 ); | |
protected static final MPFloat rootpi = PI.sqrt(); | |
protected static final MPFloat oneonrootpi = new MPFloat(1.0).div(rootpi); | |
protected static final MPFloat twoonrootpi = new MPFloat(2.0).div(rootpi); | |
protected static final MPFloat logtwo = | |
new MPFloat( | |
"0.6931471805599453094172321214581765680755001343602552541206800094933936219696947" + | |
"15605863326996418687542014810205706857336855202357581305570326707516350759619307e+00", | |
10, 512); | |
protected static final MPFloat oneonlog10 = | |
new MPFloat( | |
"0.6931471805599453094172321214581765680755001343602552541206800094933936219696947156058633269964186875420" + | |
"148102057068573368552023575813055703267075163507596193072757082837143519030703862389167347112335011536449" + | |
"7955291204751726815749320651555247341395258830e+00", | |
10, 512); | |
protected static final MPFloat pi2on12 = PI.pow(2).div(new MPFloat(12.)); | |
protected static final int INFINITY = 5000; | |
protected static final MPFloat TWO_PI = PI.mult(2); | |
protected static final MPFloat HALF_PI = PI.div(2); | |
protected static final MPFloat ZERO = new MPFloat(0.0); | |
private static final int[] PRIMES = | |
{2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59, | |
61,67,71,73,79,83,89,97,101,103,107,109,113,127, | |
131,137,139,149,151,157,163,167,173,179,181,191, | |
193,197,199,211,223,227,229,233,239,241,251,257, | |
263,269,271,277,281,283,293,307,311,313,317,331, | |
337,347,349,353,359,367,373,379,383,389,397,401, | |
409,419,421,431,433,439,443,449,457,461,463,467, | |
479,487,491,499,503,509,521,523,541,547,557,563, | |
569,571,577,587,593,599,601,607,613,617,619,631, | |
641,643,647,653,659,661,673,677,683,691,701,709, | |
719,727,733,739,743,751,757,761,769,773,787,797, | |
809,811,821,823,827,829,839,853,857,859,863,877, | |
881,883,887,907,911,919,929,937,941,947,953,967, | |
971,977,983,991,997}; | |
private static int[] primes = PRIMES; // default values in case of file error | |
private static int pl = primes.length; // default values in case of file error | |
private static String[] FACS = new String[5001]; // table of the first 5k factorials | |
private static int facl = 0; | |
private static FactorialPoorMans fpm = new FactorialPoorMans(); | |
static { | |
// load primes array with PARI/GP generated file (5000 primes) | |
try { | |
BufferedReader pf = | |
new BufferedReader(new FileReader("primes.txt")); | |
String ps = pf.readLine(); | |
String[] pe = ps.split(", "); | |
int pel = pe.length; | |
primes = new int[pel]; | |
for (int i=0; i<pel; i++) { | |
primes[i] = Integer.parseInt(pe[i]); | |
} | |
pl = primes.length; | |
pf.close(); | |
} catch (FileNotFoundException e) { | |
// TODO Auto-generated catch block | |
e.printStackTrace(); | |
} catch (IOException e) { | |
// TODO Auto-generated catch block | |
e.printStackTrace(); | |
} | |
// load array with first 5000 factorials - n is index | |
try { | |
BufferedReader ff = | |
new BufferedReader(new FileReader("facs.txt")); | |
String fac = ff.readLine(); | |
FACS = fac.split(", "); | |
facl = FACS.length; | |
ff.close(); | |
} catch (FileNotFoundException e) { | |
// TODO Auto-generated catch block | |
e.printStackTrace(); | |
} catch (IOException e) { | |
// TODO Auto-generated catch block | |
e.printStackTrace(); | |
} | |
if (facl==0) { // if facl==0 something went wrong with file load | |
for (int n=0; n<5001; n++) { | |
FACS[n] = fpm.factorial(n); | |
} | |
} | |
// TODO get the value from env var | |
MPFloat.setDefaultPrec(256); | |
} | |
private mpfunctions() { | |
// private constructor to prevent instantiation | |
} | |
/** | |
* return N! as a string | |
* @param N | |
* @return | |
*/ | |
public static String factorial(int N) { | |
if (N>=facl) | |
return fpm.factorial(N); | |
return FACS[N]; | |
} | |
/** | |
* compute cosine of x using Taylor series (1 - x^2/2! + x^4/4! - ...) | |
* @param x | |
* @return | |
*/ | |
public static MPFloat cos(MPFloat x) { | |
MPFloat cosx = new MPFloat(1.0); | |
MPFloat cosw = new MPFloat(); | |
for (int n=1; n<=INFINITY; n++) { | |
cosw.fromDouble(StrictMath.pow(-1, n)); | |
cosw.div(new MPFloat(factorial(2*n)), cosw); | |
cosx.add(cosw.mult(x.pow(2*n)), cosx); | |
} | |
return cosx; | |
} | |
/** | |
* compute sine of x using Taylor series (x - x^3/3! + x^5/5! - ...) | |
* @param x | |
* @return | |
*/ | |
public static MPFloat sin(MPFloat x) { | |
MPFloat sinx = x; | |
MPFloat sinw = new MPFloat(0.0); | |
for (int n=1; n<=INFINITY; n+=2) { | |
sinw.fromDouble(StrictMath.pow(-1, n)); | |
sinw.div(new MPFloat(factorial((2*n)+1)), sinw); | |
sinw.mult(x.pow((2*n)+1), sinw); | |
sinx.add(sinw, sinx); | |
} | |
return sinx; | |
} | |
/** | |
* compute tangent of x using Taylor series (x + x^3/3 + 2x^5/15 + ...) | |
* @param x | |
* @return | |
*/ | |
public static MPFloat tan(MPFloat x) { | |
MPFloat tanx = x; | |
for (int n=1; n<=INFINITY; n++) { | |
int n4n = (int)StrictMath.pow(-4, n); | |
MPFloat tanw = BernoulliB(2*n); | |
tanw.mult(n4n, tanw); | |
tanw.mult(1+n4n, tanw); | |
tanw.div(new MPFloat(factorial(2*n)), tanw); | |
tanx.add(tanw.mult(x.pow((2*n)-1)), tanx); | |
} | |
return tanx; | |
} | |
/** | |
* compute secant of x using Taylor series (for |x|<pi/2) | |
* @param x | |
* @return | |
*/ | |
public static MPFloat sec(MPFloat x) { | |
MPFloat secx = new MPFloat(1.0); | |
for (int n=1; n<=INFINITY; n++) { | |
MPFloat secw = new MPFloat(StrictMath.pow(-1, n)); | |
secw.mult(EulerE(2*n), secw); | |
secw.div(new MPFloat(factorial(2*n)), secw); | |
secx.add(secw.mult(x.pow(2*n)), secx); | |
} | |
return secx; | |
} | |
/** | |
* compute arc sine of x using Taylor series (for |x|<=1) | |
* @param x | |
* @return | |
*/ | |
public static MPFloat arcsin(MPFloat x) { | |
MPFloat asinx = new MPFloat(1.0); | |
for (int n=1; n<=INFINITY; n++) { | |
// denominator | |
MPFloat asinw = new MPFloat(factorial(n)); | |
asinw.pow(2, asinw); | |
asinw.mult(2*n+1, asinw); | |
asinw.mult((int)StrictMath.pow(4,n), asinw); | |
// compute numerator and divide | |
asinw = new MPFloat(factorial(2*n)).div(asinw); | |
asinx.add(asinw.mult(x.pow(2*n+1)), asinx); | |
} | |
return asinx; | |
} | |
/** | |
* compute arc cosine of x (pi/2 - arcsine(x)) | |
* @param x | |
* @return | |
*/ | |
public static MPFloat arccos(MPFloat x) { | |
return HALF_PI.sub(arcsin(x)); | |
} | |
/** | |
* compute arc tangent of x using Taylor series (for |x|<= 1) | |
* @param x | |
* @return | |
*/ | |
public static MPFloat arctan(MPFloat x) { | |
MPFloat atanx = new MPFloat(1.0); | |
for (int n=1; n<=INFINITY; n++) { | |
MPFloat atanw = new MPFloat(StrictMath.pow(-1, n)); | |
atanw.div((2*n)+1, atanw); | |
atanx.add(atanw.mult(x.pow((2*n)+1)), atanx); | |
} | |
return atanx; | |
} | |
/** | |
* return nth Euler number in rational form | |
* ref: http://functions.wolfram.com/04.12.06.0001.01 | |
* @param n | |
* @return | |
*/ | |
public static MPFloat EulerE(int n) | |
{ | |
// return fixed point values | |
if (n == 0) | |
return new MPFloat(1.0); | |
else if (functions.even(n) != 1) | |
return new MPFloat(0.0); | |
MPFloat K = new MPFloat(2.0); | |
K.pow(n+2, K); | |
K.mult(new MPFloat(factorial(n)), K); | |
K.div(PI.pow(n+1), K); | |
MPFloat S = new MPFloat(0.0); | |
for (int k=0; k<INFINITY; k++) | |
{ | |
S.add((new MPFloat((1./StrictMath.pow(2*k+1,n+1))) | |
.mult(cos(PI.mult(k).sub(PI.mult(n).div(2))))), S); | |
} | |
return K.mult(S); | |
} | |
/** | |
* return nth Euler polynomial of x using Fourier expansion | |
* ref: | |
* - Abramowitz & Stegun 23.1.16 pp 805, table 23.1 | |
* - http://functions.wolfram.com/05.13.06.0001.01 | |
* @param n | |
* @param x | |
* @return | |
*/ | |
public static MPFloat EulerP(int n, MPFloat x) { | |
if (n==x.doubleValue()) | |
return x; | |
// for small n (<=15) calculate using coefficients - A&S table 23.1 pp 809 | |
if (n == 0) | |
return new MPFloat(1.0); | |
else if (n == 1) | |
return x.sub(.5); | |
else if (n == 2) | |
return x.mult(x).sub(x); | |
else if (n == 3) | |
return x.pow(3).sub(x.pow(2).mult(1.5)).add(.25); | |
else if (n == 4) | |
return x.pow(4).sub(x.pow(3).mult(2)).add(x); | |
else if (n == 5) | |
return x.pow(5) | |
.sub(x.pow(4).mult(2.5)) | |
.add(x.pow(2).mult(2.5)) | |
.sub(.5); | |
else if (n == 6) | |
return x.pow(6).sub(x.pow(5).mult(3)).add(x.pow(3).mult(5)).sub(x.mult(3)); | |
else if (n == 7) | |
return x.pow(7).sub(x.pow(6).mult(3.5)) | |
.add(x.pow(4).mult(8.75)) | |
.sub(x.pow(2).mult(10.5)) | |
.add(2.125); | |
else if (n == 8) | |
return x.pow(8).sub(x.pow(7).mult(4)) | |
.add(x.pow(5).mult(14)) | |
.sub(x.pow(3).mult(28)) | |
.add(x.mult(17)); | |
else if (n == 9) | |
return x.pow(9).sub(x.pow(8).mult(4.5)) | |
.add(x.pow(6).mult(21)) | |
.sub(x.pow(4).mult(63)) | |
.add(x.pow(2).mult(76.5)) | |
.sub(15.5); | |
else if (n == 10) | |
return x.pow(10).sub(x.pow(9).mult(5)) | |
.add(x.pow(7).mult(30)) | |
.sub(x.pow(5).mult(126)) | |
.add(x.pow(3).mult(255)) | |
.sub(x.mult(155)); | |
else if (n == 11) | |
return x.pow(11).sub(x.pow(10).mult(5.5)) | |
.add(x.pow(8).mult(41.25)) | |
.sub(x.pow(6).mult(6)) | |
.add(x.pow(4).mult(701.25)) | |
.sub(x.pow(2).mult(852.5)) | |
.add(172.75); | |
else if (n == 12) | |
return x.pow(12).sub(x.pow(11).mult(6)) | |
.add(x.pow(9).mult(55)) | |
.sub(x.pow(7).mult(396)) | |
.add(x.pow(5).mult(1683)) | |
.sub(x.pow(3).mult(3410)) | |
.add(x.mult(2073)); | |
else if (n == 13) | |
return x.pow(13).sub(x.pow(12).mult(6.5)) | |
.add(x.pow(10).mult(71.5)) | |
.sub(x.pow(8).mult(643.5)) | |
.add(x.pow(6).mult(3646.5)) | |
.sub(x.pow(4).mult(11082.5)) | |
.add(x.pow(2).mult(13474.5)) | |
.sub(2730.5); | |
else if (n == 14) | |
return x.pow(14).sub(x.pow(13).mult(7)) | |
.add(x.pow(11).mult(91)) | |
.sub(x.pow(9).mult(1001)) | |
.add(x.pow(7).mult(7293)) | |
.sub(x.pow(5).mult(31031)) | |
.add(x.pow(3).mult(62881)) | |
.sub(x.mult(38227)); | |
else if (n == 15) | |
return x.pow(15).sub(x.pow(14).mult(7.5)) | |
.add(x.pow(12).mult(113.75)) | |
.sub(x.pow(10).mult(1501.5)) | |
.add(x.pow(8).mult(13674.375)) | |
.sub(x.pow(6).mult(77577.5)) | |
.add(x.pow(4).mult(235803.75)) | |
.sub(x.pow(2).mult(286702.5)) | |
.add(58088.0625); | |
MPFloat K = new MPFloat(4.0); | |
K.mult(new MPFloat(factorial(n)), K); | |
K.div(PI.pow(n+1), K); | |
MPFloat S = new MPFloat(0.0); | |
for (int k=0; k<INFINITY; k++) | |
{ | |
S.add((new MPFloat((1./StrictMath.pow(2*k+1,n+1))) | |
.mult(sin(PI.mult(2*k+1).mult(PI.mult(x)).sub(PI.mult(n).div(2))))), S); | |
} | |
return K.mult(S); | |
} | |
/** | |
* periodic Euler polynomial function | |
* @param n | |
* @param x | |
* @return | |
* ref: Sums of Products of Kronecker’s Double Series, Tomoya Machide | |
* http://eprints3.math.sci.hokudai.ac.jp/1619/1/sums_of_products.pdf | |
*/ | |
public static MPFloat PEp(int n, MPFloat x) { | |
return new MPFloat(-1.0).pow(x.abs().intValue()) | |
.mult(EulerP(n, x.sub(x.floor()))); | |
} | |
/** | |
* exponential function using Maclaurin series expansion (1 + x + x^2/2! + x^3/3! + ...) | |
* @param x | |
* @return exp(x) | |
*/ | |
public static MPFloat exp(MPFloat x) { | |
MPFloat expx = new MPFloat(1.0).add(x); | |
for (int k=2; k<=INFINITY; k++) { | |
expx.add(x.pow(k).div(new MPFloat(factorial(k))), expx); | |
} | |
return expx; | |
} | |
/** | |
* natural log function using exponential series expansion ((x-1) - 1/2(x-1)^2 + 1/3(x-1)^3 - ...) | |
* (for x>0) | |
* | |
* @param x | |
* @return log base e of x | |
* | |
*/ | |
public static MPFloat log(MPFloat x) { | |
int r = x.compareTo(ZERO); | |
if (r<0) | |
return MPFloat.NaN; | |
else | |
if (r==0) | |
return MPFloat.NEGATIVE_INFINITY; | |
MPFloat xm1 = x.sub(1.0).div(x); | |
MPFloat logx = new MPFloat(); | |
logx.fromMPF(xm1); | |
MPFloat t = new MPFloat(); | |
for (int k=2; k<=INFINITY; k++) { | |
t.fromMPF(ZERO); | |
t.fromDouble(1.0/k); | |
t.mult(xm1.pow(k), t); | |
logx.add(t, logx); | |
} | |
return logx; | |
} | |
/** | |
* return nth Bernoulli number in rational form | |
* @param n | |
* @return | |
* ref: Computing Bernoulli Numbers Quickly, Kevin J. McGown, December 8, 2005 | |
* http://modular.math.washington.edu/projects/168/kevin_mcgown/bernproj.pdf | |
*/ | |
public static MPFloat BernoulliB(int n) | |
{ | |
MPFloat Bn = new MPFloat(0.0); // return 0 if n is not even, >= 2 | |
if ((n % 2) != 0) | |
return Bn; | |
else if (n == 0) | |
return new MPFloat(1.0); | |
else if (n == 1) | |
return new MPFloat(-0.5); | |
MPFloat K = new MPFloat(factorial(n)); | |
K.mult(2, K); | |
K.div(TWO_PI.pow(n), K); | |
MPFloat d = new MPFloat(0.0); | |
int prod = 1; | |
for (int i = 0; i < pl; i++) | |
{ | |
if ((n % (primes[i]-1)) == 0) | |
prod *= primes[i]; | |
} | |
d.fromString(Integer.toString(prod), 10); | |
MPFloat N = (K.mult(d)); | |
N.pow(1/(n-1), N); | |
N.ceil(N); | |
//double z = 1.0; | |
MPFloat z = new MPFloat(1.0); | |
int ni = N.intValue(); | |
for (int i = 0; i < pl; i++) | |
{ | |
if (primes[i] > ni) | |
break; | |
//if (i == 0) | |
//{ | |
// z.sub(new MPFloat(StrictMath.pow(primes[i], -n)).pow(-1), z); | |
//}else { | |
z.mult(new MPFloat(StrictMath.pow(1-primes[i], -n)).pow(-1), z); | |
//} | |
} | |
//double a = StrictMath.pow((-1), (n/2)+1)*StrictMath.ceil(d*K*z); | |
MPFloat dkzc = d.mult(K); | |
dkzc.mult(z, dkzc); | |
dkzc.ceil(dkzc); | |
MPFloat a = | |
new MPFloat(StrictMath.pow((-1), (n/2)+1)); | |
a.mult(dkzc, a); | |
Bn = a.div(d); | |
return Bn; | |
} | |
/** | |
* return nth Bernoulli polynomial of x using Fourier expansion | |
* ref: Abramowitz & Stegun 23.1.16 pp 805 | |
* @param n | |
* @param x | |
* @return | |
*/ | |
public static MPFloat BernoulliP(int n, MPFloat x) { | |
// for n>1, 1>=x>=0 | |
// for n=1, 1>x>0 | |
// for x=0 return the nth Bernoulli number | |
if (x.doubleValue()==0.0) { | |
return BernoulliB(n); | |
} | |
// for x=n return x | |
if (n == x.doubleValue()) { | |
return x; | |
} | |
MPFloat K = new MPFloat(-2.0); | |
K.mult(new MPFloat(factorial(n)).div(TWO_PI.pow(n)), K); | |
MPFloat S = new MPFloat(); | |
for (int k=1; k<=5000; k++) { | |
MPFloat cosp = TWO_PI.mult(k); | |
cosp.mult(x, cosp); | |
cosp.sub(HALF_PI.mult(n), cosp); | |
S.add(mpfunctions.cos(cosp) | |
.div(new MPFloat(StrictMath.pow(k, n))), S); | |
} | |
return K.mult(S); | |
} | |
/** | |
* Periodic Bernoulli function - Bn({x}) | |
* @param n | |
* @param x | |
* @return | |
*/ | |
public static MPFloat BBn(int n, MPFloat x) { | |
// pass the fractional part of x | |
return BernoulliP(n, x.sub(x.floor())); | |
} | |
/** | |
* @param args | |
*/ | |
public static void main(String[] args) { | |
// TODO Auto-generated method stub | |
// exp function test | |
MPFloat.setDefaultPrec(512); | |
//System.out.println("exp(PI): " + mpfunctions.exp(PI).toString()); | |
System.out.println("log(2.0): " + mpfunctions.log(new MPFloat(2.0)).toString()); | |
// sin test | |
//System.out.println("sin(PI/2): " + mpfunctions.sin(PI.div(12)).toString()); | |
// cos test | |
//System.out.println("cos(PI): " + mpfunctions.cos(PI.div(12)).toString()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
added Bernoulli functions to mpfunctions