c++ - std :: map - Is my idea too dirty?
-
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.
-
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.
-
This is really too pessimistic No, realistic. Far too many people use floating point numbers where they are not necessary, or actually wrong.
-
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.
-
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 astd :: 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
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 toint
s 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 ownstd::map
based class that disables the affected operations or replaces them with a version that treats close numbers as identical (defining an epsilon). -
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 toint
s 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 ownstd::map
based class that disables the affected operations or replaces them with a version that treats close numbers as identical (defining an epsilon). -
This is really too pessimistic No, realistic. Far too many people use floating point numbers where they are not necessary, or actually wrong.
-
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
-
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
-
Try this
#define NUMBER 133333333
int main()
{
int nValue = NUMBER;
float fValue = NUMBER;printf("%d\\n", nValue); printf("%f\\n", fValue);
-
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 astd :: 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
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
-
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
-
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