[SOLVED - by using qFuzzyCompare] If help (comparing floats)



  • OK, at first sight this might seem basic but I'm supposed to be way past this and yet again I'm getting these weird results.

    Intro:
    I have an 2d array of floats @float P_profili[15][7];@ where the first value of every row is a diameter (example: P_profili[something] [0]=100).
    I also have an array of diameters @float R_Da_b[99];@ which is directly extracted from the 2d array mentioned above (this happens previously in the code).

    Situation:
    I have a function which for each member of R_Da_b tries to find a same value in P_profili and return a previous one to another float (R_Da_bP -> P as Previous):

    @void pocetni::findingTheProfile()
    {
    int i;
    for(i=1; i<tT; ++i)
    {
    int j=0;
    bool isItOK=false;
    while(!isItOK && j<=14)
    {
    ui->out_debug->append(QString::number(R_Da_b[i])+" :: " + QString::number(P_profili[j][0]/1000));
    if(R_Da_b[i]==P_profili[j][0]/1000) // where the problem occurs
    {
    if(j>0){R_Da_bP[i]=P_profili[j-1][0]/1000; isItOK=true;}
    else{R_Da_bP[i]=0.08; isItOK=true;} //this is in the case if it's below the first table value (P_profili[0][0])
    }
    else{R_Da_bP[i]=0.666; ++j;} //this is a random number for debug
    }
    ui->out_debug->append("---- :: " + QString::number(R_Da_b[i])+" :: " + QString::number(R_Da_bP[i]));
    }
    }@

    The problem:
    It does not recognize specific values as the same. Possible values are 0.1, 0.125, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.6, 0.7, 0.8, 0.9, 1
    Out of those values, only two it can recognize as the same are: 0.125, 0.25, 0.5, 1

    Additional info:
    Copy paste from debug window (notice how it skips the exact same values as if they are not the same)
    The only one it recognizes as same is 0.25:

    0.4 :: 0.1
    0.4 :: 0.125
    0.4 :: 0.15
    0.4 :: 0.2
    0.4 :: 0.25
    0.4 :: 0.3
    0.4 :: 0.35
    0.4 :: 0.4
    0.4 :: 0.45
    0.4 :: 0.5
    0.4 :: 0.6
    0.4 :: 0.7
    0.4 :: 0.8
    0.4 :: 0.9
    0.4 :: 1
    ---- :: 0.4 :: 0.666
    0.35 :: 0.1
    0.35 :: 0.125
    0.35 :: 0.15
    0.35 :: 0.2
    0.35 :: 0.25
    0.35 :: 0.3
    0.35 :: 0.35
    0.35 :: 0.4
    0.35 :: 0.45
    0.35 :: 0.5
    0.35 :: 0.6
    0.35 :: 0.7
    0.35 :: 0.8
    0.35 :: 0.9
    0.35 :: 1
    ---- :: 0.35 :: 0.666
    0.25 :: 0.1
    0.25 :: 0.125
    0.25 :: 0.15
    0.25 :: 0.2
    0.25 :: 0.25
    ---- :: 0.25 :: 0.2
    0.15 :: 0.1
    0.15 :: 0.125
    0.15 :: 0.15
    0.15 :: 0.2
    0.15 :: 0.25
    0.15 :: 0.3
    0.15 :: 0.35
    0.15 :: 0.4
    0.15 :: 0.45
    0.15 :: 0.5
    0.15 :: 0.6
    0.15 :: 0.7
    0.15 :: 0.8
    0.15 :: 0.9
    0.15 :: 1
    ---- :: 0.15 :: 0.666
    0.1 :: 0.1
    0.1 :: 0.125
    0.1 :: 0.15
    0.1 :: 0.2
    0.1 :: 0.25
    0.1 :: 0.3
    0.1 :: 0.35
    0.1 :: 0.4
    0.1 :: 0.45
    0.1 :: 0.5
    0.1 :: 0.6
    0.1 :: 0.7
    0.1 :: 0.8
    0.1 :: 0.9
    0.1 :: 1
    ---- :: 0.1 :: 0.666
    0.15 :: 0.1
    0.15 :: 0.125
    0.15 :: 0.15
    0.15 :: 0.2
    0.15 :: 0.25
    0.15 :: 0.3
    0.15 :: 0.35
    0.15 :: 0.4
    0.15 :: 0.45
    0.15 :: 0.5
    0.15 :: 0.6
    0.15 :: 0.7
    0.15 :: 0.8
    0.15 :: 0.9
    0.15 :: 1
    ---- :: 0.15 :: 0.666
    0.15 :: 0.1
    0.15 :: 0.125
    0.15 :: 0.15
    0.15 :: 0.2
    0.15 :: 0.25
    0.15 :: 0.3
    0.15 :: 0.35
    0.15 :: 0.4
    0.15 :: 0.45
    0.15 :: 0.5
    0.15 :: 0.6
    0.15 :: 0.7
    0.15 :: 0.8
    0.15 :: 0.9
    0.15 :: 1
    ---- :: 0.15 :: 0.666



  • Your code is terribly difficult to read. And if you are using unrecognizable names for variables, you could at least rename them before posting your code here, so others have an easier time of understanding your problem.

    Number one, maybe not even related to what you are doing:
    Maybe try out "qFuzzyCompare(float,float)":http://qt-project.org/doc/qt-5/qtglobal.html#qFuzzyCompare-10 instead of the standard "==".

    Number two:
    Why is this code so complicated and what is it supposed to do?
    @if(R_Da_b[i] == P_profili[j][0]/1000)
    {
    ...
    }@
    I assume that dividing the value by 1000 is correct? If so, qFuzzyCompare might really help you out.

    @else
    {
    ++j;
    }@
    So you are iterating over your list of diameters to make comparisons. And if a value differs, you step forward in both that list and the array from which you take the values to compare with. This strikes me as strange behavior, I hope it is intended to be like that.

    You are in a Qt forum, maybe you could use some "QLists":http://qt-project.org/doc/qt-5/qlist.html to make your life easier?



  • [quote author="thEClaw" date="1404106363"]Your code is terribly difficult to read. And if you are using unrecognizable names for variables, you could at least rename them before posting your code here, so others have an easier time of understanding your problem.[/quote]
    I am aware of this, I already found a way easier workaround for the problem. However I still do not understand why this does not work.

    [quote author="thEClaw" date="1404106363"]
    Number one, maybe not even related to what you are doing:
    Maybe try out "qFuzzyCompare(float,float)":http://qt-project.org/doc/qt-5/qtglobal.html#qFuzzyCompare-10 instead of the standard "==".[/quote]
    Will definitely give it a look.

    [quote author="thEClaw" date="1404106363"]
    Number two:
    Why is this code so complicated and what is it supposed to do?
    @if(R_Da_b[i] == P_profili[j][0]/1000)
    {
    ...
    }@
    I assume that dividing the value by 1000 is correct? If so, qFuzzyCompare might really help you out.[/quote]
    That is correct. The value to the right is in milimeters and one to the left is in meters (hence division by 1000). Note that all the values have 3 decimal points at max (see output, I know it's long but you'll get the picture). Also note that the value to the left directly came from the value to the right previously in the code, at which time it was also divided by 1000.

    [quote author="thEClaw" date="1404106363"]
    @else
    {
    ++j;
    }@
    So you are iterating over your list of diameters to make comparisons. And if a value differs, you step forward in both that list and the array from which you take the values to compare with. This strikes me as strange behavior, I hope it is intended to be like that.[/quote]
    It is intended to be like that, for each R_Da_b it tries to find to find the exact same value in P_profili and return the previous one ( [j-1] or a specific value of 0.08 if it is below the first value in P_profili ) and store it into R_Da_bP.

    [quote author="thEClaw" date="1404106363"]
    You are in a Qt forum, maybe you could use some "QLists":http://qt-project.org/doc/qt-5/qlist.html to make your life easier?[/quote]

    Will definitely give it a look.



  • The
    @++j;@
    is still not clear to me. You are iterating over i while incrementing j in case there was a mismatch. Looks like you are skipping comparisons.

    Also, if QList is too overblown for you, QVector might be an alternative.



  • [quote author="thEClaw" date="1404124638"]The
    @++j;@
    is still not clear to me. You are iterating over i while incrementing j in case there was a mismatch. Looks like you are skipping comparisons.
    [/quote]
    Definitely not the case, see output. The while loop won't stop until j has reached it's max value of 14 or if it managed to find the exact same value in which case isItOK becomes true (hence @while(!isItOK && j<=14)@).
    It is bound to find the exact match for each i, before j reaches 14 but for some values it does not.
    Example: My first R_Da_b[i] is equal to 0.4 and P_profili[j] [0] contains the following values: 0.1, 0.125, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.6, 0.7, 0.8, 0.9, 1
    (these are after division by 1000).
    Output for this case:
    0.4 :: 0.1
    0.4 :: 0.125
    0.4 :: 0.15
    0.4 :: 0.2
    0.4 :: 0.25
    0.4 :: 0.3
    0.4 :: 0.35
    0.4 :: 0.4 //note how at this point it does not stop
    0.4 :: 0.45
    0.4 :: 0.5
    0.4 :: 0.6
    0.4 :: 0.7
    0.4 :: 0.8
    0.4 :: 0.9
    0.4 :: 1 //while loop starts because j is now over 14
    R_Da_b[i] is the value to the left, P_profili[j] [0] is to the right. R_Da_b stays the same until while is done.

    In another case where my R_Da_b[i] is equal to 0.25 it does recognize it as the same. Here's the output:

    0.25 :: 0.1
    0.25 :: 0.125
    0.25 :: 0.15
    0.25 :: 0.2
    0.25 :: 0.25 //note that the while loop stops because isItOK is true

    I gave this many tries, it does not depend on which [i] it is at the moment, it is only dependent on whether R_Da_b is the following value (0.125, 0.25, 0.5, 1). If it is not one of those, it will never detect them as equal.



  • Not even when using qFuzzyCompare?



  • [quote author="thEClaw" date="1404125719"]Not even when using qFuzzyCompare?[/quote]

    Will give it a try in a minute, just woke up :)



  • Thanks alot, qFuzzyCompare works!

    Output:
    0.4 :: 0.1
    0.4 :: 0.125
    0.4 :: 0.15
    0.4 :: 0.2
    0.4 :: 0.25
    0.4 :: 0.3
    0.4 :: 0.35
    0.4 :: 0.4
    ---- :: 0.4 :: 0.35
    0.35 :: 0.1
    0.35 :: 0.125
    0.35 :: 0.15
    0.35 :: 0.2
    0.35 :: 0.25
    0.35 :: 0.3
    0.35 :: 0.35
    ---- :: 0.35 :: 0.3
    0.3 :: 0.1
    0.3 :: 0.125
    0.3 :: 0.15
    0.3 :: 0.2
    0.3 :: 0.25
    0.3 :: 0.3
    ---- :: 0.3 :: 0.25
    0.15 :: 0.1
    0.15 :: 0.125
    0.15 :: 0.15
    ---- :: 0.15 :: 0.125
    0.15 :: 0.1
    0.15 :: 0.125
    0.15 :: 0.15
    ---- :: 0.15 :: 0.125
    0.125 :: 0.1
    0.125 :: 0.125
    ---- :: 0.125 :: 0.1
    0.125 :: 0.1
    0.125 :: 0.125
    ---- :: 0.125 :: 0.1

    Great to know it can work this way, although I still don't understand why it wouldn't work with ==. Wouldn't be much of a wonder if it didn't work for some values and not for others.
    I used it as following: @if(qFuzzyCompare(R_Da_b[i], P_profili[j][0]/1000))@
    Much love <3


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.