-
-
Notifications
You must be signed in to change notification settings - Fork 130
map() for float data type #71
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Shouldn't need to rename to |
This is just a dandy example of what's wrong with C++. I've been writing C since it was developed. Like Ken Thompson, I think C++ fills a much needed gap. The bit about "String" vs. "char" is another pain in the a**. |
I do not quite understand the point you are making. Overloading is a very useful feature. Also, |
Well, maybe it's unrelated, but it may also taken into account... https://github.com/arduino/Arduino/issues/2466 |
Careful here. Actually what you're interested in is the RETURN value of the function, and as far as I know C++ doesn't allow overloading by return type. Normally you want to deal with integers, so that the map() function receives an integer and yields an integer, and only integer arithmetic is used. Sometimes you may want to get a float, using the potentially slower float arithmetic. But if someone tries to do something like So options are:
I might be biased by C, but in this case I think the second option makes more sense, since the intent may not be clear from the arguments, and it is potentially dangerous for inexperienced programmers. |
To me, C++ (and other variants) fills a much-needed gap. And I was a Bell Labs when it was developed. I always treat it as plain C where possible and would avoid it all together if I weren't programming Arduinos and Particle Photons. For Ken Thompson's view, see Ken Thompson on C++ | | | | |
Shouldn't need to rename to mapf. Overloading the map() function with all floats should suffice.
|
This is true only if the return type is changed (not the parameters). However what the op was requesting was the return type and parameters be a
If There is a problem when using all integers though as This solution would be quite verbose (usage would be simple, however the code implementing it is complex). If there is interest for it, I'd certainly be keen to write it, or at least propose a change. |
Well, I got this behavior:
If I remove the
produces an output 26 bytes larger than if I move the In short, I think just having two versions with different names would simplify things a lot. It will save headaches to both developers and users. |
Shouldn't you write this as float foo(int a, float b, float c, float d, float e) { return 0; } Peter Olson
|
I think what you guys are looking for is C++ templates. This would ensure return types are the same as the output types and even convert types where needed. Here's what I've whipped up in the past for another project: template<typename T, typename T2>
inline T map(T2 val, T2 in_min, T2 in_max, T out_min, T out_max) {
return (val - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
} |
Yep, maybe templates + indicating the return type as the EDIT: The issue with heterogeneous types still holds: |
FWIW, here's the template-based map() from Teensy, where we're using C++14 dialect and type_traits.
|
Oh yes; I forgot that. If you don't cast to long, an int->int mapping has high chances of overflowing. Honestly I think all this (rewriting all Arduino.h's function-like macros as templated functions or std:: ones) should be thoroughly discussed, maybe on a separate issue or a thread on the mailing list. |
I agree, and moving things to templates and whatnot will inevitably break someones code somewhere. I've been writing my own alternative Arduino core (@PhantomEmbedded) that addresses many of these issues, but is completely incompatible because everything is based on classes rather than functions. If someone makes a separate thread on this topic I would be happy to help. |
Question: is this something people still want? |
I'm guessing that at this point, those that were bothered by this or wanted this have rolled our own. I wouldn't be opposed to seeing something official in the future though. |
map should be overloaded to work with DOUBLE, workaround: |
The template I showed above (about 3 years ago) automatically does map() using 64 bit double if your input variable is a 64 bit double. But if you give it 32 bit float, everything is done using faster 32 bit floats. And if you give it any integer, everything is computed using 32 bit long. No need to add mapf() to the Arduino API. Templates can let you have your cake and eat it too, from one convenient map() that automatically adapts depending on the type of the user's input variable. |
This is related to issue 288. The Arduino.app C++ compiler accepts float arguments (no warning) to the map() function and then truncates them to integer values. This provides erroneous output that may not be immediately noticed. I think that map() should be defined as all float -- args and return (below). Particle.io's development platform has the same problem. All C++ compilers?
My float version:
float mapf(float value, float istart, float istop, float ostart, float ostop) {
return ostart + (ostop - ostart) * ((value - istart) / (istop - istart));
}
See http://dicks-photon-arduino.blogspot.com/
The text was updated successfully, but these errors were encountered: