package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"strconv"
)

//Util
func nextStr() string {
	sc.Scan()
	return sc.Text()
}

func nextInt() int {
	sc.Scan()
	i, e := strconv.Atoi(sc.Text())
	if e != nil {
		panic(e)
	}
	return i
}

func maxInt(a, b int) int {
	if a > b {
		return a
	} else {
		return b
	}
}

func minInt(a, b int) int {
	if a > b {
		return b
	} else {
		return a
	}
}

func absInt(a int) int {
	if a >= 0 {
		return a
	} else {
		return -a
	}
}

func absFloat64(a float64) float64 {
	if a >= 0 {
		return a
	} else {
		return -a
	}
}

func maxFloat64(a, b float64) float64 {
	if a > b {
		return a
	} else {
		return b
	}
}

func minFloat64(a, b float64) float64 {
	if a > b {
		return b
	} else {
		return a
	}
}

func str2Int(s string) int {
	n, _ := strconv.Atoi(s)
	return n
}

func reverse(s string) string {
	runes := []rune(s)
	for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
		runes[i], runes[j] = runes[j], runes[i]
	}
	return string(runes)
}

func powInt(p, q int) int {
	return int(math.Pow(float64(p), float64(q)))
}

func isPrime(x int) bool {
	if x == 1 {
		return false
	}
	if x == 2 {
		return true
	}
	if x%2 == 0 {
		return false
	}

	b := true
	rootx := int(math.Sqrt(float64(x)))
	i := 3
	for i <= rootx {
		if x%i == 0 {
			b = false
			break
		}
		i += 2
	}
	return b
}

func PrimeFactors(n int) (pfs []int) {
	// Get the number of 2s that divide n
	for n%2 == 0 {
		pfs = append(pfs, 2)
		n = n / 2
	}

	// n must be odd at this point. so we can skip one element
	// (note i = i + 2)
	for i := 3; i*i <= n; i = i + 2 {
		// while i divides n, append i and divide n
		for n%i == 0 {
			pfs = append(pfs, i)
			n = n / i
		}
	}

	// This condition is to handle the case when n is a prime number
	// greater than 2
	if n > 2 {
		pfs = append(pfs, n)
	}

	return
}

func sumInts(x []int) int {

	total := 0
	for _, v := range x {
		total += v
	}

	return total
}

//Main
const (
	initialBufSize = 10000
	maxBufSize     = 1000000
	mod            = 1e9 + 7
)

var (
	sc *bufio.Scanner = func() *bufio.Scanner {
		sc := bufio.NewScanner(os.Stdin)
		buf := make([]byte, initialBufSize)
		sc.Buffer(buf, maxBufSize)
		return sc
	}()
)

var N, K int

func main() {
	sc.Split(bufio.ScanWords)

	N, K = nextInt(), nextInt()
	Kf := float64(K)
	//p := 0
	// for true {
	// 	if powInt(2, p) >= K {
	// 		break
	// 	}
	// 	p++
	// }
	// coin := 0.5
	// for i := 0; i < p; i++ {
	// 	coin *= 0.5
	// }

	ans := 0.0
	if N >= K {
		ans += float64(N-K+1) / float64(N)
	}
	p := 1.0
	for i := float64(minInt(K-1, N)); i > 0; i-- {
		if i*math.Pow(2, p) < Kf {
			p++
		}
		//fmt.Println(i, 1/float64(N), math.Pow(0.5, p), float64(1.0/float64(N)*math.Pow(float64(1/2), p)))
		// tmp := 1 / float64(N) * math.Pow(0.5, p)
		// ans += tmp
		ans += 1 / float64(N) * math.Pow(0.5, p)
	}

	fmt.Println(ans)
}


n,k = gets.split.map(&:to_i)

i = 0
sum = 0.0
pre = n + 1
while pre != 1
    x = k.fdiv(2 ** i).ceil
    if pre >= x
        sum += (pre - x).fdiv(2 ** i)
        pre = x
    end
    i += 1
end

puts sum / n


str1 = gets.split
N,K = str1[0].to_i, str1[1].to_i

a = []
for x in 0...20
  a[x] = 0
end

if N-K+1 >= 0
  a[0] = N-K+1
else
  a[0] = 0
end

b = 2
c = 1
for x in 1...20
  if (K-1)/c == 0
    a[x] = 0
  elsif N >= (K-1)/c
    a[x] = (K-1)/c - ((K-1)/b+1) + 1
  else
    a[x] = N - ((K-1)/b+1) + 1
  end
  if a[x] < 0
    a[x] = 0
  end
  b = b*2
  c = c*2
