2013-02-20 13 views
11

Mi chiedevo se c'è un modo per ottenere l'accesso al codice nativo per la classe Math. Più specificamente ho bisogno di vedere il codice per il metodo sin().codice nativo per Java Math classe

+0

Vuoi un decompilatore? – EAKAE

+0

No, sto cercando di creare il mio metodo sinusoidale e credo che sapere come funziona il metodo di classe Math potrebbe essere d'aiuto. – user2089351

risposta

17

Questo dipende dall'implementazione. Come indicato nella documentazione per java.lang.Math:

A differenza dei metodi numerici di classe StrictMath, tutte le implementazioni delle funzioni equivalenti della classe Math non sono definiti per restituire gli stessi risultati bit per bit. Questo rilassamento consente implementazioni più performanti laddove non è richiesta una rigida riproducibilità.

... I generatori di codice sono invitati a utilizzare librerie native specifiche della piattaforma o istruzioni del microprocessore, ove disponibili, per fornire implementazioni a prestazioni più elevate dei metodi Math. Tali implementazioni ad alte prestazioni devono ancora essere conformi alle specifiche per Math.

Per Dalvik (Android implementazione di 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; 
} 

Così chiama la funzione libmsin, che su Android viene fornita dallo libica bionica. Che assomiglia

bionico/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]); 
     } 
    } 
} 

e l'implementazione di __kernel_sin assomiglia

bionico/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 è simile.

+0

...? qual è il downvote per? – nneonneo

+0

anche io sono stato downvoted. qualche idiota qui. – AlexWien