Problem:
Score : 300 points

Problem Statement

Snuke has a fair N-sided die that shows the integers from 1 to N with equal probability and a fair coin. He will play the following game with them:

Throw the die. The current score is the result of the die.

As long as the score is between 1 and K-1 (inclusive), keep flipping the coin. The score is doubled each time the coin lands heads up, and the score becomes 0 if the coin lands tails up.

The game ends when the score becomes 0 or becomes K or above. Snuke wins if the score is K or above, and loses if the score is 0.

You are given N and K. Find the probability that Snuke wins the game.

Constraints

1 ≤ N ≤ 10^5

1 ≤ K ≤ 10^5

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N K

Output

Print the probability that Snuke wins the game. The output is considered correct when the absolute or relative error is at most 10^{-9}.

Sample Input 1

3 10

Sample Output 1

0.145833333333

If the die shows 1, Snuke needs to get four consecutive heads from four coin flips to obtain a score of 10 or above. The probability of this happening is \frac{1}{3} \times (\frac{1}{2})^4 = \frac{1}{48}.

If the die shows 2, Snuke needs to get three consecutive heads from three coin flips to obtain a score of 10 or above. The probability of this happening is \frac{1}{3} \times (\frac{1}{2})^3 = \frac{1}{24}.

If the die shows 3, Snuke needs to get two consecutive heads from two coin flips to obtain a score of 10 or above. The probability of this happening is \frac{1}{3} \times (\frac{1}{2})^2 = \frac{1}{12}.

Thus, the probability that Snuke wins is \frac{1}{48} + \frac{1}{24} + \frac{1}{12} = \frac{7}{48} \simeq 0.1458333333.

Sample Input 2

100000 5

Sample Output 2

0.999973749998

Solution in Java8 (OpenJDK 1.8.0) (judge verdict: Accepted)

import java.math.BigInteger;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int N = sc.nextInt();
        double K = (double)sc.nextInt();

        sc.close();

        Fraction sum = new Fraction(0, 1);

        for(int i=1; i<=N; i++){
            int denominator = N;
            if(i < K){
                denominator *= (int)(Math.pow(2, Math.ceil(Math.log(K/i) / Math.log(2))));
            }
            //int denominator = (int)(Math.pow(2, Math.ceil(Math.log(K/i) / Math.log(2))) * N);
            System.err.println(denominator); //#############
            if (denominator == 0) continue;
            Fraction tmp = new Fraction(1, denominator);
            sum.addition(tmp);
        }

        System.err.println(sum.getNumerator());//#############
        System.err.println(sum.getDenominator());//#############
        double result = sum.getNumerator().doubleValue() / sum.getDenominator().doubleValue();
        System.out.println(result);
    }
}

//コピペ
// https://gist.github.com/namiken/363bc136d7a2f1809d6b
/**
 * 分数の値、および計算メソッドを保持するクラス。計算メソッドを利用すると自信の分数の値が書き換わる。(引数の値は書き換わりません)
 *
 */
class Fraction {
    /**
     *  分子
     */
    private BigInteger numerator;

    /**
     *  分母
     */
    private BigInteger denominator;

    /**分数を作る
     * @param numerator 分子
     * @param denominator 分母
     */
    public Fraction(int numerator, int denominator) {
        //分母がゼロならエラー
        if (denominator == 0) {
            throw new RuntimeException("denominator is not permission 'zero'");
        }
        this.numerator = BigInteger.valueOf(numerator);
        this.denominator = BigInteger.valueOf(denominator);

        reduction();
    }

    /**
     * 約分を行う
     */
    private void reduction() {
        BigInteger gcdi = gcdi(numerator, denominator);
        numerator = numerator.divide(gcdi);
        denominator = denominator.divide(gcdi);
    }

    /**
     * 引数の分数を加える
     * @param fraction
     * @return
     */
    public void addition(Fraction fraction) {
        numerator =  fraction.denominator.multiply(numerator).add(fraction.numerator.multiply(denominator));
        denominator = denominator.multiply(fraction.denominator);

        reduction();
    }

    /**
     * 引数の分数を引く
     * @param fraction 引かれる数
     * @return
     */
    public void subtraction(Fraction fraction) {
        numerator = fraction.denominator.multiply(numerator).subtract(fraction.numerator.multiply(denominator));
        denominator = denominator.multiply(fraction.denominator);

        reduction();
    }

    /**
     * 引数の分数を掛ける
     * @param fraction
     * @return
     */
    public void multiplication(Fraction fraction) {
        denominator = denominator.multiply(fraction.denominator);
        numerator = numerator.multiply(fraction.numerator);

        reduction();
    }

    /**
     * 引数の分数を割る
     * @param fraction 割られる数
     * @return
     */
    public void division(Fraction fraction) {
        denominator = denominator.multiply(fraction.numerator);
        numerator = numerator.multiply(fraction.denominator);

        reduction();
    }

    /**
     * 分子を返す
     * @return
     */
    public BigInteger getNumerator() {
        return numerator;
    }

    /**
     * 分母を返す
     * @return
     */
    public BigInteger getDenominator() {
        return denominator;
    }

    @Override
    public String toString() {
        //分母が1のときは分子だけ返す
        if (denominator == BigInteger.ONE) {
            return numerator.toString();
        }
        return numerator + "/" + denominator;
    }

    /**
     * 最大公約数を求める
     * @param a
     * @param b
     * @return
     */
    private static BigInteger gcdi(BigInteger a, BigInteger b) {
        BigInteger gcd = a.gcd(b);
        //int result = gcd.intValue();
        //System.err.println("GCD:" + result);
        return gcd;
    }
}