end

answer = 0.0
d = 1.0

for x in 0...20
  answer += a[x]*d/(N*1.0)
  d = d*0.5
end

puts answer


n, k = gets.split.map(&:to_i)
n = n.to_f
result = 0.0
if n >= k
  result = (n-k+1) / n
end

k = k.to_f
old_k = k
coin = 1
while k >= 1
  k = k/2
  if k < n
    old_k = n+1 if old_k > n
    count = old_k.ceil - k.ceil
    result += count / n / 2**coin
  end
  coin += 1
  old_k = k
end

puts result


N, K = gets.chomp.split().map(&:to_i)

win_prob = []
for point in 1..N do
  t = 0
  k = K / point
  while k >= 1 do
    t += 1
    k /= 2
  end
  win_prob << 0.5 ** t / N
end

print(win_prob.sum)


n, k = gets.chomp.split(" ").map(&:to_i)
count = 0.0
(1..n).each do |i|
    ans = 1
    if i < k
        kaizuu = 0
        while true
            i = i * 2
            kaizuu += 1
            if i > k
                break
            end
        end
        ans = ans * (1.0/n.to_f) * (1/2.to_f) ** kaizuu
    else
        ans = ans * (1.0 /n.to_f)
    end
    count += ans
end
puts count


n, k = gets.chomp.split(" ").map(&:to_i)
count = 0.0
(1..n).each do |i|
    ans = 1
    if i < k
        kaizuu = 0
        while true
            i = i * 2.0
            kaizuu += 1
            if i > k
                break
            end
        end
        ans = ans * (1.0/n.to_f) * (1/2.to_f) ** kaizuu
    else
        ans = ans * (1.0 /n.to_f)
    end
    count += ans
end
puts count


fn main() {
    let nk = read_vec::<usize>();
    let n = nk[0];
    let k = nk[1];

    let mut p = 0.0;
    for i in 1..n+1 {
        let mut point = i;
        let mut cnt = 0;
        while point < k {
            point *= 2;
            cnt += 1;
        }
        let half: f64 = 0.5;
        p += (1.0 / n as f64) * half.powi(cnt);
    }

    println!("{}", p);
}

fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    s.trim().split_whitespace().map(|e| e.parse().ok().unwrap()).collect()
}


macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
    ($($r:tt)*) => {
        let s = {
            use std::io::Read;
            let mut s = String::new();
            std::io::stdin().read_to_string(&mut s).unwrap();
            s
        };
        let mut iter = s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
}

macro_rules! input_inner {
    ($iter:expr) => {};
    ($iter:expr, ) => {};

    ($iter:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($iter, $t);
        input_inner!{$iter $($r)*}
    };
}

macro_rules! read_value {
    ($iter:expr, ( $($t:tt),* )) => {
        ( $(read_value!($iter, $t)),* )
    };

    ($iter:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
    };

    ($iter:expr, chars) => {
        read_value!($iter, String).chars().collect::<Vec<char>>()
    };

    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };

    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}

#[allow(unused_imports)]
use std::{i32, i64, u32, u64, usize, f64};
#[allow(unused_imports)]
use std::cmp::{max, min, Ordering};
#[allow(unused_imports)]
use std::collections::{VecDeque, HashMap, BTreeMap, HashSet, BTreeSet};
#[allow(unused_imports)]
use std::io::{stdout, Write, BufWriter};
#[allow(unused_imports)]
use std::mem::{swap};

fn main() {
    input! {
        n: i32,
        k: i32,
    }
    let mut prob = 0f64;
    for mut i in 1..(n + 1) {
        let mut p = 0;
        while i < k {
            i *= 2;
            p += 1;
        }
        prob += 0.5f64.powi(p);
    }
    println!("{}", prob / (n as f64));
}


use std::io::*;
use std::str::FromStr;

//https://qiita.com/tubo28/items/e6076e9040da57368845
fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

fn main() {
    let n: usize = read(); //N面ダイス
    let k: usize = read();
    let mut ans = 0.0;

    for i in 1..n+1{
        let mut probability = 1.0/n as f64;
        let mut tokuten = i;
        while tokuten < k {
            tokuten *= 2;
            probability /= 2.0;
        }
        ans += probability;
    }
    println!("{}",ans);

}


#[allow(unused)]
use proconio::{
    input,
    marker::{Chars, Usize1},
};

fn main() {
    input! {
        n: i64,
        k: i64,
    }
    let mut ans = 0.0_f64;
    for i in 1..(n + 1) {
        let log = k as f64 / i as f64;
        if log > 1.0 {
            ans += 0.5_f64.powi(log.log2().trunc() as i32 + 1);
        } else {
            ans += 1.0;
        }
    }
    println!("{}", ans / n as f64);
}


use whiteread::parse_line;

fn main() {
    let (n, k): (i64, i64) = parse_line().unwrap();
    let mut pro: f64 = 0.0;
    let mut i: i64 = 1;

    while i <= n {
        let mut j: i64 = i;
        let mut t: i64 = n;
        while j <= k {
            j = j * 2;
            t = t * 2;
        }
        pro = pro + (1.0/(t as f64));
        i = i + 1;
    }

    println!("{}", pro);
}


use whiteread::parse_line;

fn main() {
    let (mut n, mut k): (i64, i64) = parse_line().unwrap();
    let mut pro: f64 = 0.0;
    let mut i: i64 = 1;

    while i <= n {
        let mut j: i64 = i;
        let mut t: i64 = n;
        while j <= k {
            j = j * 2;
            t = t * 2;
        }
        pro = pro + (1.0/(t as f64));
        i = i + 1;
    }

    println!("{}", pro);
}


import Foundation
func sqrtd(_ a: Int, _ N: Int) -> Int {
  var a = a
  var current = 0
  while a < N {
    a *= 2
    current += 1
  }
  return current
}

let input = readLine()!.split(separator: " ").map { Int($0)! }

let N = input[0]
let K = input[1]

var sum: Double = 0.0
let coe = 1.0 / Double(N)
for i in 0..<N {
  let current = i + 1
  if current >= K {
    sum += coe
    continue
  }
  let times = sqrtd(current, K)
  sum += coe * pow(0.5, Double(times))
}
print(sum)


let l:[Int] = readLine()!.split(separator:" ").map{ Int($0)! }
let n = l[0], k = l[1]

func pow (_ base:Int, _ power:Int) -> Int {
  var answer : Int = 1
  for _ in 0..<power { answer *= base }
  return answer
}

func c2(_ num: Int) -> Int {
  var m = num, c = 0
  while m < k {
    m *= 2
    c += 1
  }
  return c
}

let a = c2(1)
var sum = 1

if n >= 2 {
  for i in 2...n {
    sum += pow(2, a-c2(i))
  }
}

print(Double(sum)/Double(pow(2,a) * n))


// 🐋💭
import Foundation

func readInts() -> [Int] {
    return readLine()!.split(separator: " ").map { Int($0)! }
}

func readInt() -> Int {
    return Int(readLine()!)!
}

func readDoubles () -> [Double] {
    return readLine()!.split(separator: " ").map { Double($0)! }
}

func readDouble() -> Double{
    return Double(readLine()!)!
}
///最大公約数を返す
func gcd(_ m:Int, _ n:Int) -> Int {
    if n == 0 {return m}
    return gcd(n, m % n)
}
///最小公倍数を返す
func lcm(_ m:Int, _ n:Int) -> Int {
    return m * n / gcd(m, n)
}

///素数判定(試し割り)
func isPrime(_ x:Int) -> Bool {
    if x <= 1 || x % 2 == 0 { return false }
    if x == 2 { return true }
    for i in stride(from: 3, to: Int(ceil(sqrt(Double(x)))), by: 2){
        if x % i == 0 {
            return false
        }
    }
    return true
}

//https://program-life.com/669
///実行速度の計測
func exectionTime(action: () -> Void) {
    let startDate = Date()
    action()
    let endDate = Date()
    print(endDate.timeIntervalSince(startDate))
}

// https://melheaven.hatenadiary.jp/entry/atcoder144
///約数の配列を返す
func makeDivisors(_ n:Int) -> [Int] {
    var divisors = [Int]()
    for i in 1..<Int(pow(Double(n), 0.5)) + 1 {
        if n % i == 0{
            divisors.append(i + n / i)
        }
    }

    return divisors
}

//https://riptutorial.com/ja/swift/example/14738/インデックスを知らずに配列から要素を削除する
extension Array where Element: Equatable {

    mutating func remove(_ element: Element) {
        _ = index(of: element).flatMap {
            self.remove(at: $0)
        }
    }
}

func binarySearch(rifgt:Int, key:Int, ary:[String]) -> Int{
    var left = 0
    var right = rifgt

    while abs(right - left) > 1 {
        let mid = left + (right - left) / 2

        if Int(ary[mid])! < key {
            left = mid

        } else {
            right = mid
        }
    }
    return left
}

