精华内容
下载资源
问答
  • 本文将专门解决 Java ME 没有“幂”方法 Math.pow() 的问题。我们将演示使用三种不同的方法开发同一个 ME 应用程序,并从中选出***的编程解决方案。要讨论此问题,我们先考察整数和分数幂参数,将我们的分析限于正...

    使用 Java 开发移动设备应用程序时,可能需要用到特定 Java VM 所没有的数学方法。本文将专门解决 Java ME 没有“幂”方法 Math.pow() 的问题。我们将演示使用三种不同的方法开发同一个 ME 应用程序,并从中选出***的编程解决方案。

    要讨论此问题,我们先考察整数和分数幂参数,将我们的分析限于正实数。我们将演示求整数问题和小数问题的解集相对而言比较容易(而不考虑指数的符号)。在大多数情况下,我们将使用示例问题 n = 82/3,其中我们会求出 n 的良好估计或实际解。如果初始指数事先不可用,则此问题的其他解(包括牛顿法和割线法)不易编程。虽然二分法是可行的解决方案,但我们将关注传统上不为人所探究的三个方法。***个是简单的(不过有时效率低下)几何衰变算法;而第二个方法将利用 Math.sqrt() 方法并保证在不超过 11 次迭代中收敛到一个近似解。第三个方法将使用泰勒级数逼近法求对数并对泰勒级数进行欧拉转换。

    产生整数解的 ME Math.pow() 方法

    传统上,Java Math.pow() 方法包含两个参数。这两个参数包括底数和指数。我们假定(最初)这两个参数均为整数,然后求出 ME 中与 Java 方法使用相同参数的 Math.pow() 方法的可编程解。此处,可编程解相当简单,如示例 1 所示。在本例中,我们仅运行以指数值为指标的倍乘循环。

    示例 1intpow(intx,inty)/*we define the power method with

    base x and power y (i.e., x^y)*/

    {

    intz = x;

    for(inti =1; i 

    return

    }

    当然,有人可能会发现需要求出非整数幂的值。正实数的简单解(无需访问 Math.pow() 方法)可能涉及使用 Math.log()。例如,请考虑 82/3 的情况。利用 2/3*ln(8) = 1.386294361 中自然对数的结果。要得到最终解,需要利用指数 1.386294361(特别指出 e1.386294361 = 4)。在这种情况下,可能不需要使用幂函数。遗憾的是,Java ME 也不支持 Math.log() 方法。没有 Math.pow() 或 Math.log() 方法时,我们会考虑使用朴素的“强力”试探性方法,应用 Math.sqrt() 方法以及自然对数(和欧拉 e)的泰勒级数逼近来求得 Java ME 问题的解。

    使用几何衰变算法作为强力解的 ME Math.pow()

    Java ME 的早期实现包括浮点主数据类型 float 和 double。最近,已添加了这些类型。现在我们将 Math.pow() 声明中的整型参数替换为 double 数据类型。

    可能需要在 Java ME Math.pow() 幂方法中使用小数指数。我们提供的生成 Math.pow() 的***种方法是使用几何衰变算法的朴素的“强力”试探性方法。简单而言,衰变算法以一个大于已知解的值开始,然后应用某个方法来衰变该值,直到该值非常逼近该解(有关简单线性衰变算法的演示,请参见示例 2)。在我们的例子中,将进一步演示向上述解收敛的几何形式。

    示例 2/* This example illustrates a simplistic decay algorithm that we will assume

    converges to our desired solution (a positive integer) */

    intn;// assume that n is the solution to the number we are trying to find

    intvarX =1000;//assume that we know the solution is less than or equal to 1000

    while( varX >0)

    {

    varX -=1;// decrement by 1

    if( varX == n)returnvarX;

    }

    在示例 2 中,我们从 1000 开始递减,直到找到预期的数字,假定预期数字是一个正整数。这种类型的算法构成了强力试探性方法的基础。

    使用类似的方法,我们可在遇到小数时应用此算法。假定我们需要求出 n 的值,其中 n = 82/3。要使用衰变算法,我们必须首先找到一个合适的起点,该点要等于或大于解本身。这对于带有正指数的正实数很容易做到。对于我们的示例,要对此解进行编程,对方法两边求立方,得到 n3=82 。当然,此方程与 n3=64 等效。之后,我们的起始值将变为 64,我们知道 n 必须小于 64(因为 n3 = 64)。注意,如果限于正实数,则此推导方法同样适用于任何正指数值。现在,我们可能需要设计一个循环来产生 n 的“充分接近”预期数字的解。我们再来看示例 3,它适合于所有正底数和正指数。

    示例 3doublepow(doublex,doubley )//we define our new power method for fractions

    {

    intden =1000;// specify arbitrary denominator

    intnum = (int)(y*den);// find numerator

    ints = (num/den)+1;

    /***********************************************************************

    ** Variable 's' provides the power for which we multiply the base to find

    ** our starting search value. For example, if we seek a solution for

    ** n = 8^(2/3), then we will use 8^2 or 64 as our starting value (which is

    ** generated in our next section of code.) Why? The solution for our

    ** problem (given that the base is positive) will always be less than or

    ** equal to the base times the numerator power.

    ************************************************************************/

    /***********************************************************************

    ** Because we set the denominator to an arbitrary high value,

    ** we must attempt to reduce the fraction. In the example below,

    ** we find the highest allowable fraction that we can use without

    ** exceeding the limitation of our primitive data types.

    ************************************************************************/

    doublez = Double.MAX_VALUE;

    while( z >= Double.MAX_VALUE )

    {

    den -=1;// decrement denominator

    num = (int)(y*den);// find numerator

    s = (num/den)+1;// adjust starting value

    // find value of our base number to the power of numerator

    z = x;

    for(inti =1; i 

    }

    /***********************************************************************

    ** Now we are going to implement the decay algorithm to find

    ** the value of 'n'.

    ************************************************************************/

    /***********************************************************************

    ** We now find 'n' to the power of 's'. We will then decrement 'n',

    ** finding the value of 'n' to the power of the denominator. This

    ** value, variable 'a', will be compared to 'z'. If the 'a' is nearly

    ** equal to 'z', then we will return 'n', our desired result.

    ************************************************************************/

    doublen = x;// We define 'n' as our return value (estimate) for 'x'.

    // find 'n' to the power of 's'.

    for(inti =1; i 

    // Begin decay loop

    while( n >0)

    {

    doublea = n;//proxy for n

    // find 'a', the value of 'n' to the power of denominator

    for(inti =1; i 

    // compare 'a' to 'z'. Is the value within the hundred-thousandth?

    // if so, return 'n'.

    doublecheck1 = a-z;

    doublecheck2 = z-a;

    if( check1  .00001)returnn;

    n *= .999;// We arbitrarily use a decay of .1% per iteration

    }

    // value could not be found, return -1.

    return-1.0;

    }

    本示例演示了衰变算法的使用方法。您会注意到,n 的值(解的估计值)将按 1% 强制递减。您可能需要根据编程精度要求来改变此值。也可能考虑包括编程逻辑,该逻辑用于将前一迭代解与当前迭代进行比较,然后,如果有改善继续进行迭代,但是,如果解已回归,则返回前一个值。

    这里讲述的解只处理正指数。如果值为负会出现什么情况呢?下面我们将解决这种意外情况。

    处理负指数

    要再增加一层复杂度,假定正在向 Math.pow() 方法传递负指数。在这种情况下,指数为负,一种简单的解决方案是将底数转换为小数,使指数为正。例如,8-2 可转换为 (1/8)2。我们以可编程的方式用底数 x 来除 1,用 -1 来乘 y(参见示例 6)。

    示例 6if( y <0)

    {

    x = (1/x);// convert base number to fraction

    y *= -1;// make exponent positive

    }

    现在,我们已经讨论了用于在 Java ME 中估计幂函数的“强力”几何衰变算法。读者会注意到,对于较大的底数和指数分子组合,朴素的“强力”试探性方法有性能问题。请考虑示例 85/2。使用此算法的起始值将为 85 = 32,768。如果使用 1% 的衰变,则要求全部 5196 次迭代都求该解,这样几乎达不到***。谨记此事实并且不提供改善的试探性搜索算法,我们转到二次逼近,这会提供更多合理的迭代要求。

    使用 Math.sqrt() 方法的 ME Math.pow()

    开发我们的 Math.pow() 方法的第二种方法是通过使用 Math.sqrt() 方法(参见示例 7)。使用Math.sqrt() 方法要求我们对具有偶分母的幂进行估计。例如,n = 82/3 => n3 = 82 是一个棘手问题,因为我们需要立方根,而非平方根。为了调整示例中的此问题,我们我们就对两端再求一次平方:n3 = 82 => n6 = 84。然后,我们就可以继续进行,恰好在两次迭代之内求出解。

    当然,我们的 ME Math.pow() 方法的指数不会以分子和分母的形式开始,而是向我们传递一个实数。我们将此实数转换为具有偶分母的小数,然后利用相应的平方根数来对

    n 求解。在我们的 n = 82/3 示例中,我们进行如下转换:

    n = 82/3 => n = 8683/1024 => n1024 = 8683

    我们选择 1024 作为分母,因为对平方根函数迭代 10 次将得到 n 的值。特别指出,(n1024)(1/(2^10)) = n。当然,我们可能需要根据方程右侧的大小来减少迭代次数。示例 7 演示了这种方法。

    示例 7ouble pow(doublex,doubley)

    {

    //Convert the real power to a fractional form

    intden =1024;//declare the denominator to be 1024

    /*Conveniently 2^10=1024, so taking the square root 10

    times will yield our estimate for n. In our example

    n^3=8^2n^1024 = 8^683.*/

    intnum = (int)(y*den);// declare numerator

    intiterations =10;/*declare the number of square root

    iterations associated with our denominator, 1024.*/

    doublen = Double.MAX_VALUE;/* we initialize our

    estimate, setting it to max*/

    while( n >= Double.MAX_VALUE && iterations >1)

    {

    /* We try to set our estimate equal to the right

    hand side of the equation (e.g., 8^2048). If this

    number is too large, we will have to rescale. */

    n = x;

    for(inti=1; i 

    /*here, we handle the condition where our starting

    point is too large*/

    if( n >= Double.MAX_VALUE )

    {

    iterations--;/*reduce the iterations by one*/

    den = (int)(den /2);/*redefine the denominator*/

    num = (int)(y*den);//redefine the numerator

    }

    }

    /*************************************************

    ** We now have an appropriately sized right-hand-side.

    ** Starting with this estimate for n, we proceed.

    **************************************************/

    for(inti =0; i 

    {

    n = Math.sqrt(n);

    }

    // Return our estimate

    returnn;

    }

    自然对数和欧拉 e 的泰勒级数逼近

    对于正实数产生 Math.pow() 方法最简便的方式之一是链接几个方法,包括使用 泰勒级数。假定我们需要幂 y = xb。该式与 ln(y) = b*ln(x) 等价。进而,我们可以使用泰勒级数扩展估算 x 的自然对数,如下所示。ln(x) = (x-1) –(x-1)2/2+ (x-1)3/3- (x-1)4/4….if|x-1|<=1OR

    ln(x) =1/(x/(x-1)) +1/(x/(x-1))2+1/(x/(x-1))3…if|x|>1

    由于 x 为正,因而 x 的整个域为这些方程所覆盖。此交错级数可以提供对底数对数的非常接近的逼近。用指数乘以此对数将得到 ln(y),方程的右侧 ln(y)=b*ln(x)。现在,我们仅需求出 eln(y) 即可完成运算。我们使用另一个泰勒级数扩展来完成此过程:ex = 1 + x + x2 / 2! + x3 / 3! + … 使用这两个公式,即可求得问题的解,如示例 8 所示。

    示例 8doublepow(doublea,doubleb)

    {

    // true if base is greater than 1

    booleangt1 = (Math.sqrt((a-1)*(a-1)) <=1)?false:true;

    intoc = -1;// used to alternate math symbol (+,-)

    intiter =20;// number of iterations

    doublep, x, x2, sumX, sumY;

    // is exponent a whole number?

    if( (b-Math.floor(b)) ==0)

    {

    // return base^exponent

    p = a;

    for(inti =1; i 

    returnp;

    }

    x = (gt1)?

    (a /(a-1)):// base is greater than 1

    (a-1);// base is 1 or less

    sumX = (gt1)?

    (1/x):// base is greater than 1

    x;// base is 1 or less

    for(inti =2; i 

    {

    // find x^iteration

    p = x;

    for(intj =1; j 

    doublexTemp = (gt1)?

    (1/(i*p)):// base is greater than 1

    (p/i);// base is 1 or less

    sumX = (gt1)?

    (sumX+xTemp):// base is greater than 1

    (sumX+(xTemp*oc));// base is 1 or less

    oc *= -1;// change math symbol (+,-)

    }

    x2 = b * sumX;

    sumY =1+x2;// our estimate

    for(inti =2; i <= iter; i++ )

    {

    // find x2^iteration

    p = x2;

    for(intj =1; j 

    // multiply iterations (ex: 3 iterations = 3*2*1)

    intyTemp =2;

    for(intj = i; j >2; j-- )yTemp *= j;

    // add to estimate (ex: 3rd iteration => (x2^3)/(3*2*1) )

    sumY += p/yTemp;

    }

    returnsumY;// return our estimate

    }

    几乎在所有情况下,由泰勒级数逼近返回的估计比衰变算法方法更为精确,而 Math.sqrt() 也可以产生更好的结果。泰勒级数方法所使用的计算周期较少, 但在值趋于 0 时会不稳定。Math.sqrt() 结果可以提供良好的逼近,通常到第三位数字。有关使用多个任意分配的正实型变量的方法的比较,请参见表 1。我们可以看到,对于实际应用, Math.sqrt() 或泰勒级数方法对于是大多数值都比较优良。

    表 1:衰变算法和平方根方法的比较

    底数,指数 实际结果 泰勒级数逼近 Math.sqrt() 估计值 衰变算法估计值

    8.0, 0.75 4.75682846 4.7423353221144557 4.75682846 4.751286816

    8.0, 0.667 4.002774 3.9919355054959973 3.994588452 3.994453662

    16.0, 8.0 4294967296 4294967296 4294967296 4294752931

    32.0, 5.0 33554432 33554432 33554432 33553177.47

    11.0, 3.0 1331 1331 1331 1330.967224

    10.0, 10.0 10000000000 10000000000 10000000000 9999699608

    77.0, 3.0 456533 456533 456533 456527.6254

    5.0, 15.0 30517578125 30517578125 30517578125 30516279235

    15.0, 9.0 38443359375 38443359375 38443359375 38440083836

    3.0, 21.0 10460353203 10460353203 10460353203 10459907131

    5.0, 0.05 1.083798387 1.0837883791740017 1.083457755 1.08205432

    7.0, 0.37 2.054406 2.0529191207908064 2.050973357 2.051043668

    1.5, 0.789 1.377006542 1.377006541546755 1.376496289 1.376798426

    1.5, 3.789 4.647397078 4.647381683179335 4.64015972 4.644836289

    0.06282, 0.325784 0.405919146 0.41327102396968585 0 0.06282

    0.7261, 0.20574 0.936270645 0.9362706445348806 0.93646901 0.7261

    0.903272, 0.48593 0.951767579 0.951767579257642 0.951823588 0.903272

    0.821111, 0.767392 0.85963221 0.8596322100794738 0.859766145 0.821111

    0.24352, .004322 0.99391353 0.9939136545397182 0.994497397 0.24352

    0.000125, .99556 0.000130089 627097113.1963351 0 0.000125

    编程注意事项和结论

    本文已经解决了在 Java ME 中开发 Math.pow() 方法的三种途径。虽然朴素的“强力”几何衰变试探性方法比较不错,而且对于小问题可能很有用处,但是 Math.sqrt() 改写对于大多数范围的应用可能要好一些。***方法可能是泰勒级数逼近。显然,这三个示例均未包括完成该任务的特有方法(如二分法及参考资料中介绍的其他方法),并且我们希望其他方法可以提供占用较少资源的更为高效的技巧。***需要注意的一点是:如果要求您开发此类方法,务必考虑其应用,所需的参数以及预期的结果和精度。

    【编辑推荐】

    【责任编辑:red7 TEL:(010)68476606】

    点赞 0

    展开全文
  • 本文将专门解决 Java ME没有“幂”方法 Math.pow() 的问题。我们将演示使用三种不同的方法开发同一个 ME 应用程序,并从中选出最佳的编程解决方案。要讨论此问题,我们先考察整数和分数幂参数,将我们的分析限于正...

    使用 Java 开发移动设备应用程序时,可能需要用到特定 Java VM 所没有的数学方法。本文将专门解决 Java ME

    没有“幂”方法 Math.pow() 的问题。我们将演示使用三种不同的方法开发同一个 ME 应用程序,并从中选出最佳的编程解决方案。

    要讨论此问题,我们先考察整数和分数幂参数,将我们的分析限于正实数。我们将演示求整数问题和小数问题的解集相对而言比较容易(而不考虑指数的符号)。在大多数情况下,我们将使用示例问题

    n = 82/3,其中我们会求出 n

    的良好估计或实际解。如果初始指数事先不可用,则此问题的其他解(包括牛顿法和割线法)不易编程。虽然二分法是可行的解决方案,但我们将关注传统上不为人所探究的三个方法。第一个是简单的(不过有时效率低下)几何衰变算法;而第二个方法将利用

    Math.sqrt() 方法并保证在不超过 11

    次迭代中收敛到一个近似解。第三个方法将使用泰勒级数逼近法求对数并对泰勒级数进行欧拉转换。

    产生整数解的 ME Math.pow() 方法

    传统上,Java Math.pow()

    方法包含两个参数。这两个参数包括底数和指数。我们假定(最初)这两个参数均为整数,然后求出 ME 中与 Java 方法使用相同参数的

    Math.pow() 方法的可编程解。此处,可编程解相当简单,如示例 1 所示。在本例中,我们仅运行以指数值为指标的倍乘循环。

    示例 1

    int

    pow( int x,

    int y){int z =

    x;for( int

    i = 1; i

    < y; i++

    )z *= x;

    return

    }

    当然,有人可能会发现需要求出非整数幂的值。正实数的简单解(无需访问 Math.pow() 方法)可能涉及使用

    Math.log()。例如,请考虑 82/3 的情况。利用 2/3*ln(8) = 1.386294361

    中自然对数的结果。要得到最终解,需要利用指数 1.386294361(特别指出 e1.386294361 =

    4)。在这种情况下,可能不需要使用幂函数。遗憾的是,Java ME 也不支持 Math.log() 方法。没有 Math.pow()

    或 Math.log() 方法时,我们会考虑使用朴素的“强力”试探性方法,应用 Math.sqrt() 方法以及自然对数(和欧拉

    e)的泰勒级数逼近来求得 Java ME 问题的解。

    使用几何衰变算法作为强力解的 ME Math.pow()

    Java ME 的早期实现包括浮点主数据类型 float 和 double。最近,已添加了这些类型。现在我们将

    Math.pow() 声明中的整型参数替换为 double 数据类型。

    可能需要在 Java ME Math.pow() 幂方法中使用小数指数。我们提供的生成 Math.pow()

    的第一种方法是使用几何衰变算法的朴素的“强力”试探性方法。简单而言,衰变算法以一个大于已知解的值开始,然后应用某个方法来衰变该值,直到该值非常逼近该解(有关简单线性衰变算法的演示,请参见示例

    2)。在我们的例子中,将进一步演示向上述解收敛的几何形式。

    示例 2

    int n; //

    assume that n is the

    solution to the number we are trying to findint varX =

    1000;//assume that

    we know the solution is

    less than or equal to 1000while(

    varX >

    0 )

    {

    varX -= 1;

    // decrement by 1if( varX == n)return

    varX;

    }

    在示例 2 中,我们从 1000

    开始递减,直到找到预期的数字,假定预期数字是一个正整数。这种类型的算法构成了强力试探性方法的基础。

    使用类似的方法,我们可在遇到小数时应用此算法。假定我们需要求出 n 的值,其中 n =

    82/3。要使用衰变算法,我们必须首先找到一个合适的起点,该点要等于或大于解本身。这对于带有正指数的正实数很容易做到。对于我们的示例,要对此解进行编程,对方法两边求立方,得到

    n3=82 。当然,此方程与 n3=64 等效。之后,我们的起始值将变为 64,我们知道 n 必须小于 64(因为 n3 =

    64)。注意,如果限于正实数,则此推导方法同样适用于任何正指数值。现在,我们可能需要设计一个循环来产生 n

    的“充分接近”预期数字的解。我们再来看示例 3,它适合于所有正底数和正指数。

    示例 3

    double

    pow( double x, double y

    )//we define our new power

    method for fractions

    {int den =

    1000; //

    specify arbitrary denominatorint num =

    (int)(y*den);

    // find numeratorint s =

    (num/den)+1;double z =

    Double.MAX_VALUE;while( z >= Double.MAX_VALUE )

    {

    den -=1;

    // decrement denominator

    num = (int)(y*den);

    // find numerator

    s = (num/den)+1;

    // adjust starting value// find value of our base number to the power

    of numerator

    z = x;for( int

    i = 1; i

    < num; i++ )z

    *= x;

    }double n =

    x; // We

    define 'n' as our return value (estimate) for

    'x'.//

    find 'n' to the

    power of 's'.for(

    int i =

    1;

    i <

    s; i++)n

    *= x;// Begin decay loopwhile( n > 0 )

    {double a =

    n; //proxy

    for n// find 'a', the value

    of 'n' to the power of denominatorfor(

    int i =

    1;

    i <

    den; i++ )a

    *= n;// compare 'a' to 'z'. Is

    the value within the hundred-thousandth?//

    if so, return 'n'.double check1 = a-z;double check2 = z-a;if( check1 < .00001||

    check2 >

    .00001 ) return

    n;

    n *= .999;//

    We arbitrarily use a decay of

    .1% per iteration

    }// value could not be found,

    return -1.

    return -1.0;

    }

    本示例演示了衰变算法的使用方法。您会注意到,n 的值(解的估计值)将按 1%

    强制递减。您可能需要根据编程精度要求来改变此值。也可能考虑包括编程逻辑,该逻辑用于将前一迭代解与当前迭代进行比较,然后,如果有改善继续进行迭代,但是,如果解已回归,则返回前一个值。

    这里讲述的解只处理正指数。如果值为负会出现什么情况呢?下面我们将解决这种意外情况。

    处理负指数

    要再增加一层复杂度,假定正在向 Math.pow()

    方法传递负指数。在这种情况下,指数为负,一种简单的解决方案是将底数转换为小数,使指数为正。例如,8-2 可转换为

    (1/8)2。我们以可编程的方式用底数 x 来除 1,用 -1 来乘 y(参见示例 6)。

    示例 6

    if(

    y <

    0 )

    {

    x = (1/x);

    // convert base number to fraction

    y *= -1;

    // make exponent positive

    }

    现在,我们已经讨论了用于在 Java ME

    中估计幂函数的“强力”几何衰变算法。读者会注意到,对于较大的底数和指数分子组合,朴素的“强力”试探性方法有性能问题。请考虑示例

    85/2。使用此算法的起始值将为 85 = 32,768。如果使用 1% 的衰变,则要求全部 5196

    次迭代都求该解,这样几乎达不到最优。谨记此事实并且不提供改善的试探性搜索算法,我们转到二次逼近,这会提供更多合理的迭代要求。

    使用 Math.sqrt() 方法的 ME Math.pow()

    开发我们的 Math.pow() 方法的第二种方法是通过使用 Math.sqrt() 方法(参见示例

    7)。使用Math.sqrt() 方法要求我们对具有偶分母的幂进行估计。例如,n = 82/3 =>

    n3 = 82 是一个棘手问题,因为我们需要立方根,而非平方根。为了调整示例中的此问题,我们我们就对两端再求一次平方:n3 = 82

    => n6 = 84。然后,我们就可以继续进行,恰好在两次迭代之内求出解。

    当然,我们的 ME Math.pow()

    方法的指数不会以分子和分母的形式开始,而是向我们传递一个实数。我们将此实数转换为具有偶分母的小数,然后利用相应的平方根数来对 n

    求解。在我们的 n = 82/3 示例中,我们进行如下转换:

    n

    = 82/3

    => n =

    8683/1024

    => n1024 =

    8683

    我们选择 1024 作为分母,因为对平方根函数迭代 10 次将得到 n 的值。特别指出,(n1024)(1/(2^10))

    = n。当然,我们可能需要根据方程右侧的大小来减少迭代次数。示例 7 演示了这种方法。

    示例 7

    double

    pow(double x, double y)

    {//Convert the real power to a

    fractional formint den =

    1024; //declare the

    denominator to

    be 1024int num =

    (int)(y*den);

    // declare numeratorint iterations = 10;double n =

    Double.MAX_VALUE; while( n >= Double.MAX_VALUE &&

    iterations > 1)

    {n = x;for( int

    i=1; i

    < num; i++ )n*=x;if( n >= Double.MAX_VALUE )

    {

    iterations--;den = (int)(den /

    2);num = (int)(y*den);

    //redefine the numerator

    }

    }for( int

    i = 0; i

    < iterations; i++ )

    {

    n = Math.sqrt(n);

    }// Return our estimate

    return n;

    }

    自然对数和欧拉 e 的泰勒级数逼近

    对于正实数产生 Math.pow() 方法最简便的方式之一是链接几个方法,包括使用 泰勒级数。假定我们需要幂 y =

    xb。该式与 ln(y) = b*ln(x) 等价。进而,我们可以使用泰勒级数扩展估算 x 的自然对数,如下所示。

    ln(x)

    = (x-1)

    –(x-1)2/2

    + (x-1)3/3

    -(x-1)4/4….if

    |x-1|<=1 ORln(x) = 1/(x/(x-1))

    + 1/(x/(x-1))2

    + 1/(x/(x-1))3…

    if |x|>1

    由于 x 为正,因而 x 的整个域为这些方程所覆盖。此交错级数可以提供对底数对数的非常接近的逼近。用指数乘以此对数将得到

    ln(y),方程的右侧 ln(y)=b*ln(x)。现在,我们仅需求出 eln(y)

    即可完成运算。我们使用另一个泰勒级数扩展来完成此过程:ex = 1 + x + x2 / 2! + x3 / 3! + …

    使用这两个公式,即可求得问题的解,如示例 8 所示。

    示例 8

    double

    pow(double a, double b)

    {// true if

    base is greater

    than 1boolean gt1 =

    (Math.sqrt((a-1)*(a-1))

    <= 1)?

    false:true;int oc =

    -1;

    // used to

    alternate math symbol

    (+,-)int iter =

    20; //

    number of iterationsdouble p, x, x2, sumX, sumY;// is exponent a

    whole number?if( (b-Math.floor(b)) == 0

    )

    {// return base^exponent

    p = a;for( int

    i = 1; i

    < b; i++

    )p *= a;

    return p;

    }

    x = (gt1)?

    (a /(a-1)):

    // base is

    greater than 1(a-1);

    // base is

    1 or less

    sumX = (gt1)?

    (1/x):

    // base is

    greater than 1x; // base is

    1 or lessfor( int

    i = 2; i

    < iter; i++ )

    {// find x^iteration

    p = x;for( int

    j = 1; j

    < i; j++)p

    *= x;double xTemp =

    (gt1)?

    (1/(i*p)):

    // base is

    greater than 1(p/i); //

    base is 1

    or less

    sumX = (gt1)?

    (sumX+xTemp): // base

    is greater than 1(sumX+(xTemp*oc));

    // base is

    1 or less

    oc *= -1;

    // change math symbol (+,-)

    }

    x2 = b *

    sumX;

    sumY = 1+x2;

    // our estimatefor( int

    i = 2; i

    <= iter; i++ )

    {// find x2^iteration

    p = x2;for( int

    j = 1; j

    < i; j++)p

    *= x2;// multiply iterations (ex: 3 iterations = 3*2*1)int yTemp =

    2;for( int

    j = i; j

    > 2;

    j-- )yTemp *= j;// add to

    estimate (ex: 3rd iteration

    => (x2^3)/(3*2*1) )

    sumY += p/yTemp;

    }

    return sumY; //

    return our estimate

    }

    几乎在所有情况下,由泰勒级数逼近返回的估计比衰变算法方法更为精确,而 Math.sqrt()

    也可以产生更好的结果。泰勒级数方法所使用的计算周期较少, 但在值趋于 0 时会不稳定。Math.sqrt()

    结果可以提供良好的逼近,通常到第三位数字。有关使用多个任意分配的正实型变量的方法的比较,请参见表 1。我们可以看到,对于实际应用,

    Math.sqrt() 或泰勒级数方法对于是大多数值都比较优良。

    表 1:衰变算法和平方根方法的比较

    底数,指数 实际结果 泰勒级数逼近 Math.sqrt() 估计值 衰变算法估计值

    8.0, 0.75 4.75682846 4.7423353221144557 4.75682846

    4.751286816

    8.0, 0.667 4.002774 3.9919355054959973 3.994588452

    3.994453662

    16.0, 8.0 4294967296 4294967296 4294967296 4294752931

    32.0, 5.0 33554432 33554432 33554432 33553177.47

    11.0, 3.0 1331 1331 1331 1330.967224

    10.0, 10.0 10000000000 10000000000 10000000000 9999699608

    77.0, 3.0 456533 456533 456533 456527.6254

    5.0, 15.0 30517578125 30517578125 30517578125 30516279235

    15.0, 9.0 38443359375 38443359375 38443359375 38440083836

    3.0, 21.0 10460353203 10460353203 10460353203 10459907131

    5.0, 0.05 1.083798387 1.0837883791740017 1.083457755

    1.08205432

    7.0, 0.37 2.054406 2.0529191207908064 2.050973357

    2.051043668

    1.5, 0.789 1.377006542 1.377006541546755 1.376496289

    1.376798426

    1.5, 3.789 4.647397078 4.647381683179335 4.64015972

    4.644836289

    0.06282, 0.325784 0.405919146 0.41327102396968585 0

    0.06282

    0.7261, 0.20574 0.936270645 0.9362706445348806 0.93646901

    0.7261

    0.903272, 0.48593 0.951767579 0.951767579257642 0.951823588

    0.903272

    0.821111, 0.767392 0.85963221 0.8596322100794738 0.859766145

    0.821111

    0.24352, .004322 0.99391353 0.9939136545397182 0.994497397

    0.24352

    0.000125, .99556 0.000130089 627097113.1963351 0 0.000125

    编程注意事项和结论

    本文已经解决了在 Java ME 中开发 Math.pow()

    方法的三种途径。虽然朴素的“强力”几何衰变试探性方法比较不错,而且对于小问题可能很有用处,但是 Math.sqrt()

    改写对于大多数范围的应用可能要好一些。最佳方法可能是泰勒级数逼近。显然,这三个示例均未包括完成该任务的特有方法(如二分法及参考资料中介绍的其他方法),并且我们希望其他方法可以提供占用较少资源的更为高效的技巧。最后需要注意的一点是:如果要求您开发此类方法,务必考虑其应用,所需的参数以及预期的结果和精度。

    展开全文
  • number= base*Math.pow(10, exponent); So, how do I avoid the rounding error? (There are ways that I can work around it, but if it's possible to do, then I'd like to know how to fix the issue) Thanks. ...

    I'm having trouble with (what I suspect is) a rounding error.

    I have a string, 0.686357E-01, which I'm trying to convert to a double. I've been able to split it up using the Pattern.split() function, and I'm capturing the base and the exponent values just fine. However, once I try to multiply them appropriately, I get this as a result: 0.06863570000000001.

    Here's my relevant code:

    pattern = Pattern.compile("E\\+?");

    String[] number = pattern.split(string);

    double base = Double.parseDouble(number[0]);

    int exponent = Integer.parseInt(number[1]);

    number= base*Math.pow(10, exponent);

    So, how do I avoid the rounding error? (There are ways that I can work around it, but if it's possible to do, then I'd like to know how to fix the issue)

    Thanks.

    解决方案

    You don't need to split it, Double.parseDouble can handle those kinds of numbers just fine.

    double number = Double.parseDouble("0.686357E-01");

    展开全文
  • Math.pow用法及实现探究

    千次阅读 2021-02-26 20:01:11
    pow函数在java.lang.Math类中,是求次方的函数,定义为:public static double pow(double a, double b);即求a的b次方,例如:public static void main(String[] args) {double a = 2.0D;double b = 4.0D;double r ...

    pow函数在java.lang.Math类中,是求次方的函数,定义为:

    public static double pow(double a, double b);

    即求a的b次方,例如:

    public static void main(String[] args) {

    double a = 2.0D;

    double b = 4.0D;

    double r = Math.pow(a, b);

    System.out.println(r);

    //输出为16.0

    }

    查看源码,发现其实现调用了StrictMath类的pow函数,并且,Math中很多函数都调是直接调用了StrictMath类中的函数,而在StrictMath类中方法用native修饰,表明调用的并非java代码,而是其它的。经了解,这里是C代码来实现这些方法的,而这些源码在jdk中并没有公布。

    遂思考如何用java来实现呢?最先想到用循环和递归两种方式可实现。如下:

    为简化逻辑实现,只考虑了自然数(0和正整数)次幂。

    1、循环实现:

    static int mypow(int x, inty)

    {if(y < 0){return 0;

    }if(y == 0){return 1;

    }if(y == 1){returnx;

    }int result =x;for (int i = 1; i < y; i++) {

    result*=x;

    }returnresult;

    }

    2、递归实现:

    static int mypow(int x, inty)

    {if(y < 0){return 0;

    }if(y == 0){return 1;

    }if(y == 1){returnx;

    }int result = 0;int tmp = mypow(x, y/2);if(y % 2 != 0) //奇数

    {

    result= x * tmp *tmp;

    }else{

    result= tmp *tmp;

    }returnresult;

    }

    注:本文所述内容基于JDK1.7。

    水平有限,上述观点难免有误,仅供参考。欢迎牛们拍砖!

    展开全文
  • Is there a difference in the results returned by Python's built-in pow(x, y) (no third argument) and the values returned by math.pow(), in the case of two float arguments.I am asking this question bec...
  • Java Math.pow() 方法

    2021-02-12 16:40:00
    Java Math.pow() 方法java.lang.Math.pow() 方法用于返回第一个参数的第二个参数次方。pow() 方法的返回类型为double。1 语法public static double pow(double a, double b)2 参数a :基数b :指数3 返回值此方法...
  • python利用math.powpow和 ** 进行指数运算的问题 1、问题说明 2、接下来对math.pow(),pow() 和 ** 进行简单介绍 3、进行实验 - 发现(1) - 发现(2) - 发现(3) - 发现(4) 4、 进一步的实验 1、问题说明 在刷力扣的...
  • I would like to ask time complexity of the following code.... (Is time complexity of Math.pow() O(1)? ) In general, is Math.pow(a,b) has time complexity O(b) or O(1)? Thanks in advance.publ...
  • Math.pow()的用法

    2021-08-09 20:53:00
    Math.pow(底数,几次方) 实例1——用于开根号 题目详情 小 A 有两块球形橡皮泥,一个半径是 4,一个半径是 10。他想把这两块橡皮泥揉在一起,然后塑造成一个正方体,请问这个正方体的棱长是多少?如果结果不是整数,...
  • 本文实例讲述了Python中pow()和math.pow()函数用法。共享给大家供大家参考,详细如下:1. 内置函数pow()>>> help(pow)Help on built-in function pow in module __builtin__:pow(...)pow(x, y[, z]) -> ...
  • I have do to a question to write a method to input an array of type LONG that stores the values of all the powers of 2 from 0 to 63 (i... 20 to 263)Output the contects of the array screen.Hint: Math.p...
  • @[TOC](python 中 math.pow() 和 pow() 的区别) 在做算法题的时候发现 python 中的 math.pow() 和 pow() 计算结果不太一样,在网上搜索了一下,看了简书上一位博主写的文章,觉得例子很有代表性,所以拿过来做一下...
  • 指数运算符(**) console.log(2 ** 2); // 4 console.log(3 ** 2); // 9 console.log('3' ** '2'); // 9 console.log((() => { ...Math.pow() ...Math.pow(x,y)//x:基数y:指数 console.lo...
  • Java中Math.pow()的用法

    2021-03-05 15:13:02
    Java中Math.pow()的用法1.问题描述153是一个非常特殊的数,它等于它的每位数字的立方和,即153=1*1*1+5*5*5+3*3*3。编程求所有满足这种条件的三位十进制数。输出格式按从小到大的顺序输出满足条件的三位十进制数,每...
  • 昨天我看到一个问题,问为什么Math.pow(int,int)这么慢,但是问题措辞不佳,没有进行任何研究,因此很快就关闭了。我做了一些自我测试,发现与整数参数相比,Math.pow方法实际上比我自己的幼稚实现(甚至不是一个特别...
  • //直接定位区间 while (n > sum) { sum = (int)(9 * Math.pow(10, digit -1) * digit); //指数方法,统计每个区间(一位数,二位数等的区间数量总和) if (n > sum) { n -= sum; digit++; } } //第几个,如thNum=3,...
  • JavaScript 中 Math.pow()函数的用法

    千次阅读 2021-02-25 14:30:21
    Math.pow(x,y) x=底数 , y=底数的几次方 如:var a=3; var b=3; varc=Math.pow(a,b); 就是3的三次方是多少; c最终为27; Math.pow(底数,几次方) 直接使用Math.pow(a,3)即可,即等于求a的3次方。 基础用法:用...
  • 如果您查看Java Math类的源代码,您会发现它调用StrictMath.pow(double1,double2),StrictMath的签名是public static native pow(double a,double b);所以,最终,这是一个真正的本地电话,可能会因平台而有所不同.然而,...
  • 代码Code highlighting produced by Actipro CodeHighlighter (freeware)...Javascript四舍五入(Math.round()与Math.pow())//Math.round(x);返回数字最接近的整数,四舍五入取整数,即舍去小数部分function f(){ale...
  • 你在你的表达式中的一部分利用Math.Pow(),但是,你会想在谈话过程中,后来给出的表达式的第一部分使用Math.Sqrt()。其次,与表达中的括号分组导致表达的错误评价的问题第三,你将需要你没有一个十进制值,以评估...
  • Math.pow(x,1/y)表示对x开y次方根,比如Math.pow(x,1/2)是求x的平方根,相当于Math.sqrt(x)
  • 实现Math.pow(x,n)

    2021-09-19 10:05:32
    实现 pow(x, n) ,即计算 x 的 n 次幂函数(即,xn)。 示例 1: 输入:x = 2.00000, n = 10 输出:1024.00000 示例 2: 输入:x = 2.10000, n = 3 输出:9.26100 示例 3: 输入:x = 2.00000, n = -2 输出:0....
  • In numpy, I have done the following: result = numpy.sqrt(numpy.sum(numpy.pow(some_vector, 2))) And in pure python something like this would be expected: result = math.sqrt(math.pow(A, 2) + math.pow(B...
  • Java.math.BigDecimal.pow()方法实例

    千次阅读 2021-03-03 14:10:16
    全屏Java.math.BigDecimal.pow()方法实例java.math.BigDecimal.pow(int n)返回一个BigDecimal,其值是 (thisn), 被精确计算的幂值,使其具有无限精度。参数n必须在范围0到999999999(包括)。 ZERO.pow(0)返回ONE。...
  • output = Math.pow(input, input2); answer=String.valueOf(output); num.setText(answer); } }); break; case R.id.broot: output= Math.sqrt(input); answer=String.valueOf(output); num.setText(answer); break...
  • Which one is more efficient using math.pow or the ** operator? When should I use one over the other?So far I know that x**y can return an int or a float if you use a decimalthe function pow will retur...
  • Math.pow的用法

    2021-03-30 16:20:11
    int m=(int)Math.pow(a,b) 意思是m=a的b次方 Math.pow(3,3)=27
  • 171. Excel 表列序号 - 力扣... 更新:2021年10月11日13:53:25 参考:Excel表列序号 - Excel 表列序号 - 力扣(LeetCode) 【更新结束】 有关参考 更新:2021年10月11日14:18:37 参考:Math.pow() - JavaScript | MDN

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 149,244
精华内容 59,697
关键字:

math.pow

友情链接: usb.rar