快速pow和sqrt

 

http://www.matrix67.com/blog/archives/361

http://blog.csdn.net/liuqiyao_01/article/details/8478402



下面这种方法可以很有效地求出根号a的近似值:首先随便猜一个近似值x,然后不断令x等于x和a/x的平均数,迭代个六七次后x的值就已经相当精确了。
    例如,我想求根号2等于多少。假如我猜测的结果为4,虽然错的离谱,但你可以看到使用牛顿迭代法后这个值很快就趋近于根号2了:

(       4  + 2/   4     ) / 2 = 2.25
(    2.25  + 2/   2.25  ) / 2 = 1.56944..
( 1.56944..+ 2/1.56944..) / 2 = 1.42189..
( 1.42189..+ 2/1.42189..) / 2 = 1.41423..

....

      
    这种算法的原理很简单,我们仅仅是不断用(x,f(x))的切线来逼近方程x^2-a=0的根。根号a实际上就是x^2-a=0的一个正实根,这个函数的导数是2x。也就是说,函数上任一点(x,f(x))处的切线斜率是2x。那么,x-f(x)/(2x)就是一个比x更接近的近似值。代入f(x)=x^2-a得到x-(x^2-a)/(2x),也就是(x+a/x)/2。
    同样的方法可以用在其它的近似值计算中。Quake III的源码中有一段非常牛B的开方取倒函数。

  1. **=============================================**  
  2. ||快速pow(多次使用时及其有效)               ||  
  3. **=============================================**  
  4. __int64 qpow(int a, int b){  
  5.     __int64 c, d; c = 1; d = a;  
  6.     while (b > 0){  
  7.         if (b & 1)  
  8.           c *= d;  
  9.         b = b >> 1;  
  10.         d = d * d;  
  11.     }  
  12.     return c;  
  13. }  
    1. **=============================================**  
    2. ||快速1/sqrt(x)(牛顿迭代法)                    ||  
    3. **=============================================**  
    4. float InvSqrt (float x) {  
    5.      float xhalf = 0.5f * x;  
    6.      long i = *(long*)&x;  
    7.      i = 0x5f3759df - (i >> 1);  
    8.      x = *(float *)&i;  
    9.      x = x * (1.5f - xhalf * x * x);  
    10.      return x;  
    11. }  
好的,以下是一个简单的 Java 计算器窗口,可以进行加减乘除、powsqrt、log10 的计算: ```java import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Calculator extends JFrame implements ActionListener { private JTextField textField; private double num1, num2, result; private int operator; private boolean isFirstNum = true; public Calculator() { super("Calculator"); setLayout(new BorderLayout()); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(300, 200); // 文本框 textField = new JTextField(10); textField.setEditable(false); add(textField, BorderLayout.NORTH); // 操作按钮 JPanel panel = new JPanel(); panel.setLayout(new GridLayout(4, 4)); JButton button7 = new JButton("7"); button7.addActionListener(this); panel.add(button7); JButton button8 = new JButton("8"); button8.addActionListener(this); panel.add(button8); JButton button9 = new JButton("9"); button9.addActionListener(this); panel.add(button9); JButton buttonAdd = new JButton("+"); buttonAdd.addActionListener(this); panel.add(buttonAdd); JButton button4 = new JButton("4"); button4.addActionListener(this); panel.add(button4); JButton button5 = new JButton("5"); button5.addActionListener(this); panel.add(button5); JButton button6 = new JButton("6"); button6.addActionListener(this); panel.add(button6); JButton buttonSubtract = new JButton("-"); buttonSubtract.addActionListener(this); panel.add(buttonSubtract); JButton button1 = new JButton("1"); button1.addActionListener(this); panel.add(button1); JButton button2 = new JButton("2"); button2.addActionListener(this); panel.add(button2); JButton button3 = new JButton("3"); button3.addActionListener(this); panel.add(button3); JButton buttonMultiply = new JButton("*"); buttonMultiply.addActionListener(this); panel.add(buttonMultiply); JButton button0 = new JButton("0"); button0.addActionListener(this); panel.add(button0); JButton buttonDot = new JButton("."); buttonDot.addActionListener(this); panel.add(buttonDot); JButton buttonEquals = new JButton("="); buttonEquals.addActionListener(this); panel.add(buttonEquals); JButton buttonDivide = new JButton("/"); buttonDivide.addActionListener(this); panel.add(buttonDivide); JButton buttonPow = new JButton("pow"); buttonPow.addActionListener(this); panel.add(buttonPow); JButton buttonSqrt = new JButton("sqrt"); buttonSqrt.addActionListener(this); panel.add(buttonSqrt); JButton buttonLog10 = new JButton("log10"); buttonLog10.addActionListener(this); panel.add(buttonLog10); add(panel, BorderLayout.CENTER); setVisible(true); } public void actionPerformed(ActionEvent event) { String command = event.getActionCommand(); if (command.equals("+")) { operator = 1; num1 = Double.parseDouble(textField.getText()); isFirstNum = false; textField.setText(""); } else if (command.equals("-")) { operator = 2; num1 = Double.parseDouble(textField.getText()); isFirstNum = false; textField.setText(""); } else if (command.equals("*")) { operator = 3; num1 = Double.parseDouble(textField.getText()); isFirstNum = false; textField.setText(""); } else if (command.equals("/")) { operator = 4; num1 = Double.parseDouble(textField.getText()); isFirstNum = false; textField.setText(""); } else if (command.equals("pow")) { operator = 5; num1 = Double.parseDouble(textField.getText()); isFirstNum = false; textField.setText(""); } else if (command.equals("sqrt")) { operator = 6; num1 = Double.parseDouble(textField.getText()); result = Math.sqrt(num1); textField.setText(Double.toString(result)); } else if (command.equals("log10")) { operator = 7; num1 = Double.parseDouble(textField.getText()); result = Math.log10(num1); textField.setText(Double.toString(result)); } else if (command.equals("=")) { if (isFirstNum) { return; } num2 = Double.parseDouble(textField.getText()); switch (operator) { case 1: result = num1 + num2; break; case 2: result = num1 - num2; break; case 3: result = num1 * num2; break; case 4: result = num1 / num2; break; case 5: result = Math.pow(num1, num2); break; } textField.setText(Double.toString(result)); isFirstNum = true; } else { textField.setText(textField.getText() + command); } } public static void main(String[] args) { new Calculator(); } } ``` 这个计算器窗口包含一个文本框和一些按钮。当你点击数字按钮时,数字将显示在文本框中。当你点击操作符按钮时,计算器将保存第一个数字并清空文本框,等待输入第二个数字。当你点击等于号时,计算器将执行相应的操作并将结果显示在文本框中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值