Corey
Corey

Reputation: 1855

Alternative to floating point as key

I would like to dynamically store the value of a variable k and a list of corresponding values y1=f(k,1), y2=f(k,2), etc. All numbers are floating point.

For example, I might have several cut values k1=0.25 and k2=0.5, and I then want to store different properties of my data calculated using each cut value.

I could use, for example, a std::map< float, std::vector<float> > . While this container seems to work, it uses floating points as keys, which I would like to avoid if a better solution is out there.

Are there any generally accepted alternatives in situations like this?

(One alternative that occurred to me was to use a std::vector<int> to store the values of k and then a std::map< unsigned int, std::vector<float> > to store the y values, with the integer key being the index in the vector of k's. This seems to mimic what SQL databases do. But it limits how easily I can analyze the results.)

Upvotes: 2

Views: 1036

Answers (2)

user4992621
user4992621

Reputation:

std::map requires its key type to obey the strict weak ordering property, which I very much suspect floats (or doubles) won't. If you're not using very high precision float values, maybe you could just multiply all of those floats with a high enough power-of-ten that they can be converted to unique ints/longs/long longs?

Upvotes: 0

rici
rici

Reputation: 241701

Since std::map maintains its keys in order, using std::less, there really isn't a problem using floating-point keys provided that:

  • you are only using the map to keep the keys in order; or
  • you are prepared to do lookups using some strategy which is not dependent on strict key equality, such as "nearest key" (or "nearest key if close enough"), or interpolation; or
  • the way you compute key values is stable, so you can rely on the computation to produce a lookup value which is present in the map.

To implement either "closest key" or "interpolated value", you'll want to find the bracketing keys; that is, largest key not greater than the search key and the smallest key not less than the search key. The second of these can be found with std::map::lower_bound, and the first is either the same key (if it's equal), the previous key, or non-existent (if the value is less than every key).

I don't see any advantage to using an integer key instead. How would you look up the integer corresponding to a floating point value without doing precisely the same computation? (And if you can guarantee that you will always be looking up values using precisely the same number as you used to store them, then floating point isn't going to cause you any grief at all.)

Upvotes: 1

Related Questions