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 C++14 (GCC 5.4.1) (judge verdict: Accepted)

// #pragma GCC optimize ("O3")
#pragma GCC target ("sse4")
#include <bits/stdc++.h>
using namespace std;
const double EPS=1e-7;
const int MOD=1e9+7;
#define IOS ios_base::sync_with_stdio(0);cin.tie(0);
#define VI vector<int>
#define VD vector<double>
#define VC vector<char>
#define VS vector<string>
#define VVI vector<VI>
#define VVD vector<VD>
#define VVC vector<VC>
#define VVS vector<VS>
#define PII pair<int,int>
#define PIII pair<int,PII>
#define VPII vector<PII>
#define VPIII vector<PIII>
#define emb emplace_back
#define pub push_back
#define pob pop_back
#define mp make_pair
#define mp3(a,b,c) mp(a,mp(b,c))
#define fi first
#define se second
#define fir fi
#define sec se.fi
#define thr se.se
#define fou(i,a,n) for(int i=a;i<n;i++)
#define fod(i,a,n) for(int i=n-1;i>=a;i--)
#define rep(n) fou(_,0,n)
#define tra(a,x) for(auto& a : x)
#define elif(c) else if(c)
#define si(vec) ((int)(vec).size())
#define all(vec) vec.begin(),vec.end()
#define lla(vec) vec.rbegin(),vec.rend()
#define range(vec,x,y) vec.begin()+x,vec.begin()+y
#define sortup(vec) sort(all(vec))
#define sortdown(vec) sort(lla(vec))
#define eraseif(vec,condition_VAR) vec.erase(remove_if(all(vec),[&](auto VAR){return condition_VAR;}),vec.end())
#define erase_unique(vec) vec.erase(unique(all(vec)),vec.end())
#define rotateleft(vec,n) rotate(vec.begin(),vec.begin()+n,vec.end())
#define rotateright(vec,n) rotate(vec.rbegin(),vec.rbegin()+n,vec.rend())
template<class C>int minelement(vector<C>&vec){int s=si(vec);C m=0;fou(i,1,s)if(vec[i]<vec[m])m=i;return m;}
template<class C>int maxelement(vector<C>&vec){int s=si(vec);C m=0;fou(i,1,s)if(vec[i]>vec[m])m=i;return m;}
template<class C>void mini(C&a,const C&b){a=min(a,b);}
template<class C>void maxi(C&a,const C&b){a=max(a,b);}
// make_pair,vector calculate
#define opall(calc) calc(+)calc(-)calc(*)calc(/)calc(%)calc(<<)calc(>>)calc(&)calc(|)calc(^)
#define paircalc(op) template<class C1,class C2,class C3>pair<C1,C2>operator op(const pair<C1,C2>&l,const C3&r){return mp(l.first op r,l.second op r);}
#define pair2calc(op) template<class C1,class C2>pair<C1,C2>operator op(const pair<C1,C2>&l,const pair<C1,C2>&r){return mp(l.first op r.first,l.second op r.second);}
#define vectorcalc(op) template<class C1,class C2>vector<C1>operator op(const vector<C1>&l,const C2&r){int s=si(l);vector<C1> v(s);fou(i,0,s)v[i]=l[i] op r;return v;}
#define vector2calc(op) template<class C>vector<C>operator op(const vector<C>&l,const vector<C>&r){int s=min(si(l),si(r));vector<C>v(s);fou(i,0,s)v[i]=l[i] op r[i];return v;}
#define opeq(op) template<class C1,class C2>C1 operator op ## =(C1&l,const C2&r){return l=l op r;}
opall(paircalc)opall(pair2calc)opall(vectorcalc)opall(vector2calc)opall(opeq)
// iostream
#define in(T,...) T __VA_ARGS__;_cin(__VA_ARGS__)
#define out(...) _cout(__VA_ARGS__)
void _cin(){}template<class Head,class...Tail>void _cin(Head&head,Tail&&...tail){cin>>head;_cin(forward<Tail>(tail)...);}
template<class Head>void _cout(const Head&head){cout<<head<<endl;}template<class Head,class...Tail>void _cout(const Head&head,Tail...tail){cout<<head<<" ";_cout(forward<Tail>(tail)...);}
template<class C1,class C2>istream&operator>>(istream&is,pair<C1,C2>&p){return is>>p.fi>>p.se;}
template<class C>istream&operator>>(istream&is,vector<C>&vec){tra(v,vec)is>>v;return is;}
template<class C1,class C2>ostream&operator<<(ostream&os,const pair<C1,C2>&p){os<<p.fi<<" "<<p.se;return os;}
template<class C>ostream&operator<<(ostream&os,const vector<C>&vec){int vecsize=si(vec);fou(i,0,vecsize-1)os<<vec[i]<<" ";os<<vec[vecsize-1];return os;}
// math
int gcd_sub(const int&a,const int&b){if(b)return gcd_sub(b,a%b);else return a;}int gcd(const int&a,const int&b){return gcd_sub(max(a,b),min(a,b));}
int lcm(const int&a,const int&b){return a/gcd(a,b)*b;}
int fact(const int&n){return n==0?1:n*fact(n-1);}
PII comb_sub(const int&m,const int&n){return n==0?mp(1,1):mp(m,n)*comb_sub(m-1,n-1);}int comb(const int&m,const int&n){PII p=comb_sub(m,min(n,m-n));return p.fi/p.se;}
int mnum(const int&a){return a%MOD+(a<0?MOD:0);}
int minv(int a){a=mnum(a);int b=MOD,u=0,v=1;while(a>1){u-=b/a*v;b%=a;swap(a,b);swap(u,v);}return mnum(v);}
int madd(const int&a,const int&b){return (mnum(a)+mnum(b))%MOD;}
int msub(const int&a,const int&b){return (mnum(a)-mnum(b))%MOD;}
int mmul(const int&a,const int&b){return (mnum(a)*mnum(b))%MOD;}
int mdiv(const int&a,const int&b){return mmul(a,minv(b));}
int mpow(int a,int b){int r=1;while(b>0){if(b&1)r=mmul(r,a);a=mmul(a,a);b>>=1;}return r;}
// algorithm
template<class C>vector<C>cumsum(vector<C>vec){int s=si(vec);fou(i,1,s)vec[i]+=vec[i-1];return vec;}
template<class C>vector<vector<C>>cumsum2(vector<vector<C>>vec){int s=si(vec);fou(i,1,s)vec[i]+=vec[i-1];fou(i,0,s)vec[i]=cumsum(vec[i]);return vec;}
template<class C>int binarysearch(const vector<C>vec,const C&n,const char&c){
  int left=-1;int right=si(vec);bool outleft=(c=='d'||c=='U');int getmin=(c=='u'||c=='d')?1:-1;
  while(right-left>1){
    int mid=left+(right-left)/2;
    bool OK=vec[mid]*getmin>=n*getmin;
    if(outleft==OK) left=mid;else right=mid;
  }
  return outleft?left:right;
}

