Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. c++ - std :: map - Is my idea too dirty?

c++ - std :: map - Is my idea too dirty?

Scheduled Pinned Locked Moved C / C++ / MFC
questionc++performancehelp
18 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Offline
    L Offline
    Lost User
    wrote on last edited by
    #1

    Would you ever do something like this:

    std :: map >

    I don't see a reason why not to do it, but I have a bad feeling doing it. Any Remarks / objections? Ok, this double - Key is a user Input with a known/limited number of decimal places. I could also take this into acount and use a

    std :: map >

    But why I should? Btw: Performance is out of questions, the map size is Maximum 10 items. Thank you very much in advance.

    It does not solve my Problem, but it answers my question

    L CPalliniC J 5 Replies Last reply
    0
    • L Lost User

      Would you ever do something like this:

      std :: map >

      I don't see a reason why not to do it, but I have a bad feeling doing it. Any Remarks / objections? Ok, this double - Key is a user Input with a known/limited number of decimal places. I could also take this into acount and use a

      std :: map >

      But why I should? Btw: Performance is out of questions, the map size is Maximum 10 items. Thank you very much in advance.

      It does not solve my Problem, but it answers my question

      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #2

      In 64bit code (so using XMM registers) it'll probably work, unless any DLL secretly changes a rounding mode on you and "forgets" to set it back. In 32bit code (usually using the x87 FPU stack), who knows? The danger there as usual is that keeping a double in an FPU register keeps it at whatever value was actually computed (which depending on how `stod` works internally may have bits set in the part of the 64bit significand that extends beyond the 53 bits you usually get) while storing it to memory and reloading it changes the value, and this is something that compilers think is a normal part of how they work so they do it outside of your control, though you can force a store/reload to get a safer value to work with. So it may still work, but there are some sneaky conditions that may depend on specific codegen choices the compiler makes.

      L 1 Reply Last reply
      0
      • L Lost User

        In 64bit code (so using XMM registers) it'll probably work, unless any DLL secretly changes a rounding mode on you and "forgets" to set it back. In 32bit code (usually using the x87 FPU stack), who knows? The danger there as usual is that keeping a double in an FPU register keeps it at whatever value was actually computed (which depending on how `stod` works internally may have bits set in the part of the 64bit significand that extends beyond the 53 bits you usually get) while storing it to memory and reloading it changes the value, and this is something that compilers think is a normal part of how they work so they do it outside of your control, though you can force a store/reload to get a safer value to work with. So it may still work, but there are some sneaky conditions that may depend on specific codegen choices the compiler makes.

        L Offline
        L Offline
        Lost User
        wrote on last edited by
        #3

        Thank you so much! To be honest I don't get all of your explanations at the moment. But the most important Thing is, that you Point out, that there can be a Problem... and that corresponds with "my bad Feeling". So now it will be my part to investigate more for possible pitfalls Thank you very much again. [Edit] And please flag your Response as an answer, it is much more than a "general"

        It does not solve my Problem, but it answers my question

        1 Reply Last reply
        0
        • L Lost User

          Would you ever do something like this:

          std :: map >

          I don't see a reason why not to do it, but I have a bad feeling doing it. Any Remarks / objections? Ok, this double - Key is a user Input with a known/limited number of decimal places. I could also take this into acount and use a

          std :: map >

          But why I should? Btw: Performance is out of questions, the map size is Maximum 10 items. Thank you very much in advance.

          It does not solve my Problem, but it answers my question

          L Offline
          L Offline
          Lost User
          wrote on last edited by
          #4

          Simple answer: no. Double and float values have an inherent precision problem so you can never rely on two numbers being the same. You need to rethink your design.

          L 1 Reply Last reply
          0
          • L Lost User

            Would you ever do something like this:

            std :: map >

            I don't see a reason why not to do it, but I have a bad feeling doing it. Any Remarks / objections? Ok, this double - Key is a user Input with a known/limited number of decimal places. I could also take this into acount and use a

            std :: map >

            But why I should? Btw: Performance is out of questions, the map size is Maximum 10 items. Thank you very much in advance.

            It does not solve my Problem, but it answers my question

            CPalliniC Offline
            CPalliniC Offline
            CPallini
            wrote on last edited by
            #5

            Quote:

            Is my idea too dirty?

            I have just the same feeling about.

            In testa che avete, signor di Ceprano?

            1 Reply Last reply
            0
            • L Lost User

              Simple answer: no. Double and float values have an inherent precision problem so you can never rely on two numbers being the same. You need to rethink your design.

              L Offline
              L Offline
              Lost User
              wrote on last edited by
              #6

              This is really too pessimistic about floating point arithmetic though. There are definitely cases where doubles will reliably have exactly equal values. They're not non-deterministic, just hard to work with and 80bit nonsense messes things up extra.

              L 1 Reply Last reply
              0
              • L Lost User

                This is really too pessimistic about floating point arithmetic though. There are definitely cases where doubles will reliably have exactly equal values. They're not non-deterministic, just hard to work with and 80bit nonsense messes things up extra.

                L Offline
                L Offline
                Lost User
                wrote on last edited by
                #7

                This is really too pessimistic No, realistic. Far too many people use floating point numbers where they are not necessary, or actually wrong.

                L 2 Replies Last reply
                0
                • L Lost User

                  This is really too pessimistic No, realistic. Far too many people use floating point numbers where they are not necessary, or actually wrong.

                  L Offline
                  L Offline
                  Lost User
                  wrote on last edited by
                  #8

                  That is true, but "you can never rely on two numbers being the same" is not. There are conditions that can be satisfied that will make the numbers the same.

                  L 1 Reply Last reply
                  0
                  • L Lost User

                    That is true, but "you can never rely on two numbers being the same" is not. There are conditions that can be satisfied that will make the numbers the same.

                    L Offline
                    L Offline
                    Lost User
                    wrote on last edited by
                    #9

                    Yes, but you understand floating point representation. Too many developers do not appear to share that understanding.

                    1 Reply Last reply
                    0
                    • L Lost User

                      Would you ever do something like this:

                      std :: map >

                      I don't see a reason why not to do it, but I have a bad feeling doing it. Any Remarks / objections? Ok, this double - Key is a user Input with a known/limited number of decimal places. I could also take this into acount and use a

                      std :: map >

                      But why I should? Btw: Performance is out of questions, the map size is Maximum 10 items. Thank you very much in advance.

                      It does not solve my Problem, but it answers my question

                      J Offline
                      J Offline
                      Jochen Arndt
                      wrote on last edited by
                      #10

                      I'm a bit late to the party. The key point of a map is that no two elements in a map container can have equivalent keys. If the number of significant digits entered is less than the precision of double values, this will not happen (besides entering the same value again which applies to ints as well). But you might get problems when trying to access elements by key when the argument is from other sources (affected by rounding). That would be my bad feeling: While there is no problem with the map itself, key based operations ([]operator, erase, swap, find) might behave not as expected (no match). Even when not using such operations now but only iterator based ones, they may be used later when updating the code. So you should at least place a comment about this. Another option is creating your own std::map based class that disables the affected operations or replaces them with a version that treats close numbers as identical (defining an epsilon).

                      L 1 Reply Last reply
                      0
                      • J Jochen Arndt

                        I'm a bit late to the party. The key point of a map is that no two elements in a map container can have equivalent keys. If the number of significant digits entered is less than the precision of double values, this will not happen (besides entering the same value again which applies to ints as well). But you might get problems when trying to access elements by key when the argument is from other sources (affected by rounding). That would be my bad feeling: While there is no problem with the map itself, key based operations ([]operator, erase, swap, find) might behave not as expected (no match). Even when not using such operations now but only iterator based ones, they may be used later when updating the code. So you should at least place a comment about this. Another option is creating your own std::map based class that disables the affected operations or replaces them with a version that treats close numbers as identical (defining an epsilon).

                        L Offline
                        L Offline
                        Lost User
                        wrote on last edited by
                        #11

                        Thank you very much for your comments and your time.

                        It does not solve my Problem, but it answers my question

                        1 Reply Last reply
                        0
                        • L Lost User

                          This is really too pessimistic No, realistic. Far too many people use floating point numbers where they are not necessary, or actually wrong.

                          L Offline
                          L Offline
                          Lost User
                          wrote on last edited by
                          #12

                          So with your Argumentation one Need also to say: Don't use int_64 ... which of course makes no sense. A double value has a discret number of numbers it can represent, same as an int_64 has ;)

                          It does not solve my Problem, but it answers my question

                          L 2 Replies Last reply
                          0
                          • L Lost User

                            So with your Argumentation one Need also to say: Don't use int_64 ... which of course makes no sense. A double value has a discret number of numbers it can represent, same as an int_64 has ;)

                            It does not solve my Problem, but it answers my question

                            L Offline
                            L Offline
                            Lost User
                            wrote on last edited by
                            #13

                            No, that is not what I am saying at all. And it appears, that like so many people on these forums, you also do not understand how floating point numbers work.

                            1 Reply Last reply
                            0
                            • L Lost User

                              So with your Argumentation one Need also to say: Don't use int_64 ... which of course makes no sense. A double value has a discret number of numbers it can represent, same as an int_64 has ;)

                              It does not solve my Problem, but it answers my question

                              L Offline
                              L Offline
                              Lost User
                              wrote on last edited by
                              #14

                              Try this

                              #define NUMBER 133333333
                              int main()
                              {
                              int nValue = NUMBER;
                              float fValue = NUMBER;

                              printf("%d\\n", nValue);
                              printf("%f\\n", fValue);
                              
                              L 1 Reply Last reply
                              0
                              • L Lost User

                                Try this

                                #define NUMBER 133333333
                                int main()
                                {
                                int nValue = NUMBER;
                                float fValue = NUMBER;

                                printf("%d\\n", nValue);
                                printf("%f\\n", fValue);
                                
                                L Offline
                                L Offline
                                Lost User
                                wrote on last edited by
                                #15

                                Thank you very much for this. I'm completely aware of such effects and also on the normalizing stuff. Thank you again :thumbsup:

                                It does not solve my Problem, but it answers my question

                                1 Reply Last reply
                                0
                                • L Lost User

                                  Would you ever do something like this:

                                  std :: map >

                                  I don't see a reason why not to do it, but I have a bad feeling doing it. Any Remarks / objections? Ok, this double - Key is a user Input with a known/limited number of decimal places. I could also take this into acount and use a

                                  std :: map >

                                  But why I should? Btw: Performance is out of questions, the map size is Maximum 10 items. Thank you very much in advance.

                                  It does not solve my Problem, but it answers my question

                                  L Offline
                                  L Offline
                                  Lost User
                                  wrote on last edited by
                                  #16

                                  0x01AA wrote:

                                  std :: map<double, MyType, std :: less<double> >

                                  Hi, I was avoiding this discussion but I wanted to just add one more comment. The FPU has a state that has an affect on the precision. In other words... when the FPU is in various states you get a different rounding value. You can control this state with [_controlfp_s](https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/controlfp-s) Printer DLL and other libraries outside of your control could potentially change the thread FPU state causing your std::map to contain multiple floating point numbers from the same calculations. Unfortunately on Windows user-applications cannot always control third-party DLL from loading into your process. Those DLL could modify and then fail to reset the floating point state. The answer is "Yes" what you are proposing would work 99% of the time or in "laboratory" conditions where you control both the hardware and software. But if you tried to ship out a commercial product using the above technique... you will almost certainly have a small percentage of the conditions I described above. Best Wishes, -David Delaune

                                  L 2 Replies Last reply
                                  0
                                  • L Lost User

                                    0x01AA wrote:

                                    std :: map<double, MyType, std :: less<double> >

                                    Hi, I was avoiding this discussion but I wanted to just add one more comment. The FPU has a state that has an affect on the precision. In other words... when the FPU is in various states you get a different rounding value. You can control this state with [_controlfp_s](https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/controlfp-s) Printer DLL and other libraries outside of your control could potentially change the thread FPU state causing your std::map to contain multiple floating point numbers from the same calculations. Unfortunately on Windows user-applications cannot always control third-party DLL from loading into your process. Those DLL could modify and then fail to reset the floating point state. The answer is "Yes" what you are proposing would work 99% of the time or in "laboratory" conditions where you control both the hardware and software. But if you tried to ship out a commercial product using the above technique... you will almost certainly have a small percentage of the conditions I described above. Best Wishes, -David Delaune

                                    L Offline
                                    L Offline
                                    Lost User
                                    wrote on last edited by
                                    #17

                                    :thumbsup: Wow, great that you share this knowledge. Thank you very much for this.

                                    It does not solve my Problem, but it answers my question

                                    1 Reply Last reply
                                    0
                                    • L Lost User

                                      0x01AA wrote:

                                      std :: map<double, MyType, std :: less<double> >

                                      Hi, I was avoiding this discussion but I wanted to just add one more comment. The FPU has a state that has an affect on the precision. In other words... when the FPU is in various states you get a different rounding value. You can control this state with [_controlfp_s](https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/controlfp-s) Printer DLL and other libraries outside of your control could potentially change the thread FPU state causing your std::map to contain multiple floating point numbers from the same calculations. Unfortunately on Windows user-applications cannot always control third-party DLL from loading into your process. Those DLL could modify and then fail to reset the floating point state. The answer is "Yes" what you are proposing would work 99% of the time or in "laboratory" conditions where you control both the hardware and software. But if you tried to ship out a commercial product using the above technique... you will almost certainly have a small percentage of the conditions I described above. Best Wishes, -David Delaune

                                      L Offline
                                      L Offline
                                      Lost User
                                      wrote on last edited by
                                      #18

                                      :thumbsup: Wow, great that you share this knowledge. Thank you very much for this.

                                      It does not solve my Problem, but it answers my question

                                      1 Reply Last reply
                                      0
                                      Reply
                                      • Reply as topic
                                      Log in to reply
                                      • Oldest to Newest
                                      • Newest to Oldest
                                      • Most Votes


                                      • Login

                                      • Don't have an account? Register

                                      • Login or register to search.
                                      • First post
                                        Last post
                                      0
                                      • Categories
                                      • Recent
                                      • Tags
                                      • Popular
                                      • World
                                      • Users
                                      • Groups