wie checkst du bitte auf "0" bei long double ?
Natürlich teste ich nicht auf 0 sondern auf |x|<epsilon, wobei epsilon eine Konstante im Program nahe 0 ist. In meinem Fall teste ich allerdings gegen eine andere Variable - siehe unteres Listing...
Wie RHBaum schon sagte - hier hat der Compiler unter Garantie keine Schuld und der Fehler sitzt vor dem Bildschirm.
Das sage ich auch immer, und hoffe das das auch hier der Fall ist
Schreib uns ein Testcase und wir werden den Fehler finden.
Hier mein Code:
Es gibt eine Library in der steht folgende Klasse mit folgender Funktion:
Code: Alles auswählen
class RgbNorm : public RefObj
{
public:
RgbNorm_t r;
RgbNorm_t g;
RgbNorm_t b;
RgbNorm();
RgbNorm(const RgbNorm &_rhs);
RgbNorm(const RgbNorm_t _r,
const RgbNorm_t _g,
const RgbNorm_t _b);
RgbNorm& operator=(const RgbNorm &_rgb);
bool operator==(const RgbNorm &_rgb) const;
bool operator!=(const RgbNorm &_rgb) const;
void SetRgb(const RgbNorm_t _r,
const RgbNorm_t _g,
const RgbNorm_t _b);
RgbNorm_t GetAverage() const;
RgbNorm_t GetDistanceQuad(const RgbNorm &_rhs) const;
void Invert(); // invert the rgb-values (rgb_new = 255 - rgb_old)
public:
virtual enumArchive Stream(Archive &_a);
}; // class RgbNorm
die Basisklasse RefObj implementiert einen Referenzzähler und kann hier ignoriert werden.
Hier interessiert die Methode:
GetDistanceQuad
Code: Alles auswählen
///////////////////////////////////////////////////////////////////////////////
// RgbNorm::GetDistanceQuad
///////////////////////////////////////////////////////////////////////////////
RgbNorm_t RgbNorm::GetDistanceQuad(const RgbNorm &_rgb) const
{
RgbNorm_t fDist = (_rgb.r - r) * (_rgb.r - r) +
(_rgb.g - g) * (_rgb.g - g) +
(_rgb.b - b) * (_rgb.b - b); // != 0
return fDist; // nach Rückgabe == 0
} // RgbGetDistanceQuad
Hier gibts es das Problem, siehe auch weiter unten für die Erläuterung dessen, was die Klassen machen sollen.
Zu Testzwecken weise ich das Quadrat der Farbabweichung, einem Wert zu. Dieser ist an dieser Stelle != 0, nach Rückgabe == 0
------------------------------------------------------------------------------
In einer weiteren Bibliothek steht folgende Klasse:
Code: Alles auswählen
class Palette : public RefObj
{
protected:
u16 m_u16Colors; // no. of the colors in this palette
RgbNorm *m_pRgb; // pointer to the rgb-values
public:
Palette(); // creates an empty palette
Palette(enumPalType _ePalType); // creates the palette from PalType
Palette(const u16 _u16ColorCount, // for optimized palettes
const enumForceColor _eForceColor,
const Pic *_pPic);
//Palette(i16 _u16ColorCount,
// structRgbQuad *_pRgbQuad);
Palette(const Palette &_rhs);
virtual ~Palette();
/////////////////////////////////////////////////////////////////////////////
// operators
/////////////////////////////////////////////////////////////////////////////
public:
Palette& operator=(const Palette &_rhs);
/////////////////////////////////////////////////////////////////////////////
// access
/////////////////////////////////////////////////////////////////////////////
public:
u16 GetColorCount() const; // number of the colors in this palette
bool AddColor(const RgbNorm_t _r, // new color r-value to add
const RgbNorm_t _g, // new color g-value to add
const RgbNorm_t _b, // new color b-value to add
const bool _bCheck4Double); // True => check, whether the color is always in the palette
// return: true=> color was added or already in the palette
// false => always 0xffff colors in the palette => no color was added
bool AddColor(const RgbNorm &_rgbNew, // new color to add
const bool _bCheck4Double); // True => check, whether the color is always in the palette
// return: true => color was added or already in the palette
// false => always 0xffff colors in the palette => no color was added
const RgbNorm& GetRgb(const u16 _u16Index) const; // no check, _u16Index must not be greater than m_u16Colors-1
const RgbNorm& GetRgbCheck(const u16 _u16Index) const; // with check, _slIndex<0 || _slIndex>=m_u16Colors => return rgbBlack
void GetRgb(const u16 _u16Index, // no check, _u16Index must not be greater than m_u16Colors-1
RgbNorm &_rgb) const;
void GetRgb(const u16 _u16Index, // no check, _u16Index must not be greater than m_u16Colors-1
RgbNorm_t &_r,
RgbNorm_t &_g,
RgbNorm_t &_b) const;
virtual void GetNearestRgb(const RgbNorm &_rgbShut, // return the CRgb::GetDistanceQuad of the two rgb´s
RgbNorm &_rgbIs) const; // no color found => black
virtual RgbNorm_t GetNearestRgbDistQuad(const RgbNorm &_rgbShut, // return the CRgb::GetDistanceQuad of the two rgb´s
RgbNorm &_rgbIs) const; // no color found => black
// return: the distance to the shut-color
void SetRgb(const u16 _u16Index, // no check, _s32Index must not be greater than m_s32Colors-1
const RgbNorm &_rgb);
void SetRgb(const u16 _u16Index, // no check, _s32Index must not be greater than m_s32Colors-1
const RgbNorm_t _r,
const RgbNorm_t _g,
const RgbNorm_t _b);
private:
void AddWebPalette();
void MedianCut(s16 _s16Colors,
const Pic *_pPic);
/////////////////////////////////////////////////////////////////////////////
// modifying
/////////////////////////////////////////////////////////////////////////////
public:
void Invert(); // invert the rgb-values (rgb_new = 255 - rgb_old)
/////////////////////////////////////////////////////////////////////////////
// member from CBaseObj
/////////////////////////////////////////////////////////////////////////////
//public:
// // I/O-subroutines
//virtual enumArchive Archive(CArchiveAK &_a);
//protected:
//virtual void DeleteContents(); // default: does nothing
}; // class Palette
Hier interessiert die Methode:
GetNearestRgbDistQuad
Code: Alles auswählen
//////////////////////////////////////////////////////////////////////////
// Palette::GetNearestRgbDistQuad
//////////////////////////////////////////////////////////////////////////
RgbNorm_t Palette::GetNearestRgbDistQuad(const RgbNorm &_rgbShut,
RgbNorm &_rgbIs) const
{
CHECK_PRE_CONDITION(m_u16Colors > 0, 0)
u16 u;
s16 s16Index = 0;
RgbNorm_t fMinDist = m_pRgb[0].GetDistanceQuad(_rgbShut); // mit erstem Rgb-Wert-Abstand initialisieren
RgbNorm_t fDist;
for (u=1; u<m_u16Colors; u++)
{
fDist = m_pRgb[u].GetDistanceQuad(_rgbShut); // hier kommt 0 zurück!
if (fDist < fMinDist)
{
fMinDist = fDist;
s16Index = (s16) u;
}
} // for (si=0; si<m_u16Colors; si++)
return fMinDist;
} // Palette::GetNearestRgbDistQuad
-----------------------------------------------------
Was macht die Methode?
vorab:
Die Bibliotheken haben aus Kompatibilitätsgründen eigene Datentypen:
u16 ist unsigned mit 16 bit
s16 ist signed mit 16 bit
außerdem:
Ich suche den zu einem gegebenen RGB-Wert nächsten Paletteneintrag.
Dazu iteriere ich über die Einträge der Palette, berechne mir den quadratischen Abstand. Ist dieser Abstand kleiner als das bisherige Minimum, wird dieses gespeichert als potentiell nächste Farbe, usw.
Am Ende gebe ich diesen Abstand zurück, der ist aber natürlich dann 0.
Ach ja, der Fehler tritt auch mit RgbNorm_t = double auf!
Beide Bibliotheken (also die mit RgbNorm und die mit Palette) werden statisch zum Hauptprogramm gelinkt.
Ich hoffe, das diese Angaben helfen. Wie gesagt, auch ich gehe von einem Fehler VOR dem Bildschirm aus, allerdings sehe ich keinen, und soooo komplex ist das Programm ja nicht!
Danke und Gruß
[/code]