class unionfind{vector<int> p;int n;public:unionfind(int _n):n(_n){p.resize(n);iota(all(p),0);}int get(const int&x){return (x==p[x]?x:(p[x]=get(p[x])));}void unite(int x,int y){x=get(x);y=get(y);if(x!=y)p[x]=y;}bool same(int x,int y){x=get(x);y=get(y);return x==y;}};
template<typename T>class BIT{vector<T> tree;int n;public:BIT(int _n):n(_n){tree.resize(n);}void add(int x,T v){while(x<n){tree[x]+=v;x|=(x+1);}}T sum(int x){T v=0;while(x>=0){v+=tree[x];x=(x&(x+1))-1;}return v;}};
// part,set,get,mul



#define int int64_t
// #define double long double

signed main(){
  in(int,n,k);
  VI times(k+1);

  int left=(k+1)/2;
  int right=k-1;
  int t=1;
  while(left>1){
    fou(i,left,right+1) times[i]=t;
    right=left-1;
    left=(left+1)/2;
    t++;
  }
  times[1]=t;

  VD div2(t+1);
  div2[0]=1;
  fou(i,0,t) div2[i+1]=div2[i]/2;

  double ans=0;
  fod(i,1,n+1){
    ans+=(long double)(i<k?(div2[times[i]]):1)/n;
  }

  // out(div2[times[1]]/n);
  // out(ans);
  printf("%.10f\n",ans);

}