import java.util.*;

public class Euler499 {
    static double[][] matMul(double[][] A, double[][] B) {
        int n = A.length;
        double[][] C = new double[n][n];
        for (int i = 0; i < n; i++)
            for (int k = 0; k < n; k++) {
                if (A[i][k] == 0)
                    continue;
                for (int j = 0; j < n; j++)
                    C[i][j] += A[i][k] * B[k][j];
            }
        return C;
    }

    static double[] matVec(double[][] A, double[] v) {
        int n = A.length;
        double[] r = new double[n];
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
                r[i] += A[i][j] * v[j];
        return r;
    }

    static double[][] matPow(double[][] A, long exp) {
        int n = A.length;
        double[][] res = new double[n][n];
        for (int i = 0; i < n; i++)
            res[i][i] = 1;
        while (exp > 0) {
            if ((exp & 1) == 1)
                res = matMul(res, A);
            A = matMul(A, A);
            exp >>= 1;
        }
        return res;
    }

    static boolean solveLinear(double[][] A, double[] b, double[] x) {
        int n = A.length;
        for (int i = 0; i < n; i++) {
            int piv = i;
            for (int r = i + 1; r < n; r++)
                if (Math.abs(A[r][i]) > Math.abs(A[piv][i]))
                    piv = r;
            if (Math.abs(A[piv][i]) < 1e-30)
                return false;
            double[] tmp = A[i];
            A[i] = A[piv];
            A[piv] = tmp;
            double t = b[i];
            b[i] = b[piv];
            b[piv] = t;
            double d = A[i][i];
            for (int c = i; c < n; c++)
                A[i][c] /= d;
            b[i] /= d;
            for (int r = 0; r < n; r++) {
                if (r == i)
                    continue;
                double f = A[r][i];
                for (int c = i; c < n; c++)
                    A[r][c] -= f * A[i][c];
                b[r] -= f * b[i];
            }
        }
        System.arraycopy(b, 0, x, 0, n);
        return true;
    }

    static double probabilityNoRuin(long m, long s) {
        if (s < m)
            return 0;
        int d = (int) (m - 1), N = 50;
        long[] pow2n = new long[N];
        double[] probs = new double[N];
        for (int n = 0; n < N; n++) {
            pow2n[n] = 1L << n;
            probs[n] = Math.pow(2, -(n + 1));
        }

        // Build A_minus and transitions for R iteration
        double[][] Aminus = new double[d][d];
        List<int[]> trIdx = new ArrayList<>();
        List<Double> trProb = new ArrayList<>();
        Map<Long, Integer> expIndex = new TreeMap<>();
        List<Long> exps = new ArrayList<>();
        for (int n = 0; n < N; n++) {
            long delta = pow2n[n] - m;
            for (int r = 0; r < d; r++) {
                long c = d + r + 1, cp = c + delta, kp = (cp - 1) / d;
                int rp = (int) ((cp - 1) % d);
                if (kp - 1 == -1)
                    Aminus[r][rp] += probs[n];
                else {
                    long e = kp;
                    if (!expIndex.containsKey(e)) {
                        expIndex.put(e, exps.size());
                        exps.add(e);
                    }
                    trIdx.add(new int[] { r, rp, expIndex.get(e) });
                    trProb.add(probs[n]);
                }
            }
        }

        // Iterate R to fixed point
        double[][] R = new double[d][d];
        for (int i = 0; i < d; i++)
            System.arraycopy(Aminus[i], 0, R[i], 0, d);
        for (int iter = 0; iter < 500; iter++) {
            double[][][] Rpows = new double[exps.size()][][];
            for (int i = 0; i < exps.size(); i++)
                Rpows[i] = matPow(R, exps.get(i));
            double[][] Rn = new double[d][d];
            for (int i = 0; i < d; i++)
                System.arraycopy(Aminus[i], 0, Rn[i], 0, d);
            for (int t = 0; t < trIdx.size(); t++) {
                int[] ti = trIdx.get(t);
                double p = trProb.get(t);
                double[][] mp = Rpows[ti[2]];
                for (int j = 0; j < d; j++)
                    Rn[ti[0]][j] += p * mp[ti[1]][j];
            }
            double diff = 0;
            for (int i = 0; i < d; i++)
                for (int j = 0; j < d; j++)
                    diff = Math.max(diff, Math.abs(Rn[i][j] - R[i][j]));
            R = Rn;
            if (diff < 1e-18)
                break;
        }

        // Compute y0 boundary
        List<Long> bexps = new ArrayList<>();
        for (int n = 0; n < N; n++) {
            long delta = pow2n[n] - m;
            for (int r = 0; r < d; r++) {
                long cp = r + 1 + delta;
                if (cp <= 0)
                    continue;
                long kp = (cp - 1) / d;
                if (kp >= 1)
                    bexps.add(kp);
            }
        }
        bexps = new ArrayList<>(new TreeSet<>(bexps));
        double[][][] bRpows = new double[bexps.size()][][];
        Map<Long, Integer> bExpIdx = new HashMap<>();
        for (int i = 0; i < bexps.size(); i++) {
            bExpIdx.put(bexps.get(i), i);
            bRpows[i] = matPow(R, bexps.get(i));
        }

        double[][] M = new double[d][d];
        double[] bb = new double[d];
        for (int n = 0; n < N; n++) {
            long delta = pow2n[n] - m;
            for (int r = 0; r < d; r++) {
                long cp = r + 1 + delta;
                if (cp <= 0) {
                    bb[r] += probs[n];
                    continue;
                }
                long kp = (cp - 1) / d;
                int rp = (int) ((cp - 1) % d);
                if (kp == 0)
                    M[r][rp] += probs[n];
                else {
                    int idx = bExpIdx.get(kp);
                    for (int j = 0; j < d; j++)
                        M[r][j] += probs[n] * bRpows[idx][rp][j];
                }
            }
        }
        double[][] A = new double[d][d];
        for (int i = 0; i < d; i++) {
            for (int j = 0; j < d; j++)
                A[i][j] = -M[i][j];
            A[i][i] += 1;
        }
        double[] y0 = new double[d];
        solveLinear(A, bb, y0);

        long c2 = s - d;
        long k = (c2 - 1) / d;
        int r2 = (int) ((c2 - 1) % d);
        if (k == 0)
            return 1.0 - y0[r2];
        double[][] Rk = matPow(R, k);
        double[] yk = matVec(Rk, y0);
        return 1.0 - yk[r2];
    }

    public static void main(String[] args) {
        double ans = probabilityNoRuin(15, 1000000000L);
        System.out.printf("%.7f%n", ans);
    }
}
