2

I'm reading double values from file as strings and parsing them with std::atof. Afterwards, I'm using the values as keys in a unordered map. It's seems to be working correctly, but is it guaranteed to work in 100% of the cases?

I'm asking the question because it's extremely hard to produce identical double value if you do any arithmetic operations with it.

Is std::atof guaranteed to produce exactly the same double value if given the same string value multiple times?

Arsen Zahray
  • 24,367
  • 48
  • 131
  • 224
  • 8
    Regardless of what `atof` returns, I wouldn't use floating-point values as keys in a `map`. – cigien Sep 07 '20 at 13:46
  • 1
    The answer to the question in the title (as well as at the end of the body) is Yes. – goodvibration Sep 07 '20 at 13:48
  • 1
    I suspect that question is badly stated and actual problem is [some flavor of this question](https://stackoverflow.com/q/588004/1387438). I suspect that because of this statement: `hard to produce identical double value if you do any arithmetic operations with it`. – Marek R Sep 07 '20 at 13:50
  • 1
    _"[...] if given the same string value multiple times?"_ Do you mean inside the same program? A standard implementation that would behave differently each time you call the function would be really broken. Or do you mean multiple times accross different platforms? – Lukas-T Sep 07 '20 at 13:53
  • 1
    As @churill has stated - across multiple platforms and/or programs, the "current C locale" could be different - which *could* cause different interpretations of a decimal numeric string. – Adrian Mole Sep 07 '20 at 13:55
  • maybe obvious, maybe not: if the float numbers you are using all fall inside a certain range and you only care about certain number of significant digits then you can map them to integers without loss. Integers as keys are no problem – 463035818_is_not_an_ai Sep 07 '20 at 14:21

1 Answers1

3

You can round trip a number with DBL_DIG significant digits or fewer via a std::string. Typically DBL_DIG is 15 but that depends on the floating point scheme used on your platform.

That's not quite the same as what you are asking. For example, it's possible on some platforms to change the floating point rounding mode at runtime, so you could end up with different results even during the execution of a program. Then you have signed zeros, subnormal numbers, and NaN (in its various guises) to worry about.

There are just too many pitfalls. I would not be comfortable using floating point types as map keys. It would be far, far better to use the std::string as the key in your map.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483