# Fast way to access bits of Float64?

**URL:** https://discourse.julialang.org/t/fast-way-to-access-bits-of-float64/11098
**Category:** General Usage
**Created:** [May 23, 2018, 2:33pm UTC](https://discourse.julialang.org/t/fast-way-to-access-bits-of-float64/11098 "2018-05-23T14:33:47Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![robertfeldt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robertfeldt/32/239_2.png) [@robertfeldt](https://discourse.julialang.org/u/robertfeldt)
#### Post date: [May 23, 2018, 2:33pm UTC](https://discourse.julialang.org/t/fast-way-to-access-bits-of-float64/11098/1 "2018-05-23T14:33:47Z")

</div>

I need a fast way to repeatedly access bits in the representation of a floating point value in Julia

```julia
julia> rawbit(x::Float64, bit::I) where {I <: Integer} = reinterpret(UInt64, x) & (1 << (bit-1))

```

but the native code generated for this is quite lengthy. I toyed around with pre-creating the masks in an array but then it is hard to guarantee that the bit argument is between 1 and 64, and thus hard to optimize heavily by the compiler. Any ideas on how to make this very performant?

For context: This is for fast, dynamic, lookup-trees for vectors of Floats which are structured based on bit values ([www.phtree.org](http://www.phtree.org))

---

<div class="post-metadata">

### Author: ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)
#### Post date: [May 23, 2018, 2:57pm UTC](https://discourse.julialang.org/t/fast-way-to-access-bits-of-float64/11098/2 "2018-05-23T14:57:56Z")

</div>

The checks we do to make bit shift operations have predictable, well-defined behavior unfortunately cause quite a bit of unwanted code bloat here. This leads to a paradoxical situation where doing what seems to be more work at the high level ends up generating less machine code. Here’s what I came up with:

```julia
rawbit(x::Float64, bit::UInt64) = reinterpret(UInt64, x) & (1 << (63 & (bit-1)))
rawbit(x::Float64, bit::Integer) = rawbit(x, bit % UInt64)

julia> @code_native rawbit(1.5, 3)
	vmovq	%xmm0, %rcx
	addl	$63, %edi
	movl	$1, %eax
	shlxq	%rdi, %rax, %rax
	andq	%rcx, %rax
	retq

```

I’ve omitted all the verbose comments that `@code_native` emits these days. The key tricks here are:

1. `bits % UInt64`: modding the `bit` index into the `UInt64` type which is strictly non-negative allows the code to skip checking for negative shift values.

2. `63 & (bit-1)`: anding the `bit-1` shift value with 63 guarantees that the bit shift value cannot be too large which allows the code to skip checking for and handling overly large shift values.

The flip side is that the function has the explicit behavior that it mods all integer values it’s given into a shift value between 0 and 63. As long as you’re ok with that, this definition will work.

---

<div class="post-metadata">

### Author: ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)
#### Post date: [May 23, 2018, 3:12pm UTC](https://discourse.julialang.org/t/fast-way-to-access-bits-of-float64/11098/3 "2018-05-23T15:12:23Z")

</div>

Oh, also, note that if you have code that uses constant values for `bit` a lot of that code bloat goes away. For my definition for example:

```julia
bit12(x::Float64) = rawbit(x, 12)

julia> @code_native bit12(1.5)
	vmovq	%xmm0, %rax
	andl	$2048, %eax ## imm = 0x800
	retq

```

That’s the minimal code you can hope for since you have to move float values to integer registers before you can do integer operations on them.

---

<div class="post-metadata">

### Author: ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)
#### Post date: [May 23, 2018, 7:35pm UTC](https://discourse.julialang.org/t/fast-way-to-access-bits-of-float64/11098/4 "2018-05-23T19:35:49Z")

</div>

with this macro I copied from [here](https://discourse.julialang.org/t/defining-function-inside-a-macro/9139/4) rewritten so it works in a loop/iteration 1:64

```julia
macro make_rawbit(idx)
    fn = Symbol(string("rawbit",idx))
    quote
        function $(esc(fn))(x::Float64)
            rawbit(x, $idx)
        end
    end
 end

```

or just written 64 times

```julia
@make_rawbit(i) where i=1:64
rawbits = (rawbit1, rawbit2, .., rawbit64)

rawbits[kthbit](targetfloat64)

```

`rawbits[kthbit](targetfloat64)` compiles as `rawbitk(targetfloat64)`

---

<div class="post-metadata">

### Author: ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)
#### Post date: [May 23, 2018, 9:16pm UTC](https://discourse.julialang.org/t/fast-way-to-access-bits-of-float64/11098/5 "2018-05-23T21:16:46Z")

</div>

I don’t think this is any more efficient than calling `rawbit(x, bit)` with a constant `bit` value (at least not on master, and I suspect on older versions as well).

---

<div class="post-metadata">

### Author: ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)
#### Post date: [May 23, 2018, 9:19pm UTC](https://discourse.julialang.org/t/fast-way-to-access-bits-of-float64/11098/6 "2018-05-23T21:19:08Z")

</div>

It is not faster than that. It is exactly as fast as that (the native code appears identical).  
I mentioned the approach to allow someone to get the performance you isolated without needing to know which bit they may need during the time of problem solution.

:goldstar: _a celebration of your code_

---

<div class="post-metadata">

### Author: ![robertfeldt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robertfeldt/32/239_2.png) [@robertfeldt](https://discourse.julialang.org/u/robertfeldt)
#### Post date: [May 24, 2018, 7:55am UTC](https://discourse.julialang.org/t/fast-way-to-access-bits-of-float64/11098/7 "2018-05-24T07:55:07Z")

</div>

Thanks to both of you, this is very helpful.

This seems a case where the switch statement might be useful: [A case/switch statement for Julia · Issue #18285 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/18285)  
but I can also work with the code you’ve given me to pre-calc which rawbit function to use at which level (in my tree structure) and thus get good performance anyway.

---

<div class="post-metadata">

### Author: ![robertfeldt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robertfeldt/32/239_2.png) [@robertfeldt](https://discourse.julialang.org/u/robertfeldt)
#### Post date: [May 24, 2018, 7:56am UTC](https://discourse.julialang.org/t/fast-way-to-access-bits-of-float64/11098/8 "2018-05-24T07:56:05Z")

</div>

Oh, for others that might have similar situation I should point out that Stefan’s solution require 0.7, on 0.6 the generated code is not as optimal.
