素数の分布の予測を加えてみた

素数の分布と一緒に、ガウスの予測値を書くようにしました。
青線がxより小さい素数の個数、赤線がガウスの予測値x/log(x)です。

import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;

public class SosuBunpu{
    public static void main(String args[]) {
        JFrame frame = new JFrame("素数分布");

        boolean [] sosu = new boolean [1000000];
        long[] bunpu = new long[sosu.length];
        JLabel lblCanvas = new JLabel();

        frame.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        frame.add(lblCanvas);
        frame.pack();

        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        frame.setBounds((screenSize.width-450)/2, (screenSize.height-350)/2, 450, 350);
        
        for(int i = 2; i < sosu.length; ++i){
            sosu[i] = true;
        }
        //素数を求める
        for(int i = 2; i < sosu.length; ++i){
            if(!sosu[i]) continue;
            for(int j = i + i; j < sosu.length; j += i){
                sosu[j] = false;
            }
        }
        //素数の分布を求める
        int n = 0;
        for(int i = 0; i < sosu.length; ++i){
            if(sosu[i]) ++n;
            bunpu[i] = n;
        }
        
        //描画
        Image img = frame.createImage(400, 300);
        Graphics2D g = (Graphics2D) img.getGraphics();
        Path2D p = new GeneralPath();//素数の個数
        Path2D l = new GeneralPath();//素数の個数の予測
        p.moveTo(0, 0);
        l.moveTo(0, 0);
        for(int x = 0; x < 400; ++x){
            long dn = x * bunpu.length / 400;
            long y = bunpu[(int)dn] * 300 / bunpu[bunpu.length - 1];
            long dy = (long)( dn / Math.log(dn) * 300 / bunpu[bunpu.length - 1]);
            p.lineTo(x, 300 - y);
            l.lineTo(x, 300 - dy);
        }
        g.setColor(Color.RED);
        g.draw(l);
        g.setColor(Color.BLUE);
        g.draw(p);
        g.dispose();
        ImageIcon ii = new ImageIcon(img);
        lblCanvas.setIcon(ii);    
        frame.setVisible(true);
    }
}