Floating point range analysis?

I have an image processing program that uses floating point calculations. However, I need to transfer it to a processor that does not have floating point support. So, I have to change the program to use fixed point calculations. To do this, I need the correct scaling of these floating point numbers, for which I need to know the range of all values, including intermediate values ​​of floating point calculations.

Is there a method when I just run the program and it automatically gives me the range of all floating point calculations in the program? Trying to figure out the ranges manually would be too cumbersome, so if there is any tool for this, it would be awesome!

+4
source share
3 answers

You can use some “dimensional” replacement for your floating type along these lines ( live example ):

template<typename T>
class foo
{
    T val;

    using lim = std::numeric_limits<int>;

    static int& min_val() { static int e = lim::max(); return e; }
    static int& max_val() { static int e = lim::min(); return e; }

    static void sync_min(T e) { if (e < min_val()) min_val() = int(e); }
    static void sync_max(T e) { if (e > max_val()) max_val() = int(e); }

    static void sync(T v)
    {
        v = std::abs(v);
        T e = v == 0 ? T(1) : std::log10(v);
        sync_min(std::floor(e)); sync_max(std::ceil(e));
    }

public:
    foo(T v = T()) : val(v) { sync(v); }
    foo& operator=(T v) { val = v; sync(v); return *this; }

    template<typename U> foo(U v) : foo(T(v)) {}
    template<typename U> foo& operator=(U v) { return *this = T(v); }

    operator T&() { return val; }
    operator const T&() const { return val; }

    static int min() { return min_val(); }
    static int max() { return max_val(); }
};

to be used as

int main ()
{
    using F = foo<float>;
    F x;

    for (F e = -10.2; e <= 30.4; e += .2)
        x = std::pow(10, e);

    std::cout << F::min() << " " << F::max() << std::endl;  // -11 31
}

This means that you need to define an alias (say Float) for your floating type ( Floator double) and use it consistently throughout the program. It may be inconvenient, but it may prove useful in the end (because then your program is more general). If your code is already set to a floating type, even better.

"" "", Float foo<T> T, T - Float double.

, , . , , , . (, ) foo. , .

+3

, , - - , , .

, , - over/underflow ( ).

++ Anthony Williams. ++ fixed , , float double fixed. int64_t 34 28 (34Q28), 8 , int32_t.

/, , .

32- ARM 5 , - , ARM VFP C.

, sqrt() , , . , , .

+3

C Frama-C , h :

value analysis on floating-point variable h

g, h:

value analysis on floating-point variable g

(, - ). , , float_interval:

/*@ ensures \is_finite(\result) && l <= \result <= u ; */
float float_interval(float l, float u);

Frama-C is easiest to install on Linux, with Debian and Ubuntu binary packages for the latest (but usually not the latest) version available from the distribution.

If you could post your code, it would help to find out if this approach is realistic. If your C ++ code, for example (your question does not say, it is marked with several language tags), then the current version of Frama-C will not help, since it only accepts C programs.

+2
source

Source: https://habr.com/ru/post/1537091/


All Articles