"Christmas - the time to fix the computers of your loved ones" « Lord Wyrm

single precision saturation

wergor 18.01.2021 - 15:31 3979 4
Posts

wergor

connoisseur de mimi
Avatar
Registered: Jul 2005
Location: graz
Posts: 4019
ich habe eine IEEE 754 single precision float x. in einer schleife wird zu x eine zahl y im bereich von 0-32767 addiert. ab welchem wert von x ist
Code:
x + y = x
wenn
  1. y = 32767
  2. y = 1024
  3. y = 1
?

wergor

connoisseur de mimi
Avatar
Registered: Jul 2005
Location: graz
Posts: 4019
meine quick+dirty lösung:
Code: C++
#include <math.h>
#include <limits>

#include <stdio.h>
#include <iostream>

int main()
{
    float max = std::numeric_limits<float>::max();
    float min = 0.0f;

    float y = 32767;

    float diff;

    do
    {
        float x = (max - min) / 2.0f;

        diff = abs(x - (x + y));

        if (diff <= std::numeric_limits<float>::epsilon())
            max = x;
        else
            min = x;

    } while (diff <= std::numeric_limits<float>::epsilon());

    std::cout << max << std::endl;
}

  1. 1.09951e+12
  2. 6.87195e+10
  3. 6.71089e+07

mat

Administrator
Legends never die
Avatar
Registered: Aug 2003
Location: nö
Posts: 25371
Ist das ein IQ-Test oder hast du eine spezielle Frage zur Implementierung? :D

Bei float == float musst du immer vorsichtig sein. Wenn es deine Implementierung zulässt, dann entweder < oder > bzw. gewisse Thresholds verwenden (0,1 oder Epsilon zB). Es gibt dazu eine Menge Material online. Ich würde mir Sprachen-spezifische Beispiele dazu anschauen, da es doch teilweise deutliche Unterschiede bzw. auch bereits vorhandene Konstanten gibt.

wergor

connoisseur de mimi
Avatar
Registered: Jul 2005
Location: graz
Posts: 4019
Zitat aus einem Post von mat
Bei float == float musst du immer vorsichtig sein.
ich weis ;) siehe c++ code. die frage war aber absichtlich nicht auf eine bestimmte sprache bezogen.
ich implementiere was auf einem fpga (in labview) und will wissen ob ein akkumulator da drin in sättigung geht. ich habs jetzt auf die klassische art implementiert, ich weis aber noch nicht ob ich fehler bei kleinen y ignorieren kann / muss und nicht doch einen fixen wert verwende.
overflow_249410.png

wergor

connoisseur de mimi
Avatar
Registered: Jul 2005
Location: graz
Posts: 4019
im code oben sind ein paar fehler drin. hier der korrigierte code, nicht dass vinci den nassen fetzen auspackt :D
Code: C++
#include <math.h>
#include <limits>

#include <stdio.h>
#include <iostream>

int main()
{
    float max = std::numeric_limits<float>::max();
    float min = 0.0f;

    float y = 32767.0f;

    float diff;

    do
    {
        float x = (max / 2.0f) + (min / 2.0f);

        diff = abs(x - (x + y));

        if (diff <= std::numeric_limits<float>::epsilon())
            max = x;
        else
            min = x;

    } while (abs(max-min) > 2.0f*y);

    std::cout << max << std::endl;
}

  1. 5.49756e+11
  2. 3.43597e+10
  3. 3.35544e+07
Kontakt | Unser Forum | Über overclockers.at | Impressum | Datenschutz