Ergebnis 1 bis 3 von 3

Thema: Anteile mit hoher Genauigkeit [C++]

  1. #1
    Forum Guru Avatar von The User
    Registriert seit
    28.10.2007
    Ort
    Zwischen Pazifik und Atlantik...
    Beiträge
    4.044
    Danke
    0
    Bekam 0 mal "Danke" in 0 Postings

    Standard Anteile mit hoher Genauigkeit [C++]

    Fließkommazahlen (float, double,...) reichen nicht immer aus, um gebrochene Zahlen darzustellen.
    Festkommazahlen stellen dabei eine Möglichkeit dar. Häufig kommt es vor, dass man Anteile ausdrücken möchte, also Zahlen im Intervall [0, 1] oder [-1, 1], genau das leistet dieses Klassen-Template. Im beigelegten Archiv findet man alles, was gebraucht wird.
    Darüber hinaus wird über eine Policy eine Überprüfung auf Laufzeitfehler (overflow/underflow) ermöglicht. Diese kann aber selbstverständlich abgestellt werden

    Ein Beispiel:
    Code:
    #include <iostream>
    #include "part.h"
    
    using namespace std;
    using namespace numerics;
    
    typedef part<unsigned int, double, part_policies::assert_check> part_t;
    
    int main()
    {
    	part_t x = part_t::from_float(0.25);
    	part_t y = part_t::from_float(0.5);
    	part_t z = x * y;
    	cout << z << endl;
    	z *= 6;
    	cout << z << endl;
    	z -= 0.6;
    	cout << z << endl;
    	z -= y; // z would be less than 0, assertion fails
    }
    Der Code des Klassen-Templates:
    Code:
    /*
    	(C) 2009 Jonathan Schmidt-Dominé
    	
    	This program is free software: you can redistribute it and/or modify
    	it under the terms of the GNU Lesser General Public License as
    	published by the Free Software Foundation, either version 3 of the
    	License, or (at your option) any later version.
    	
    	This program is distributed in the hope that it will be useful,
    	but WITHOUT ANY WARRANTY; without even the implied warranty of
    	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    	GNU Lesser General Public License for more details.
    	
    	To read the text of the GNU Lesser General Public License,
    	see <http://www.gnu.org/licenses/>.
    */
    
    #ifndef NUMERICS_PART_H
    #define NUMERICS_PART_H
    
    #include <cassert>
    #include <limits>
    
    // When you don't want to use STL's <iostream>, declare NUMERICS_NO_IO.
    #ifndef NUMERICS_NO_IO
    #include <iostream>
    #endif
    
    #include "operators.h"
    
    namespace numerics
    {
    
    
    namespace part_policies
    {
    	/**
    	 * No checks for overflow and underflow will be performed.
    	 */
    	template<class T>
    	struct no_check
    	{
    		typedef typename T::data_type data_type;
    		inline static void plus(const data_type, const data_type)
    		{}
    		inline static void minus(const data_type, const data_type)
    		{}
    		template<typename F>
    		inline static void from_float(const F f)
    		{}
    		template<typename F>
    		inline static void multiply(const data_type, const F)
    		{}
    		template<typename F>
    		inline static void divide(const data_type, const F)
    		{}
    	};
    	/**
    	 * Checks are performed at runtime using assert, iff NDEBUG was not set.
    	 * This makes it simple to search for bugs in calculations.
    	 */
    	template<class T>
    	struct assert_check
    	{
    		typedef typename T::data_type data_type;
    		inline static void plus(const data_type first, const data_type second)
    		{
    			assert(T::max() - second >= first);
    		}
    		inline static void minus(const data_type first, const data_type second)
    		{
    			assert(first - T::min() >= second);
    		}
    		template<typename F>
    		inline static void from_float(const F f)
    		{
    			assert(f <= 1);
    			assert(f >= (T::min() == 0 ? 0 : -1));
    		}
    		template<typename F>
    		inline static void multiply(const data_type first, const F second)
    		{
    			assert(T::max() / second >= first);
    			assert(T::min() / second <= first);
    		}
    		template<typename F>
    		inline static void divide(const data_type first, const F second)
    		{
    			assert(F(first) / T::max() <= second);
    			assert(-F(first) / T::max() <= second);
    		}
    	};
    };
    
    /**
     * This class represents a number from the interval [0, 1] (T is unsigned) or [-1, 1] (T is signed).
     * It can be useful when you need high precision for such numbers.
     * You can use the instances of this class like normal floating-point numbers.
     * Don't forget to use \p typedefs for instances of the class-template.
     * @param T - The type used to represent the number. It's typically a signed or an unsigned integer.
     * @param Float - For some calclations you'll still need floating-point-numbers. This type will normally be used for internall calculations and checking. You'll typically use double, with an Integer you may lose a precision.
     * @param CheckingPolicy - A class like part_policies::no_check or part_policies::assert_check. This policy can check for under- and overflows.
     */
    template<typename T, typename Float = double, template<typename> class CheckingPolicy = part_policies::no_check>
    class part
    {
    	static T minimum;
    public:
    	T data;
    	inline static const T max()
    	{
    		return std::numeric_limits<T>::max();
    	}
    	inline static const T min()
    	{
    		return minimum;
    	}
    	typedef part<T, Float, CheckingPolicy> self;
    	typedef T data_type;
    	typedef CheckingPolicy<self> check;
    	typedef Float float_type;
    	part() : data(0)
    	{
    	}
    	explicit part(const T data) : data(data)
    	{
    	}
    	template<typename F>
    	inline static self from_float(const F f)
    	{
    		check::from_float(f);
    		return self(f * max());
    	}
    	inline static self from_float(const Float f)
    	{
    		check::from_float(f);
    		return self(f * max());
    	}
    	template<typename F>
    	inline void set_float(const F f)
    	{
    		check::from_float(f);
    		data = f * max();
    	}
    	inline void set_float(const Float f)
    	{
    		check::from_float(f);
    		data = self(f * max());
    	}
    	inline self& operator+=(const self s)
    	{
    		check::plus(data, s.data);
    		data += s.data;
    		return *this;
    	}
    	inline self& operator-=(const self s)
    	{
    		check::minus(data, s.data);
    		data -= s.data;
    		return *this;
    	}
    	inline self& operator*=(const self s)
    	{
    		data /= (float_type(max()) / s.data);
    		return *this;
    	}
    	template<typename F>
    	inline F to_float() const
    	{
    		return F(data) / max();
    	}
    	inline Float to_float() const
    	{
    		return Float(data) / max();
    	}
    	template<typename U>
    	inline self& operator*=(const U t)
    	{
    		check::multiply(data, t);
    		data *= t;
    		return *this;
    	}
    	template<typename U>
    	inline self& operator/=(const U t)
    	{
    		check::divide(data, t);
    		data /= t;
    		return *this;
    	}
    	template<typename U>
    	inline self& operator+=(const U t)
    	{
    		check::from_float(t);
    		T tmp(t * max());
    		check::plus(data, tmp);
    		data += tmp;
    		return *this;
    	}
    	template<typename U>
    	inline self& operator-=(const U t)
    	{
    		check::from_float(t);
    		T tmp(t * max());
    		check::minus(data, tmp);
    		data -= tmp;
    		return *this;
    	}
    };
    
    template<typename T, typename F, template<typename> class CP>
    inline bool operator==(const part<T, F, CP> first, const part<T, F, CP> second)
    {
    	return first.data == second.data;
    }
    
    template<typename T, typename F, template<typename> class CP>
    inline bool operator<(const part<T, F, CP> first, const part<T, F, CP> second)
    {
    	return first.data < second.data;
    }
    
    template<typename T, typename F, template<typename> class CP>
    inline F operator/(const part<T, F, CP> first, const part<T, F, CP> second)
    {
    	return F(first.data) / second.data;
    }
    
    #ifndef NUMERICS_NO_IO
    
    template<typename T, typename F, template<typename> class CP>
    inline std::ostream& operator<<(std::ostream& out, const part<T, F, CP> p)
    {
    	out << p.to_float();
    	return out;
    }
    
    template<typename T, typename F, template<typename> class CP>
    inline std::istream& operator>>(std::istream& in, part<T, F, CP>& p)
    {
    	F f;
    	in >> f;
    	p.set_float(f);
    	return in;
    }
    
    #endif
    
    template<typename T, typename F, template<typename> class CP>
    T part<T, F, CP>::minimum  = std::numeric_limits<T>::is_signed ? -std::numeric_limits<T>::max() : 0;
    
    };
    
    #endif
    Kommentare währen mir lieb, insbesondere wie es mit impliziten Konvertierungen aussieht. Ich habe soetwas nun vorsichtshalber erst einmal ausgeschlossen. Eine automatische Konvertierung von/nach double wäre aber natürlich möglich.

    Viele liebe Grüße
    The User
    Achtung: Dies ist ein alter Thread im HTML und Webmaster Forum
    Diese Diskussion ist älter als 90 Tage. Die darin enthaltenen Informationen sind möglicherweise nicht mehr aktuell. Erstelle bitte zu deiner Frage ein neues Thema im Forum !!!!!
    Angehängte Dateien Angehängte Dateien

  2. #2
    Estefani
    Gast

    Standard AW: Anteile mit hoher Genauigkeit [C++]

    Hallo! Als Student der commputer Wissenschaften, dieses Amt war wirklich hilfreich für mich.

  3. #3
    Forum Guru
    Themenstarter
    Avatar von The User
    Registriert seit
    28.10.2007
    Ort
    Zwischen Pazifik und Atlantik...
    Beiträge
    4.044
    Danke
    0
    Bekam 0 mal "Danke" in 0 Postings

    Standard AW: Anteile mit hoher Genauigkeit [C++]

    Hmm? Was für ein Amt? Das hier ist einfach nur eine Festkommazahl...

Ähnliche Themen

  1. Probleme bei hoher Tabellenanzahl in MySQL?
    Von FaFoo im Forum PHP Forum - Apache - CGI - Perl - JavaScript und Co.
    Antworten: 6
    Letzter Beitrag: 23.03.2008, 21:35
  2. zu hoher pin im spiel
    Von highlaender im Forum Computer - Internet Forum
    Antworten: 1
    Letzter Beitrag: 05.12.2006, 13:33
  3. Genauigkeit bei Gleitkommazahlen
    Von ALex16 im Forum Flash Forum
    Antworten: 1
    Letzter Beitrag: 15.10.2006, 10:28
  4. Bei Hoher zu Hoher Auflösung, verzerrt es sich !
    Von Innominate im Forum HTML & CSS Forum
    Antworten: 3
    Letzter Beitrag: 13.02.2006, 12:06
  5. linktausch mit hoher traffic seite ...
    Von UltraMeb im Forum Promotion - SEO - Suchmaschine (Google & Co) – Mitarbeiter & Linkpartnersuche
    Antworten: 2
    Letzter Beitrag: 23.01.2006, 22:52

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •