single precision saturation
wergor 18.01.2021 - 15:31 4131 4
wergor
connoisseur de mimi
|
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 x + y = x
wenn - y = 32767
- y = 1024
- y = 1
?
|
wergor
connoisseur de mimi
|
meine quick+dirty lösung: #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.09951e+12
- 6.87195e+10
- 6.71089e+07
|
mat
AdministratorLegends never die
|
Ist das ein IQ-Test oder hast du eine spezielle Frage zur Implementierung? 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
|
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.
|
wergor
connoisseur de mimi
|
im code oben sind ein paar fehler drin. hier der korrigierte code, nicht dass vinci den nassen fetzen auspackt #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;
}
- 5.49756e+11
- 3.43597e+10
- 3.35544e+07
|