2013-02-20 7 views
11

Mathクラスのネイティブコードにアクセスできる方法があるかどうかは疑問でした。具体的には、sin()メソッドのコードを参照する必要があります。Java Mathクラスのネイティブコード

+0

逆コンパイラを使用しますか? – EAKAE

+0

いいえ私は自分自身のサインメソッドを作成しようとしています。そして、私はMathクラスメソッドがどのように役立つかを知っていると信じています。 – user2089351

答えて

17

これは実装によって異なります。 java.lang.Mathのドキュメントに記載されているとおり:

クラス StrictMathの数値方法のいくつかとは異なり

、クラスMathの同等の機能のすべての実装は、ビットごとの同じ結果を返すように定義されていません。この緩和によって、厳密な再現性が要求されない優れた実装が可能になります。

...コードジェネレータは、プラットフォーム固有のネイティブライブラリまたはマイクロプロセッサ命令(利用可能な場合)を使用して、Mathメソッドの高性能な実装を提供することを推奨します。そのような高性能実装は、依然としてMathの仕様に準拠しなければなりません。 Dalvik(ジャワのAndroidの実装)については

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

だから、Androidの上で供給されlibmsin機能を呼び出しますバイオニックなlibc。それは

バイオニック/ 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]); 
     } 
    } 
} 

のように見えると__kernel_sinの実装は

バイオニック/ 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も同様です。

+0

...?何のためのdownvoteですか? – nneonneo

+0

私もダウン投票されました。いくつかのばかここに。 – AlexWien

関連する問題