1

How would you compare floats & doubles sent into QML functions from Cpp side ?

If I want to do a high precision comparasion like below as mentioned here

bool AreSame(double a, double b) {
  return fabs(a - b) < EPSILON;
}

How should I do this in Qt QML ?

Or, Is it that it gets casted to real in QML & one need not worry about it?

TheWaterProgrammer
  • 7,055
  • 12
  • 70
  • 159

2 Answers2

3

You should do it the same as in JavaScript:

x = 0.2 + 0.1;
y = 0.3;
equal = Math.abs(x - y) < Number.EPSILON;

Please note that this value property is available since Qt 5.8. In previous Qt releases you can define your own epsilon, e.g. as:

readonly property double epsilon: Math.pow(2, -52)
BaCaRoZzo
  • 7,502
  • 6
  • 51
  • 82
GrecKo
  • 6,615
  • 19
  • 23
1

From the documentation for real

Note: In QML all reals are stored in double precision, IEEE floating point format.

From the documentation on data type conversion

+----------------+----------------+
|    Qt Type     | QML Basic Type |
+----------------+----------------+
|  [...]         |  [...]         |
|  double        |  double        |
|  [...]         |  [...]         |
|  float, qreal  |  real          |
+----------------+----------------+

So, according to the documentation not everything is neccessarily casted to real, but everything will have the same precision, so I think you can cast or compare them as you like.

You can either create a JavaScript Library in which you implement the function, just as described in your question.
Or you can create a C++-Object, and expose a this function, so you have the implementation directly in C++. Then you can decide, whether you instantiate this object in every file, where you need it, or if you create a singleton instance as library. AFAIK QML has problems with static functions and needs an instance of the object.

I don't know of any predefined variable in QML that specifies an epsilon. In C++, for me it is:

std::numeric_limits<double>::epsilon() -> 2.220446049250313e-16

so something around this might be a good choice.

Rudy Velthuis
  • 28,387
  • 5
  • 46
  • 94
  • so, whenever I compare, I want to do a high precision comparison using epsilon. do you suggest anything on how should I do that on in a `qml` file? OR do you think that it unnecessary to replicate following method(mentioned in question) in a `qml` file? `bool AreSame(double a, double b) { return fabs(a - b) < EPSILON; }` – TheWaterProgrammer Jul 24 '17 at 09:50
  • 1
    Ok, I was mostly focused on "*Or, Is it that it gets casted to real in QML & one need not worry about it?*" – derM - not here for BOT dreams Jul 24 '17 at 10:57
  • :) Primary goal of this question is how to replicate this : - `bool AreSame(double a, double b) { return fabs(a - b) < EPSILON; }` ? – TheWaterProgrammer Jul 24 '17 at 11:00
  • so, if I want to do it at QML level, then I need a javascript file like `UsefulMethods.js`. then include that in say `main.qml` & call that method like any other `qml` method. correct ? taking a look at that example you linked – TheWaterProgrammer Jul 24 '17 at 11:09
  • If you don't want to implement the function over and over again: Implement it in "UsefulMethods.js", then import it in each file where you want to use it. By importing it in the file where you want to use it, you reduce interfile dependencies and cut short the chain for name look-up. – derM - not here for BOT dreams Jul 24 '17 at 11:30
  • going by the .js way, there seems to be a `Math` component in qml that is from javascript? Learning this javascript + qml newly. How can I get the epsilon value from that `Math` component ? – TheWaterProgrammer Jul 24 '17 at 11:34