int mit 8 Bit definieren



  • Hi,
    ich benötige für ein kleies programm 8-Bit int's.
    Es war auch erstmal nicht das Problem es über ein typedef zu machen.

    typedef char int8;
    

    Nun habe ich aber das Problem, daß mein int8 z.B. con cout als char interpretiert wird.
    Wie kann ich mit einen 8 Bit datentyp definieren, der als Ganzzahlbehandelt wird?



  • Versuchs mal so:

    int IchBin8BitGross:8;
    


  • Einfach in einen Int Casten beim ausgeben mit cout - oder char in eine Klasse int8 Kapsel und operatoren überladen



  • wie wärs denn mit ner struct die 8 bools beinhaltet.
    dann kannst du auch gleich jedes bit einzeln abfragen



  • struct int8
    {
    	unsigned char myint;
    
    	int8() : myint() {}
    
    	template< typename T >
    		int8( T init ) : myint( init ) {}
    
    	template< typename T >
    	operator T()
    	{
    		return static_cast< T >( myint );
    	}
    
    	friend std::ostream& operator << ( std::ostream& out, int8 mint )
    	{
    		out << (int)mint.myint;
    		return out;
    	}
    
    	friend std::istream& operator >> ( std::istream& in, int8& mint )
    	{
    		short tmp;
    		in >> tmp;
    		mint.myint = tmp;
    		return in;
    	}
    };
    


  • @PuppetMaster2k
    Das funzt leider nicht.

    @Caster
    Funktioniert.

    Danke

    Mal noch eine Frage, gab es in C/C++ nicht schon einen 8 Bit Integer Typ?



  • daishi schrieb:

    gab es in C/C++ nicht schon einen 8 Bit Integer Typ?

    nö, dafür hat man immer char benutzt. viele api's definieren allerdings im header ein typedef char int8 oder so ähnlich. aber das funktioniert in deinem fall ja nicht.



  • typedef unsigned char int8;
    


  • Wäre folgendes nicht besser gewesen:

    template< typename T >
    friend std::ostream& operator << ( std::ostream& out, int8 mint )
    {
      template< typename T >
      out << static_cast< T >(mint.myint);
      return out;
    }
    

    ?



  • ...



  • @Apollon
    Bringt leider nix.

    Dazu gabs hier auch schon mal heisse Diskussionen. Wobei ich immer den Standpunkt vertreten habe dass es bekloppt ist dass C++ drei char Typen hat, aber trotzdem signed char und unsigned char im Zusammenhang mit Streams als Zeichen interpretiert (statt als Integers).

    Auf der Gegenseite war glaube ich Shade und evtl. noch 1-2 andere. (Sorry falls ich mich irre, ist schon ein paar Monate her.) Wobei ich die Argumente der Gegenseite immer noch nicht ganz verstanden habe. 🙂

    @Swordfish
    s.o.

    @Schlitzauge
    Check ich nicht. Was soll das darstellen?



  • ...



  • Swordfish schrieb:

    hustbaer schrieb:

    @@Swordfish
    s.o.

    Bitte etwas ausführlicher - stehe evtl. auf diversen Leitungen.

    Nun habe ich aber das Problem, daß mein int8 z.B. con cout als char interpretiert wird.

    P.S.: Zu genau diesem Problem habe ich bereits vor ner kleinen Weile nen Thread geöffnet.



  • Sone schrieb:

    P.S.: Zu genau diesem Problem habe ich bereits vor ner kleinen Weile nen Thread geöffnet.

    Fein. Und was fehlt?



  • Swordfish schrieb:

    hustbaer schrieb:

    @@Swordfish
    s.o.

    Bitte etwas ausführlicher - stehe evtl. auf diversen Leitungen.

    uint8_t ist oft genug (fast immer?) ein Typedef auf unsigned char .
    unsigned char wird von den Iostreams als Zeichen ausgegeben.
    Der OP will aber einen Typen der als Zahl ausgegeben wird.
    uint8_t ist also nicht der Typ den der OP will.



  • volkard schrieb:

    Sone schrieb:

    P.S.: Zu genau diesem Problem habe ich bereits vor ner kleinen Weile nen Thread geöffnet.

    Fein. Und was fehlt?

    Der Link.



  • ...



  • ...



  • Hier war der Code, den ich damals geschrieben habe (und überarbeitet, daher ist der im Thread "veraltet"), rausgekramt. Das ist Javas byte in C++ 🤡

    #include <istream>
    #include <ostream>
    #include <limits>
    
    template<bool signed_>
    struct base_byte
    {
    	typedef typename std::conditional<signed_, int8_t, uint8_t>::type underlying_type;
    
        base_byte(underlying_type t) noexcept:
    	value(t) {}
    
    	base_byte() = default;
    
    	operator underlying_type&() noexcept { return value; }
    	operator underlying_type() const noexcept { return value; }
    
    	underlying_type value;
    };
    
    template<bool si,
             typename CharT,
    	     typename Traits>
    std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, base_byte<si> const& b)
    {
        using namespace std;
    	typename basic_ostream<CharT, Traits>::sentry se(os);
    	if(se) try
        {
            ios_base::fmtflags baseflags = os.ios_base::flags() & os.ios_base::basefield;
            bool failed = use_facet<
                                    num_put<CharT,ostreambuf_iterator<CharT,Traits> >
                                   >(os.getloc()).put(os, os, os.fill(), os.basefield == ios_base::oct || os.basefield == ios_base::hex
            ? static_cast<long>(static_cast<uint8_t>(b.value))
            : static_cast<long>(b.value)).failed();
        }
        catch(...)
        {
            os.setstate( std::ios_base::badbit );
            if( os.exceptions() & ios_base::badbit )
                throw;
        }
    
    	return os;
    }
    
    template<bool si,
             typename CharT,
    	     typename Traits>
    std::basic_istream<CharT, Traits>& operator>>(std::basic_istream<CharT, Traits>& is, base_byte<si>& byte)
    {
        using namespace std;
    	typename basic_istream<CharT, Traits>::sentry se(is);
    	if(se) try
        {
            typedef num_get< CharT, istreambuf_iterator<CharT,Traits> > numget;
            ios_base::iostate err = ios_base::goodbit;
            long lval;
            use_facet< numget >(is.getloc()).get(is, 0, is, err, lval);
    
            using byte_t = typename base_byte<si>::underlying_type;
    
            if (lval < numeric_limits<byte_t>::min())
            {
                err |= ios_base::failbit;
                byte = numeric_limits<byte_t>::min();
            }
            else if (numeric_limits<byte_t>::max() < lval)
            {
                err |= ios_base::failbit;
                byte = numeric_limits<byte_t>::max();
            }
            else
                byte = static_cast<byte_t>(lval);
            is.setstate(err);
        }
        catch(...)
        {
            is.setstate( std::ios_base::badbit );
            if( is.exceptions() & ios_base::badbit )
                throw;
        }
    
    	return is;
    }
    
    using byte          = base_byte<true >;
    using signed_byte   = base_byte<true >;
    using unsigned_byte = base_byte<false>;
    


  • Swordfish schrieb:

    hustbaer schrieb:

    Swordfish schrieb:

    hustbaer schrieb:

    @@Swordfish
    s.o.

    Bitte etwas ausführlicher - stehe evtl. auf diversen Leitungen.

    uint8_t ist oft genug (fast immer?) ein Typedef auf unsigned char .
    unsigned char wird von den Iostreams als Zeichen ausgegeben.
    Der OP will aber einen Typen der als Zahl ausgegeben wird.
    uint8_t ist also nicht der Typ den der OP will.

    std::ostream & operator<<( std::ostream & os, std::uint8_t value )
    {
    	os << static_cast< unsigned >( value );
    	return os;
    }
    

    Well!?

    *schluck*

    Würde ich micht nicht trauen.
    Mittlerweile ist das schon SO lange so, dass ich mir gut vorstellen kann dass es JETZT massiv viel Code gibt der dadurch brechen würde.
    Und den Bug mag ich dann nicht suchen.

    Davon abgesehen finde ich es reichlich pervers. Der Grund dass das überhaupt funktioniert, ist, dass die char Stream-Insertion Operatoren der SCL Memberfunktionen sind. Wären sie freie Funktionen, wäre es ambiguous.
    (Daher wäre ich auch nie auf die Idee gekommen dass man das so machen konnte. Ich wusste nämlich ehrlich gesagt weder dass es Memberfunktionen sind, noch dass der Aufruf aus diesem Grund auf einmal nichtmehr ambiguous ist. Wobei ich letzteres nicht im Standard nachgeschlagen habe, ich vertraue da einfach mal auf das was gcc-4.7.2 von ideone.com macht.)


Anmelden zum Antworten