2013-02-20 4 views
11

Ich habe mich gefragt, ob es irgendeinen Weg gibt, auf den nativen Code für die Math-Klasse zuzugreifen. Genauer gesagt muss ich den Code für die Methode sin() sehen.nativer Code für Java Math-Klasse

+0

Möchten Sie einen Decompiler? – EAKAE

+0

Nein, ich möchte meine eigene Sinus-Methode erstellen, und ich glaube, es wäre hilfreich zu wissen, wie die Math-Klassenmethode funktioniert. – user2089351

Antwort

17

Dies ist implementierungsabhängig. Was java.lang.Math in der Dokumentation angegeben:

Im Gegensatz zu einigen der numerischen Methoden der Klasse StrictMath, alle Implementierungen der äquivalenten Funktionen der Klasse Math sind nicht die Bit-für-Bit gleichen Ergebnisse zurück definiert. Diese Relaxation ermöglicht leistungsfähigere Implementierungen, bei denen keine strikte Reproduzierbarkeit erforderlich ist.

... Code-Generatoren werden empfohlen, plattformspezifische native Bibliotheken oder Mikroprozessoranweisungen zu verwenden, um leistungsfähigere Implementierungen der Math-Methoden bereitzustellen. Solche Implementierungen mit höherer Leistung müssen immer noch der Spezifikation für Math entsprechen.

Für Dalvik (die Android Implementierung von Java):

Dalvik/vm/InlineNative.c

/* 
* public static double sin(double) 
*/ 
static bool javaLangMath_sin(u4 arg0, u4 arg1, u4 arg2, u4 arg3, 
    JValue* pResult) 
{ 
    Convert64 convert; 
    convert.arg[0] = arg0; 
    convert.arg[1] = arg1; 
    pResult->d = sin(convert.dd); 
    return true; 
} 

es die libmsin Funktion So nennt, die auf Android geliefert bionische libc. Das sieht aus wie

bionische/libm/src/s_sin.c

double 
sin(double x) 
{ 
    double y[2],z=0.0; 
    int32_t n, ix; 

    /* High word of x. */ 
    GET_HIGH_WORD(ix,x); 

    /* |x| ~< pi/4 */ 
    ix &= 0x7fffffff; 
    if(ix <= 0x3fe921fb) { 
     if(ix<0x3e400000)   /* |x| < 2**-27 */ 
      {if((int)x==0) return x;} /* generate inexact */ 
     return __kernel_sin(x,z,0); 
    } 

    /* sin(Inf or NaN) is NaN */ 
    else if (ix>=0x7ff00000) return x-x; 

    /* argument reduction needed */ 
    else { 
     n = __ieee754_rem_pio2(x,y); 
     switch(n&3) { 
     case 0: return __kernel_sin(y[0],y[1],1); 
     case 1: return __kernel_cos(y[0],y[1]); 
     case 2: return -__kernel_sin(y[0],y[1],1); 
     default: 
      return -__kernel_cos(y[0],y[1]); 
     } 
    } 
} 

und die Umsetzung von __kernel_sin sieht aus wie

bionische/libm/src/k_sin.c

static const double 
half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */ 
S1 = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */ 
S2 = 8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */ 
S3 = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */ 
S4 = 2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */ 
S5 = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */ 
S6 = 1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */ 

double 
__kernel_sin(double x, double y, int iy) 
{ 
    double z,r,v; 

    z = x*x; 
    v = z*x; 
    r = S2+z*(S3+z*(S4+z*(S5+z*S6))); 
    if(iy==0) return x+v*(S1+z*r); 
    else  return x-((z*(half*y-v*r)-y)-v*S1); 
} 

__kernel_cos ist ähnlich.

+0

...? Wofür ist der Downvote? – nneonneo

+0

Ich wurde auch abgelehnt. ein Idiot hier. – AlexWien