zoukankan      html  css  js  c++  java
  • 如何实现sqrt()

    jdk中实现sqrt()是native方法,没法看到具体的实现细节,所以自己整理下,以便后续查阅。

    1、暴力法,从0开始每次增加1e-6,直到非常接近

    2、牛顿法,求n的平方根

    while(abs(x-x_pre)>1e-6){
        x_pre = x;
        x = (x+n/x)/2;
    }
    return x;

    3、二分法

    4、快速平方根倒数,https://en.wikipedia.org/wiki/Fast_inverse_square_root

    float Q_rsqrt( float number )
    {
        long i;
        float x2, y;
        const float threehalfs = 1.5F;
    
        x2 = number * 0.5F;
        y  = number;
        i  = * ( long * ) &y;                       // evil floating point bit level hacking
        i  = 0x5f3759df - ( i >> 1 );               // what the fuck? 
        y  = * ( float * ) &i;
        y  = y * ( threehalfs - ( x2 * y * y ) );   // 1st iteration
    //    y  = y * ( threehalfs - ( x2 * y * y ) );   // 2nd iteration, this can be removed
    
        return y;
    }

    java版本

    public static float invSqrt(float x) {
        float xhalf = 0.5f*x;
        int i = Float.floatToIntBits(x);
        i = 0x5f3759df - (i>>1);
        x = Float.intBitsToFloat(i);
        x = x*(1.5f - xhalf*x*x);
        return x;
    }

    5、快速计算(int)(sqrt(x)),利用空间换时间

     1 public class APIsqrt2 {
     2     final static int[] table = { 0, 16, 22, 27, 32, 35, 39, 42, 45, 48, 50, 53,
     3             55, 57, 59, 61, 64, 65, 67, 69, 71, 73, 75, 76, 78, 80, 81, 83, 84,
     4             86, 87, 89, 90, 91, 93, 94, 96, 97, 98, 99, 101, 102, 103, 104,
     5             106, 107, 108, 109, 110, 112, 113, 114, 115, 116, 117, 118, 119,
     6             120, 121, 122, 123, 124, 125, 126, 128, 128, 129, 130, 131, 132,
     7             133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 144,
     8             145, 146, 147, 148, 149, 150, 150, 151, 152, 153, 154, 155, 155,
     9             156, 157, 158, 159, 160, 160, 161, 162, 163, 163, 164, 165, 166,
    10             167, 167, 168, 169, 170, 170, 171, 172, 173, 173, 174, 175, 176,
    11             176, 177, 178, 178, 179, 180, 181, 181, 182, 183, 183, 184, 185,
    12             185, 186, 187, 187, 188, 189, 189, 190, 191, 192, 192, 193, 193,
    13             194, 195, 195, 196, 197, 197, 198, 199, 199, 200, 201, 201, 202,
    14             203, 203, 204, 204, 205, 206, 206, 207, 208, 208, 209, 209, 210,
    15             211, 211, 212, 212, 213, 214, 214, 215, 215, 216, 217, 217, 218,
    16             218, 219, 219, 220, 221, 221, 222, 222, 223, 224, 224, 225, 225,
    17             226, 226, 227, 227, 228, 229, 229, 230, 230, 231, 231, 232, 232,
    18             233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238, 239, 240,
    19             240, 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246,
    20             247, 247, 248, 248, 249, 249, 250, 250, 251, 251, 252, 252, 253,
    21             253, 254, 254, 255 };
    22 
    23     /**
    24      * A faster replacement for (int)(java.lang.Math.sqrt(x)). Completely
    25      * accurate for x < 2147483648 (i.e. 2^31)...
    26      */
    27     static int sqrt(int x) {
    28         int xn;
    29 
    30         if (x >= 0x10000) {
    31             if (x >= 0x1000000) {
    32                 if (x >= 0x10000000) {
    33                     if (x >= 0x40000000) {
    34                         xn = table[x >> 24] << 8;
    35                     } else {
    36                         xn = table[x >> 22] << 7;
    37                     }
    38                 } else {
    39                     if (x >= 0x4000000) {
    40                         xn = table[x >> 20] << 6;
    41                     } else {
    42                         xn = table[x >> 18] << 5;
    43                     }
    44                 }
    45 
    46                 xn = (xn + 1 + (x / xn)) >> 1;
    47                 xn = (xn + 1 + (x / xn)) >> 1;
    48                 return ((xn * xn) > x) ? --xn : xn;
    49             } else {
    50                 if (x >= 0x100000) {
    51                     if (x >= 0x400000) {
    52                         xn = table[x >> 16] << 4;
    53                     } else {
    54                         xn = table[x >> 14] << 3;
    55                     }
    56                 } else {
    57                     if (x >= 0x40000) {
    58                         xn = table[x >> 12] << 2;
    59                     } else {
    60                         xn = table[x >> 10] << 1;
    61                     }
    62                 }
    63 
    64                 xn = (xn + 1 + (x / xn)) >> 1;
    65 
    66                 return ((xn * xn) > x) ? --xn : xn;
    67             }
    68         } else {
    69             if (x >= 0x100) {
    70                 if (x >= 0x1000) {
    71                     if (x >= 0x4000) {
    72                         xn = (table[x >> 8]) + 1;
    73                     } else {
    74                         xn = (table[x >> 6] >> 1) + 1;
    75                     }
    76                 } else {
    77                     if (x >= 0x400) {
    78                         xn = (table[x >> 4] >> 2) + 1;
    79                     } else {
    80                         xn = (table[x >> 2] >> 3) + 1;
    81                     }
    82                 }
    83 
    84                 return ((xn * xn) > x) ? --xn : xn;
    85             } else {
    86                 if (x >= 0) {
    87                     return table[x] >> 4;
    88                 }
    89             }
    90         }
    91 
    92         return -1;
    93     }
    94     public static void main(String[] args){
    95         System.out.println(sqrt(65));
    96         
    97     }
    98 }
  • 相关阅读:
    easy ui 表单ajax和from两种提交数据方法
    easy ui 下拉级联效果 ,下拉框绑定数据select控件
    easy ui 下拉框绑定数据select控件
    easy ui 异步上传文件,跨域
    easy ui 菜单和按钮(Menu and Button)
    HTTP 错误 404.3
    EXTJS4.2 后台管理菜单栏
    HTML 背景图片自适应
    easy ui 表单元素input控件后面加说明(红色)
    EXTJS 4.2 添加滚动条
  • 原文地址:https://www.cnblogs.com/shizhh/p/5775578.html
Copyright © 2011-2022 走看看