2013-02-20 24 views
11

Math sınıfının yerel koduna erişebilmemin herhangi bir yolu olup olmadığını merak ediyordum. Daha spesifik olarak sin() yönteminin kodunu görmem gerekiyor.yerel kodu

+0

Bir decompiler ister misiniz? – EAKAE

+0

Hayır Kendi sinüs yöntemimi oluşturmaya çalışıyorum ve Math sınıf yönteminin nasıl işlediğini bildiğime inanıyorum. – user2089351

cevap

17

Bu, uygulamaya bağımlıdır. java.lang.Math belgelerinde belirtildiği gibi: sınıf StrictMath sayısal yöntemler, sınıf Math eşdeğer işlevleri tüm uygulamalarında, bazı farklı

bit-bit aynı sonuçları için tanımlanmamıştır. Bu gevşeme, katı tekrarlanabilirliğin gerekli olmadığı daha iyi performans gösteren uygulamalara izin verir.

... Kod üreteçleri, mevcut olduğunda, platformlara özgü yerel kitaplıkları veya mikroişlemci yönergelerini, Math yöntemlerinin daha yüksek performanslı uygulamalarını sağlamak için kullanmaya teşvik edilir. Böyle daha yüksek performanslı uygulamalar hala Math için şartnameye uygun olmalıdır.

Dalvik (Java Android uygulaması) için

:

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; 
} 

Yani tarafından sağlanan Android'de libmsin işlevini çağırır biyonik libc. Yani

biyonik/libm/src benziyor/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]); 
     } 
    } 
} 

ve __kernel_sin uygulanması

biyonik/libm/src gibi/k_sin.c

görünüyor
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 benzerdir.

+0

...? ne için düşüş var? – nneonneo

+0

Ben de reddedildi. Burada biraz aptal. – AlexWien