I need to compare floating point numbers for near-equality. I would like to compare them based on the ULP distance (see here if you aren’t familiar/need a refresher).
The most straightforward way to do this, as far as I know, is to convert the bits that make up the floating point numbers into their equivalent integers, and then take the difference of the two resulting integers as the ULP distance.
The very naive solution I have come up with is to do something like this in Julia is:
function ULPsBetween(a::Float64, b::Float64)
a = bitstring(a)
b = bitstring(b)
aintegerrepresentation = parse(Int, a; base=2)
bintegerrepresentation = parse(Int, b; base=2)
return aintegerrepresentation - bintegerrepresentation
end
This code works correctly, but it’s very slow since it calls bitstring() and parse(). I used BenchmarkTools to evaluate the performance, and its on the order of 1 microsecond. For the number of times this function will be called in my program, that is very slow.
In C, we can do something like this instead of the parse() function:
int64_t floatToInt(double f)
{
int64_t r;
memcpy(&r, &f, sizeof(double));
return r;
}
This code executes on the order of a few nanoseconds.
Obviously, I’m not using Julia correctly. But what would a more elegant/faster solution look like? Any ideas?
For now, I will probably write a Julia function that calls the C code above with ccall(). But I would really prefer to have everything in pure Julia. Finally, I searched quite a bit and couldn’t find anything about calculating the ULP distance in Julia on here or StackOverflow, so this post may be useful to others who find themselves in the same situation in the future.
Thank you!