|
|
Home » Developing U++ » U++ Developers corner » Value with type float
Value with type float [message #58151] |
Thu, 03 March 2022 13:34  |
abductee23
Messages: 5 Registered: October 2018 Location: San Francisco
|
Promising Member |
|
|
Hi,
i was wondering - when will float be supported by Value?
(couldn't find it in the roadmap)
in the interrim - is there a bazar or patch thingy one could point me to?
thanks in advance
--m
|
|
|
|
|
Re: Value with type float [message #58228 is a reply to message #58227] |
Thu, 31 March 2022 13:49   |
Tom1
Messages: 1302 Registered: March 2007
|
Ultimate Contributor |
|
|
Hi,
I could see some benefit for supporting float in Value too. (I do signal processing with floats, so they frequently end up in various locations in my code.)
Having Value supporting float and EditFloat/EditFloatSpin added would allow cleaner code with dialogs.
Currently I have to round the float value to a clean double with roundr() to avoid excessive decimal places in EditDouble/EditDoubleSpin display. Also, when reading the value out from EditDouble/EditDoubleSpin, I will need to cast first to (double) and only thereafter to (float).
As an example, I have filtering frequencies controlled with:
void SetHPF(float fc);
float GetHPF();
Filling the EditDoubleSpin:
hpf<<=roundr(GetHPF(),3);
Reading the EditDoubleSpin:
hpf.WhenAction=[&](){ SetHPF((float)(double)~hpf); };
With float Value and EditFloatSpin support I would expect to work with:
And:
hpf.WhenAction=[&](){ SetHPF((float)~hpf); };
Anyway, changes in Core/CtrlCore/CtrlLib are something for Mirek to decide.
Best regards,
Tom
|
|
|
Re: Value with type float [message #58229 is a reply to message #58228] |
Thu, 31 March 2022 15:14   |
Tom1
Messages: 1302 Registered: March 2007
|
Ultimate Contributor |
|
|
Hi,
Now here's an uneducated, quick and dirty attempt to support float as Value.
DISCLAIMER: This will likely break something and cause all kinds of trouble, as I do not understand most of the fine details of Value/XML/JSON or Core for that matter. So, if you wish to take the risk and test this, please remember to revert back to official sources before getting back to serious work. And also destroy your copy of these attached files.
Best regards,
Tom
|
|
|
|
Re: Value with type float [message #58232 is a reply to message #58228] |
Fri, 01 April 2022 11:07   |
 |
mirek
Messages: 14256 Registered: November 2005
|
Ultimate Member |
|
|
Tom1 wrote on Thu, 31 March 2022 13:49Hi,
I could see some benefit for supporting float in Value too. (I do signal processing with floats, so they frequently end up in various locations in my code.)
Having Value supporting float and EditFloat/EditFloatSpin added would allow cleaner code with dialogs.
Currently I have to round the float value to a clean double with roundr() to avoid excessive decimal places in EditDouble/EditDoubleSpin display. Also, when reading the value out from EditDouble/EditDoubleSpin, I will need to cast first to (double) and only thereafter to (float).
As an example, I have filtering frequencies controlled with:
void SetHPF(float fc);
float GetHPF();
Filling the EditDoubleSpin:
hpf<<=roundr(GetHPF(),3);
Uhm, roundr is sort of sin of past. Perhaps it is a bad idea to pretend that either float or double are "decimal"...
That said, maybe we should just add operator float to Value and constructor from float (if that one is even needed)?
That would solve most of those additional casts that you do not like.
Mirek
|
|
|
Re: Value with type float [message #58233 is a reply to message #58232] |
Fri, 01 April 2022 11:13   |
Tom1
Messages: 1302 Registered: March 2007
|
Ultimate Contributor |
|
|
Hi Mirek,
Would that solve my EditDoubleSpin showing 0.002000000095 instead of 0.002 when I remove the roundr(xxx,3)?
Best regards,
Tom
|
|
|
Re: Value with type float [message #58234 is a reply to message #58233] |
Fri, 01 April 2022 12:06   |
Tom1
Messages: 1302 Registered: March 2007
|
Ultimate Contributor |
|
|
I see. Simply adding operator float to Value:
operator float() const { return (float)(double)*this; }
removes need for any casting at all. The required code gets clean:
hpf.WhenAction=[&](){ SetHPF(~hpf); };
EDIT: Removed from here my stupid idea to round float when constructing a Value.
Best regards,
Tom
[Updated on: Fri, 01 April 2022 14:57] Report message to a moderator
|
|
|
|
Re: Value with type float [message #58236 is a reply to message #58235] |
Fri, 01 April 2022 15:26   |
Tom1
Messages: 1302 Registered: March 2007
|
Ultimate Contributor |
|
|
OK, here's an idea to handle the EditDouble/EditDoubleSpin rounding issue. Adding something like:
to the constructor of the dialog. This will yield possibly sufficient rounding to the float value being represented as double to avoid excessive decimals.
Of course it would be nice to have such 'float compatibility' Pattern -feature available as a flag / checkbox in layout editor for EditDouble, EditDoubleSpin and the NotNull relatives.
Best regards,
Tom
|
|
|
|
|
Re: Value with type float [message #58239 is a reply to message #58235] |
Sat, 02 April 2022 09:43   |
 |
mirek
Messages: 14256 Registered: November 2005
|
Ultimate Member |
|
|
Tom1 wrote on Fri, 01 April 2022 14:03Hi,
The following code portrays the float rounding issue:
#include <Core/Core.h>
using namespace Upp;
CONSOLE_APP_MAIN
{
Value v(0.002f);
Cout() << v << "\n";
Cout() << FormatDouble(v) << "\n";
Cout() << FormatG(v,7) << "\n";
}
The result of running the above follows:
0.0020000000949949
0.0020000000949949
0.002
<--- Finished, press [ENTER] to close the window --->
I do not know how to solve this cleanly. In any case a regular user seeing 0.002000000095 in a field where he expects to see 0.002, will not be happy about it. For years I have used roundr() all over the code to fix this up, but having a solution hidden in Core would be awesome! 
Best regards,
Tom
OK, so it is correct behaviour. You can simplify that to
double x = 0.002;
DDUMP(x);
float fx = x;
x = fx;
DDUMP(x);
which produces exactly the same result. Now for an explanation what is going on here:
0.002 cannot be exactly represented as double. Normal double formatting (as used in DDUMP) rounds for 15 decimal digits which is guaranteed precision and it all yields a "correct" result (in both directions, closes value is choosen and everything is "fine").
Anyway, when you convert it to float, you have to round at equivalent of about 7 valid digits (you have to cut 28 bits of mantissa). In this case, the last mantissa bit of float is rounded up to 1 as that is the closest value to original double. When converting back to double, this cannot be undone, hence you get those "949949" digits at the end.
That said, all of this made me think that if we knew that it is float in Value, we might be able to apply for something like FormatG(v,7) instead when displaying it (e.g. in EditDouble).
Mirek
|
|
|
|
Re: Value with type float [message #58241 is a reply to message #58240] |
Sat, 02 April 2022 11:26   |
 |
mirek
Messages: 14256 Registered: November 2005
|
Ultimate Member |
|
|
Tom1 wrote on Sat, 02 April 2022 10:55Hi Mirek,
Quote:That said, all of this made me think that if we knew that it is float in Value, we might be able to apply for something like FormatG(v,7) instead when displaying it (e.g. in EditDouble).
Would that involve introducing:
const dword FLOAT_V = 13;
and 'DOUBLE_V' -like processing for it, except when putting it out in FormatG() and friends?
This is in some ways pretty much what I attempted to do with the above "float Value prototype" above, but that is really bad as I do not really understand all the details of Value. You may wish to take a look anyway -- and then trash it. 
Best regards,
Tom
Well, I guess I have to sleep over this.... FormatG(v, 7) being the only difference in processing there seems a bit too little...
Mirek
|
|
|
|
|
Re: Value with type float [message #58293 is a reply to message #58289] |
Tue, 12 April 2022 09:26   |
Tom1
Messages: 1302 Registered: March 2007
|
Ultimate Contributor |
|
|
mirek wrote on Mon, 11 April 2022 17:52Tom1 wrote on Sat, 02 April 2022 13:31No problem... I trust you will soon come up with some astonishingly smart three line solution for the task! 
Best regards,
Tom
Nothing too smart for now, but I have added ConvertFloat and EditFloat.
The jury is still out for float in Value.... do not want to do that now. It feels like while it fixes some issues (e.g. Value->JSON conversion when the values went through float precision), there might be many caveats.
Hi Mirek,
Thanks! EditFloat works fine now. However, there are a couple of things more. First, could you add float operator to Value for easy reading of EditFloat:
operator float() const { return Is(DOUBLE_V) ? (float)GetSmallRaw<double>() : (float)GetOtherDouble(); }
Second, can you add EditFloatSpin and EditFloatNotNullSpin variants?:
typedef WithSpin<float, EditFloat> EditFloatSpin;
typedef WithSpin<float, EditFloatNotNull> EditFloatNotNullSpin;
// And then some magic to make those two working and visible in layout editor.
Thanks and best regards,
Tom
|
|
|
|
Goto Forum:
Current Time: Wed Apr 30 20:35:14 CEST 2025
Total time taken to generate the page: 0.01118 seconds
|
|
|