2

I have a matrix of type CV_32FC1, and I want to limit its precision. For instance, it has value like this:

[0.00021743798, 0.000174778698, 0.00011652464, 5.826234e-005, 1.561136e-005]

But I want to limit its precision so that it will look like this (like in Matlab):

[0.0002, 0.0002, 0.0001, 0.0001, 0.0000]

I'm not looking for a std::setprecision solution but rather to completely limit the matrix value precision inside, because this will affect multiplication with other matrix later in my case. Changing matrix type didn't help (at least). What should I do? Thank you.

E_learner
  • 3,512
  • 14
  • 57
  • 88
  • So you want to round your doubles to some decimal? Chek this out: http://stackoverflow.com/questions/1343890/rounding-number-to-2-decimal-places-in-c – Potaito Jun 03 '15 at 07:28
  • just for displaying? – Micka Jun 03 '15 at 07:56
  • Multiply by 10000, trunc/round, and divide by 10000? – Adi Shavit Jun 03 '15 at 08:01
  • Thank you all but I've already tried all your suggestions. BTW, it is not just for displaying, as mentioned in the question, that is why I don't use ´std::setprecision´ method. Even going through for loop with multiplying by ´10000´ and divide again is not giving precise output. For instance, it gives me like ´0.00030612201´ when I expect to get ´0.00030000000´. – E_learner Jun 03 '15 at 08:22
  • multiply, round and divide method might not work for all cases! – sriram Jun 03 '15 at 08:24

2 Answers2

2

May be these should work (do some initial checks)

float customPrecision(float in)
{
     char buffer[15];
     int bufLen = sprintf(buffer, "%.4f", in);
     return atof(buffer);
}

I am afraid on choosing the buffer size, as float can give you 23 bits of significand, 8 bits of exponent, and 1 sign bit. Someone can help out on choosing the right buffer size.

As suggested by Adi,

float roundtoPrecision(float val,int precision)
{
     // Do initial checks
     float output = roundf(val * pow(10,precision))/pow(10,precision);
     return output;
}

int main()
{
    // your code goes here
    float a[] = {0.00021743798, 0.000174778698, 0.00011652464, 5.826234e-005, 1.561136e-005};

    for (int index = 0; index < 5; index++)
    {

        float val = roundtoPrecision(a[index], 4);
        cout << val << endl;
    }
    return 0;
}
sriram
  • 411
  • 2
  • 7
  • Although it is not giving exactly what I want, but it at least gives the most closest output, thank you. – E_learner Jun 03 '15 at 10:58
1

This function limit_precision() seems to work for me :

#include <iostream>
#include <vector>
#include <cmath>

template<typename T>
T limit_precision(T val, int precision) {
    return std::floor((val * std::pow(10, precision) + 0.5)) / std::pow(10, precision); 
}

int main() {
    std::vector<float> v{0.00021743798, 0.000174778698, 0.00011652464, 5.826234e-005, 1.561136e-005};
    for (auto &el : v) { el = limit_precision(el, 4); }
    for (auto el : v) { std::cout << el << ", "; }
    std::cout << std::endl;
}

Output is : 0.0002, 0.0002, 0.0001, 0.0001, 0

coincoin
  • 4,595
  • 3
  • 23
  • 47