func arrangement (prev:String, ary:[String], returnVal:[String]) -> [String] {
    var returnVal = returnVal
    if ary.count == 0 {
        returnVal.append(prev)
        return returnVal
    }

    for s in ary {
        let wprev = prev + s
        var wary = ary
        wary.remove(s)
        returnVal = arrangement(prev: wprev, ary: wary, returnVal: returnVal)
    }
    return returnVal
}

func main() {
    let nk = readDoubles()
    let (n, k) = (nk[0], nk[1])
    var ans = 0.0
    for i in 1...Int(n) {
        var count = 0
        var point = i
        while point < Int(k) {
            count += 1
            point *= 2
        }
        ans += (1 / n) * pow(0.5, Double(count))
    }
    print(ans)
}
main()


let l:[Int] = readLine()!.split(separator:" ").map{ Int($0)! }
let n = l[0], k = l[1]

func pow (_ base:Int, _ power:Int) -> Int {
  var answer : Int = 1
  for _ in 0..<power { answer *= base }
  return answer
}

func c2(_ num: Int) -> Int {
  var m = num, c = 0
  while m < k {
    m *= 2
    c += 1
  }
  return c
}

let a = c2(1)
var sum = 1

for i in 2...n {
  sum += pow(2, a-c2(i))
}

print(Double(sum)/Double(pow(2,a) * n))


export class Main {
  static main(input): string {
    const [n, k]: number[] = input.split("\n")[0].split(" ").map(Number);
    let result = 0;
    let nn: number = n;
    if (nn >= k) {
      result += (nn - k + 1) / n;
      nn = k - 1;
    }
    if (nn > 0) {
      let bufK: number = k;
      let buf2: number = 1;
      while (bufK > 0) {
        bufK /= 2;
        buf2 *= 2;
        if (nn >= bufK) {
          const t: number = Math.ceil(bufK);
          result += (nn - t + 1) / n / buf2;
          nn = t - 1;
        }
      }
    }
    return `${result}`
  }
}
console.log(Main.main(require("fs").readFileSync("/dev/stdin", "utf8")));


function Main(input) {
    const [n, k] = input.split(" ").map(str => Number(str));
    let result = 0;
    for (let i = 1; i <= n; i++) {
        let requiredCnt = 0;
        let score = i;
        while (true) {
            if (k <= score) break;
            score *= 2;
            requiredCnt++;
        }
        result += (1 / n) * (0.5 ** requiredCnt);
    }
    console.log(result);
}
Main(require("fs").readFileSync("/dev/stdin", "utf8"));


const stdin = require('fs').readFileSync('/dev/stdin', 'utf8')

const [n, k] = stdin
  .split('\n')[0]
  .split(' ')
  .map(Number)

const getPow = num => {
  let c = 0
  let t = num
  while (1) {
    if (t >= k) {
      return c
    }
    t *= 2
    c++
  }
}

const ans = _ => {
  let ans = ''

  let sum = 0
  for (let i = 1; i <= n; i++) {
    const res = (1 / n) * Math.pow(1 / 2, getPow(i))
    sum += res
  }
  return sum
}

console.log(ans())


import { readFileSync } from 'fs'

const getNeedsCount = (base: number, K: number) => {
  let count = 0
  let point = base
  while (true) {
    if (point > K) return count
    point *= 2
    count += 1
  }
}

function main(input: string) {
  const [N, K] = input.split(' ').map(Number)

  const list = Array(N).fill(null).map((_, i) => i + 1)
    .map(point => getNeedsCount(point, K))
    .map((v) => N * 2 ** v)

  const base = list[0]
  const result = list.reduce((acc, v) => acc + base / v, 0) / base

  console.log(result)
}

main(readFileSync('/dev/stdin', 'utf8').trim())


const main = (line) => {
	const [N,K] = line.split(" ").map(Number)
  let result = 0

  for(let i=1;i<K && i<=N;i++){

    result += (0.5 ** Math.ceil(Math.log(K/i) / Math.log(2))) / N
  }

  result += N > K ? (N - K) / N : 0

  console.log(result)
}

main(require("fs").readFileSync("/dev/stdin", "utf8"))


const input = require('fs').readFileSync('/dev/stdin', 'utf8')

const [N, K]: number[] = input.split('\n')[0].split(" ").map(Number)
let ans: number = 0;
for (let i = 1; i <= N; i++) {
  let num = 0
  for (let j = 0; j >= 0; j++) {
    if (i * 2 ** j > K) {
      if (j > 0) {
        console.log(j)
      }
      num = j
      break
    }
  }

  ans += 1 / 2 ** num / N
}
console.log(ans)