简体   繁体   中英

Fast lookup suffering from floating point inaccuracies

Suppose I have equally spaced doubles (64 bit floating point numbers) x0,x1,...,xn . Equally spaced means that for all i , x(i+1) - xi is constant; call it w for width.

Given a number y in the range [x0,xn] I want to find the largest i such that xi <= y .

A naive approach would visit each i in turn ( O(n) ). Marginally better is to use a binary search ( O(log n) ).

A constant time lookup would be to calculate (y-x0)/w and cast it to an integer. However, this will occasionally give the wrong result due to floating point inaccuracy. Eg Suppose there are 100 intervals of width 0.01 starting at 0.

(int)(0.29/0.01) = 28 //want 29 here

Can I retain the constant time lookup but ensure that the results are always identical to the binary search? Performing the calculation with decimals rather than doubles for 'w' and 'x0' seems to work here, but will it always work? I could always follow the direct lookup with a comparison with the x s either side, but this seems ugly and inefficient.

To clarify - I am given the xi and the value y as doubles - I cannot change this. But any intermediate calculation performed before returning the integer index can use any datatypes I like. Additionally, I can perform one-off "preparation" work in order to make the runtime calculation faster.

Edit: Apologies - turns out that I didn't check "equally spaced" properly - these numbers are often not "equally spaced" when their difference is calculated using floating point arithmetic.

Do the following

Calculate (int)(0.29/0.01) = 28 //want 29 here

Next, calculate back i * 0.01 for i between 28-1 and 28+1 and pick up the one that is correct.

What do you mean equally spaced ? If can make some assumptions about the numbers, for example - that they increase on an interval, you can actually use median selction that is O(1) in the best case and O(log2(N)) in the worst case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM