n 番目のフィボナッチ数を計算 (n <= 100000)
// <applet code="FibApp.class" width="300" height="300"></applet>
/**
* フィボナッチ数を求める Java Applet
* @see https://mind.kittttttan.info/java/fibapp
*/
import java.applet.Applet;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;
import java.awt.Container;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.math.BigInteger;
public class FibApp extends Applet implements ActionListener {
private final static int MAX = 100000;
private Container contentPane;
private JPanel panel1;
private JPanel panel2;
private JButton btn;
private JTextArea ta;
private JScrollPane sp;
private JLabel labelt;
private JTextField tf;
/**
* Initialize
*/
public void init() {
btn = new JButton("OK");
btn.addActionListener(this);
tf = new JTextField("777", 7);
//tf.setToolTipText("Input Integer");
labelt = new JLabel("Time[ms]");
ta = new JTextArea(15, 20);
ta.setLineWrap(true);
sp = new JScrollPane(ta);
panel1 = new JPanel();
panel1.add(tf);
panel1.add(btn);
panel1.add(labelt);
panel2 = new JPanel();
panel2.add(sp);
add(panel1, BorderLayout.CENTER);
add(panel2, BorderLayout.SOUTH);
}
/**
* Called when button pushed
*/
public void actionPerformed(ActionEvent e) {
try {
long start = System.currentTimeMillis();
String s = tf.getText();
int n = Integer.parseInt(s);
if (n > MAX) {
ta.setText("too BIG");
labelt.setText("?ms");
return;
}
BigInteger p = getFibs(n);
long stop = System.currentTimeMillis();
String ps = p.toString();
String t = String.valueOf(stop - start) + "ms";
ta.setText(ps);
labelt.setText(t);
} catch (NumberFormatException err) {
ta.setText("Input 1, 2, ...");
labelt.setText("?ms");
} catch (ArrayIndexOutOfBoundsException err) {
ta.setText("Input 1, 2, ...");
labelt.setText("?ms");
}
}
/**
* <pre>
* |a b| |d e| |ad+be bd+ce|
* | | x | | = | |
* |b c| |e f| |bd+ce be+cf|
* </pre>
*/
public static BigInteger[] utm2mul(BigInteger[] a, BigInteger[] b) {
BigInteger ad = a[0].multiply(b[0]);
BigInteger be = a[1].multiply(b[1]);
BigInteger bd = a[1].multiply(b[0]);
BigInteger ce = a[2].multiply(b[1]);
BigInteger bdce = bd.add(ce);
BigInteger cf = a[2].multiply(b[2]);
BigInteger[] m = {
ad.add(be),
bdce,
be.add(cf)
};
return m;
}
/**
* Get <var>n</var>th Fibonacci number
* <pre>
* |1 1|^n |fib(n+1) fib(n) |
* | | = | |
* |1 0| |fib(n) fib(n-1)|
* </pre>
* @param n
* @return
*/
public static BigInteger getFibs(int n){
if (n-- > 0) {
if (n-- == 1) {return BigInteger.ONE;}
BigInteger[] m0 = {BigInteger.ONE, BigInteger.ONE, BigInteger.ZERO};
BigInteger[] m = {BigInteger.ONE, BigInteger.ONE, BigInteger.ZERO};
for (; n > 0; n >>>= 1, m0 = utm2mul(m0, m0)) {
if ((n & 1) == 1) {m = utm2mul(m, m0);}
}
return m[0];
}
return BigInteger.ZERO;
}
}