Zum Inhalt springen

Problem mit der Ungenauigkeit von float


Tredory

Empfohlene Beiträge

Hallo, erstmal vorweg, ich bin nun im zweiten Semester meines Maschinenbau Studiums angekommen, und dort beginnen wir gerade mit der Programmierung in ANSI-C.

Vorkenntnisse im Programmieren habe ich schon einige wenige (Angefangen mit VB .NET 2005, und dannach immer mal wieder kleine Tools zum Umrechnen mit z.b. Java und C# geschrieben. Ausserdem einige Programme für microkontroller mit Bascom (Basic) entwickelt)

Nunja nun habe ich allerdings auch schon längere Zeit nichts mehr damit gemacht, allerdings bin ich mir ziemlich sicher das ich bisher folgendes Problem noch nicht hatte.

Also eine der ersten Aufgaben war nun ein Programm zu erstellen, das DM in Euro umrechnet, und das für alle Werte von 0.10DM - 20 DM in 0.10 DM Schritten.

Eigentlich hab ich gedacht, hah kinderkram und das Programm eben fix hingeschrieben.

Programm:

#include  <stdio.h>

main()

{

	double lower,  upper,  step;

	double  DM,  EUR;

	lower  =  0.10f; /*  untere  Grenze  der  Temperaturtabelle  */

	upper  =  20.00f;       /*  obere  Grenze  */

	step  =  0.10f; /*  Schrittweite  */

	DM  =  lower;

	printf("\n\nDM	EURO\n\n");

	while  (DM  <=  upper)  {

	EUR  =  (DM/1.95583f);

	printf("%6.2f DM   |   %6.2f EUR\n",DM ,EUR);

	DM  =  DM  +  step;

	printf("%30.20f\n",DM);

	}

	printf("\n");

	getch();

}

Nunja nur macht mir da nun der ungenaue float einen Strich durch die Rechnung. Die zusätzliche ausgabe nach dem aufaddieren der DM habe ich nachträglich eingebaut, und bin dadurch darauf gekommen das einige stellen hinter dem Komma deutliche Rundungsfehler auftauchen. Erst konnte ich mir darauf keinen Reim machen warum bei derart einfachen Addition dahinten Rundungsfehler auftauchen. Nun weiß ich mittlerweile das es dran liegt, dass sich die Nachkommastellen nicht in 1/Zweierpotenzen zerlegen lassen, und dadurch das ganze auf dichtesten Wert gerundet wird der eben so darstellbar ist. ich könnte natürlich nun auch einfach eine int Zähler variable benutzen für die while schleife, aber ich finde das das ein wenig naja sinnloser Aufwand für einen so einfachen vergleich wäre. Ist es möglich bei der Auswertung des Argumentes der While schleife einfach alle Nachkommastellen ab der 4ten stelle oder so abzuschneiden, das zuguter letzt der vergleich DM <= upper doch noch hinhaut. Hier mal die (gekürzte) Ausgabe des Programmes:
DM      EURO


  0.10 DM   |     0.05 EUR

        0.20000000298023224000

  0.20 DM   |     0.10 EUR

        0.30000000447034836000

  0.30 DM   |     0.15 EUR

        0.40000000596046448000

  0.40 DM   |     0.20 EUR

        0.50000000745058060000

......

......

......

......

 19.60 DM   |    10.02 EUR

       19.70000029355287600000

 19.70 DM   |    10.07 EUR

       19.80000029504299200000

 19.80 DM   |    10.12 EUR

       19.90000029653310800000

 19.90 DM   |    10.17 EUR

       20.00000029802322400000

Und da ist klar 20.000000298... ist nunmal nichtmehr == 20.00 sondern größer, wie bekomme ich es hin das mit dem direkten vergleich trotzdem direkt zum Ziel komme ?

Hoffe ihr könnt mir da etwas weiterhelfen.... ;)

Ab jetzt OffTopic:

Warum wird man hier bei der Registrierung im Forum mit einem google mail Konto dermaßen diskriminiert ? Ich hab ja nichts gegen die meinung der Leute die aus Datenschutzgründen ein Problem mit google haben, allerdings teilen nicht alle diese meinung.Ich finde das sollte wirklich jeder selber entscheiden ob er seine Daten Google in die Hand drücken will oder nicht. Nun musste ich mein altes verstaubtes Live Konto wieder ausgraben nur um mich hier Registrieren zu können. Ist zwar nicht so das Problem aber verstehen kann ich diese "abweisung" wirklich nicht .....

EDIT:

Ok, das Thema hat sich geklärt ich habe den Thread zu dem Thema gefunden. Rückläufige Mails sind der Hauptgrund, den ich zwar nicht nachvollziehen kann, da man die normal ja über Regeln ausfiltern könnte, aber naja ok, seis so. Und nein ich habe auch kein Problem damit das meine E-Mails anonym nach Themengebieten gescannt werden um Werbeanzeigen gezielter auszurichten. Würde es solches oder ähnliches vorgehen nicht geben bezweifel ich mal stark das Diese internetwerbung so stark vertreten wäre. Und ich persönlich habe damit kein problem wo sich doch fiele open source und freeware projekte zum teil durch eben sowas finanzieren. Und ich find Freeware nicht schlecht..

Aber darüber will ich hier KEINE Diskussion lostreten.

mfg

Jens

Bearbeitet von Tredory
Link zu diesem Kommentar
Auf anderen Seiten teilen

Faustregel: Vergleiche Fließkommatypen niemals auf Gleicheit.

  • Benutz eine Epsilon-Umgebung
  • Wähle upper so, dass es zwischen zwei Schritten liegt, nicht genau auf der rechnerischen Grenze
  • Ermittle DM statt durch wiederholtes Addieren (was den Fehler vergrößert) aus lower + n * step
  • Rechne in Pfennig bzw. Cent, und wandle nur für die Ausgabe in DM / Euro um, dann kannst du Ganzzahltypen verwenden.

Rückläufige Mails sind der Hauptgrund, den ich zwar nicht nachvollziehen kann, da man die normal ja über Regeln ausfiltern könnte
Die automatisierten Bestätigungsmails, die die Boardsoftware bei der Anmeldung verschickt, kommen bei Google Mail sehr oft fälschlicherweise als unzustellbar zurück, was einfach unnötig viel Supportarbeit verursacht. Wo sollen da Filterregeln helfen?
Link zu diesem Kommentar
Auf anderen Seiten teilen

Hoffe ihr könnt mir da etwas weiterhelfen.... ;)

Erstmal etwas, dass Dir vermutlich noch gar nicht aufgefallen ist: Du verwendest als Datentyp für Variablen zwar double, initialisierst diese aber mit float Werten, die eine geringene Genauigkeit haben. Du kannst die Genauigkeit schon mal deuitlich erhöhen, wenn Du das verbesserst.

Als nächstes kannst den Fehler senken, indem Du nicht ständig addierst.

Das Problem mit dem Vergleich ist ganz normal für Fließkommazahlen und man muss dies akzeptieren. Du kannst das Problem aber dadurch beheben, indem Du mit Integerzahlen arbeitest, was für Rechnungen mit Geldbeträgen ohnehin günstiger ist.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo, danke für die Antworten,

ich habe es nun gerade bereits auf Integer geändert. Damit klappts dann nun auch.

#include  <stdio.h>

#include <stdlib.h>



main()  //Die Main Funktion (Das Hauptprogrmm)

{

	int lower,  upper,  step, zahler; //Die Ganzzahligen Variablen für den Schleifenablauf.

	double  DOLLAR,  EURO; //Die Fließkomma Variablen für die Berechnung.



	lower  =  0; //Der Startwert der Umrechnungen in Cent

	upper  =  1000; //Die obere Grenze der Berechnungen in Cent

	step  =  25; //Die Schrittweite in Cent

	zahler = lower; //Zaehlervariable Initialisieren.


	EURO = 0;

	DOLLAR = 0;

	system("cls"); //Bildschirm löschen

	printf("\n	||EURO			||DOLLAR\n"); //Überschrift ausgeben


		while  (zahler  <=  upper)   //While Schleife für die berechnung.

		{

			EURO  =  zahler/100.0f; //Der EURO Variablen den aktuellen zahler Wert zuweisen.

			DOLLAR  =  (EURO*1.38176f); //Die Berechnung des Dollar Wertes.

			printf("	|| %13.2f Euro   ||   %13.2f Dollar ||\n",EURO ,DOLLAR); //Ausgabe des Ergebnisses. 

			zahler  =  zahler  +  step; //Den Zaehler aufaddieren.

		}


	printf("\n");

	getch();

}

Das es bei den emails um die registrierungsmails geht hab ich nicht dran gedacht ich dachte eher an mails unter mitgliedern. So ist das dann natürlich nachvollziehbar.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Nein, das hast Du nicht konsequent getan. Du rechnest noch immer mit double und die Konstanten sind immer noch floats.

Oh klar da hast du natürlich Recht,

ich meinte auch eher das ich den vergleich für die While schleife nun über Integer hab laufen lassen, die Berechnung selbst hatte ich da nicht weiter beachtet. Werde das auch noch ändern.

Link zu diesem Kommentar
Auf anderen Seiten teilen

@TE ist zwar nichts technisches, aber gewöhn dir bitte gar nicht erst an deine Variablennamen groß zu schreiben. EURO oder DOLLAR hab ich bei schnellem überfliegen für defines gehalten und mich gewundert, was zum Geier du zu tun versuchst.

Die while Schleife würde ich übrigens durch ne for ersetzen:

Beide kopfgesteuert, abhängigkeit von einer einzelnen Zählvariable, identischer "step" - for bietet sich hier einfach an.

So long.

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 1 Monat später...

Hi Leutz,

warum alles so kompliziert?

Es ist doch unnötiger Speicherverbrauch, extra für die Umwandlung, Variablen anzulegen.

Für Vergleiche ginge doch auch Typecasting.

Grundsätzlich ist es sowieso nicht ratsam, bei Cent-Beträgen, also Nachkommastellen, weiterhin mit dem ungenauen und von System zu System, sowie CPU zu CPU, mit FLOAT, DOUBLE, LONG DOUBLE zu rechnen, zumal dadurch nur unnötig die FPU der CPU angeworfen wird. Mit Ganzzahligen Datentypen lässt sich meines Wissens her, wesentlich einfacher und genauer rechnen.

Nunja, is ja jetzt auch wurscht. Hatte selber mal diese Problematik. Ich habs dann einfach damit gelöst, dass ich mir selber eine Routine zur korrekten Rundung geschrieben hab. Funktioniert mitlerweile mit fast jeder CPU und jedem OS.

Hier mal ne frühe Version meiner geschriebenen Routine:


// (c) 2009 - Copyright by Kevin Erler

//---------------------------------------------------------------------------

#include <vcl.h>

#include <stdlib>

#include <iostream>

#include <stdio>

#include <math>

#include <float>

#include <limits>

#include <iomanip>

#include <String>

#include <sstream>


using namespace std;


#pragma hdrstop


//---------------------------------------------------------------------------


long double LDBL_ROUNDUP(long double ld_RoundValue,int i_DecimalPlaces = 2)

{

  int i_IF_ROUNDVALUE_NULL = 0, i_ROUNDVALUE_IS_NEGATIVE = 0;


  if(ld_RoundValue < 0.000000000000000000)

  {

    i_ROUNDVALUE_IS_NEGATIVE = 1;

    ld_RoundValue*=(-1);

  }


  if(ld_RoundValue > LDBL_MAX)

  {

    ld_RoundValue = LDBL_MAX;

  }

  else

  {

    if(ld_RoundValue < LDBL_MIN)

    {

      ld_RoundValue = LDBL_MIN;

    }

    else  // ld_RoundValue >= LDBL_MIN || ld_RoundValue <= LDBL_MAX

    {

      if((ld_RoundValue == 0.0) ||

         (ld_RoundValue == 0.00) ||

         (ld_RoundValue == 0.000) ||

         (ld_RoundValue == 0.0000) ||

         (ld_RoundValue == 0.00000) ||

         (ld_RoundValue == 0.000000) ||

         (ld_RoundValue == 0.0000000) ||

         (ld_RoundValue == 0.00000000) ||

         (ld_RoundValue == 0.000000000) ||

         (ld_RoundValue == 0.0000000000) ||

         (ld_RoundValue == 0.00000000000) ||

         (ld_RoundValue == 0.000000000000) ||

         (ld_RoundValue == 0.0000000000000) ||

         (ld_RoundValue == 0.00000000000000) ||

         (ld_RoundValue == 0.000000000000000) ||

         (ld_RoundValue == 0.0000000000000000) ||

         (ld_RoundValue == 0.00000000000000000) ||

         (ld_RoundValue == 0.000000000000000000) )

      {

        i_IF_ROUNDVALUE_NULL = 1;

      }

    }

  }


  if(i_DecimalPlaces > LDBL_DIG)

  {

    i_DecimalPlaces = LDBL_DIG;

  }

  else

  {

  }


  if(i_IF_ROUNDVALUE_NULL == 0)

  {

    String s_ACCURACYNUMBER= "0.";

    for(int i = 0;i < LDBL_DIG;i++)

    {

      s_ACCURACYNUMBER+="5";

    }

    // s_ACCURACYNUMBER (String) in ld_ACCURACYNUMBER (long double) konvertieren (C++-spezifisch)

    stringstream sstr;

    long double ld_ACCURACYNUMBER = 0;

    sstr<<s_ACCURACYNUMBER.c_str();

    sstr>>ld_ACCURACYNUMBER;


    /*// s_ACCURACYNUMBER (String) in ld_ACCURACYNUMBER (long double) konvertieren (C-spezifisch)

    //char *endptr;

    //ld_ACCURACYNUMBER = _strtold(s_ACCURACYNUMBER.c_str(),&endptr);

    cout.precision(LDBL_DIG);

    cout << ld_ACCURACYNUMBER << endl;

    */


    long double ld_MULTIPLIKATOR_DIVISOR = 0.000000000000000000;

    switch(i_DecimalPlaces)

    {

      case 0:

        ld_MULTIPLIKATOR_DIVISOR = 1.000000000000000000;

        break;

      case 1:

        ld_MULTIPLIKATOR_DIVISOR = 10.0;

        break;

      case 2:

        ld_MULTIPLIKATOR_DIVISOR = 100.0;

        break;

      case 3:

        ld_MULTIPLIKATOR_DIVISOR = 1000.0;

        break;

      case 4:

        ld_MULTIPLIKATOR_DIVISOR = 10000.0;

        break;

      case 5:

        ld_MULTIPLIKATOR_DIVISOR = 100000.0;

        break;

      case 6:

        ld_MULTIPLIKATOR_DIVISOR = 1000000.0;

        break;

      case 7:

        ld_MULTIPLIKATOR_DIVISOR = 10000000.0;

        break;

      case 8:

        ld_MULTIPLIKATOR_DIVISOR = 100000000.0;

        break;

      case 9:

        ld_MULTIPLIKATOR_DIVISOR = 1000000000.0;

        break;

      case 10:

        ld_MULTIPLIKATOR_DIVISOR = 10000000000.0;

        break;

      case 11:

        ld_MULTIPLIKATOR_DIVISOR = 100000000000.0;

        break;

      case 12:

        ld_MULTIPLIKATOR_DIVISOR = 1000000000000.0;

        break;

      case 13:

        ld_MULTIPLIKATOR_DIVISOR = 10000000000000.0;

        break;

      case 14:

        ld_MULTIPLIKATOR_DIVISOR = 100000000000000.0;

        break;

      case 15:

        ld_MULTIPLIKATOR_DIVISOR = 1000000000000000.0;

        break;

      case 16:

        ld_MULTIPLIKATOR_DIVISOR = 10000000000000000.0;

        break;

      case 17:

        ld_MULTIPLIKATOR_DIVISOR = 100000000000000000.0;

        break;

      case 18:

        ld_MULTIPLIKATOR_DIVISOR = 1000000000000000000.0;

        break;

    }


    if(i_ROUNDVALUE_IS_NEGATIVE == 1)

    {

      ld_RoundValue = (long int)((ld_RoundValue*ld_MULTIPLIKATOR_DIVISOR)+ld_ACCURACYNUMBER)/(-ld_MULTIPLIKATOR_DIVISOR);

    }

    else

    {

      ld_RoundValue = (long int)((ld_RoundValue*ld_MULTIPLIKATOR_DIVISOR)+ld_ACCURACYNUMBER)/ld_MULTIPLIKATOR_DIVISOR;

    }

  }

  else

  {

    if(i_IF_ROUNDVALUE_NULL == 1)

    {

      String s_RoundValue = "0";

      // s_RoundValue (String) in ld_RoundValue (long double) konvertieren (C++-spezifisch)

      stringstream sstr;

      sstr<<s_RoundValue.c_str();

      sstr>>ld_RoundValue;

    }

    else

    {

    }

  }


  cout.precision(LDBL_DIG);

  return ld_RoundValue;

}


#pragma argsused

int main(int argc, char* argv[])

{

  cout << LDBL_ROUNDUP((-8.546),2) << "\n\n";


  //cout.precision(LDBL_DIG);

  cout << "Genauigkeit in Dezimalziffern (long double): " << LDBL_DIG << "\n\n";

  cout << "maximaler Gleitpunktwert (long double): " << LDBL_MAX << "\n\n";

  cout << "Minimaler normalisierter Gleitpunktwert (long double): " << LDBL_MIN << "\n\n";


  getchar();

  return 0;

}

//---------------------------------------------------------------------------

Bitte nicht lachen. Schmunzel selbst noch drüber.

Aber für all jene die es wissen wollen bzw. noch nicht wissen.

Das Problem der Rundungsfehler ist häufig der jeweiligen Std-Bibliothek zu verschulden.

Es gibt bspw. festgelegte Grenzwerte, was die Genauigkeiten und Nachkommestellen, sowie Rundungsverhalten anbelangen.

Von System zu System, also OS, können diese Dinge sich signifikant unterscheiden.

Ebenso ist häufiger Störfaktor die CPU, da diese unabhängig von der Software, teilweise unterschiedliche Rundungsfehler und sogar Berechnungsfehler ab bestimmten Nachkommatstellen aufweisen. Zum Glück gibts in einigen Std-Bilbiotheken, Variablen, die die notwenigen Information enthalten. Will man da eine möglichst genaue Rundung realisieren, die auf jedem System funktioniert, muss man die erforderlichen Informationen auslesen und bei der weiteren Verarbeitung mit einbeziehen. So in etwa, funktioniert zumindest meine geschriebene Routine. Aber wie gesagt, an der geposteten gibts noch einiges zu verbessern. Ist schließlich noch eine sehr frühe ALPHA-Version gewesen.

Für solche einfachen Dinge, wie Geld-Beträge, würde aber die Grundformel zur Rundung und die Anwendung von Typecasting bei Vergleichen, mehr als ausreichen.

Wer gerne trotzdem mit gebrochenen Zahlen rechnen möchte, kann sich ja auch eine Klasse für Brüche mit Operatorüberladung schreiben.

Eine Frage hab ich allerdings noch:

1.38176f

Was ist das für eine Schreibweise? Kenn ich noch garnicht. Ich meine die Angabe mit dem Buchstaben, hier "f" am Ende der Zahl. Ich meine, um eine Binär, Oktal oder Hexadezimalzahl als solche zu kennzeichnen, seh ich ja noch ein, aber sollte ein Kompiler nicht von selbst erkennen, um was für eine Art Zahl es sich handelt?

Allein durch Kommastellen, handelt es sich doch um eine Fließkommazahl. Das müsste eigentlich auch jeder wissen, drumm verwundert mich ja diese Schreibweise. Oder gehört das mitlerweile zum guten Ton in der Programmierung?

Grüße

Schlitzauge :-)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hm, hab schon Kompiler gehabt, Borland C++Builder und VS2010 (ich weiß, sind IDE´s), da ist es schon so.

Insb. bei Vergleichen scheint ein aktueller Kompiler eine 10 und 10.0 zu differenzieren.

Ich kenne zumindest die obige Notationsform, wie 10.551779f nicht, sondern nur 10.551779, weil aufgrund dessen, was ich gelernt habe.

Deshalb frage ich ja nochmal nach, ob das jetzt die neue Notationsempfehl ist bzw. schon immer war oder das "f" gänzlich überflüssig ist.

Aber eigentlich muss ein Kompiler das schon wissen, oder wie will er sonst den Wert 10.551779 als solches übersetzen, wenn er es sonst nicht wüsste.

Grüße

Schlitzauge :-)

Link zu diesem Kommentar
Auf anderen Seiten teilen

@Schlitzauge nur interesse halber: Sicher das dein Code funktioniert? Imho landest du da wunderbar im Nirvana, ein Überlauf von long double über LDBL_MAX dürfte bei LDBL_MIN landen und damit völlig valide sein. Überläufe kannst du hier nicht abfangen, dies müsste früher geschehen (eingabe?) - Hatte aber keine lust das ding zu compilieren oder zu googlen.

Und für den fall, dass eben genau diese Prüfungen nichts bringen, hätte es ein "(long double)var" ebenso getan.

Die genauigkeit lässt sich btw. deutlich eleganter in pow(10, iDecimals) ausdrücken und zu guter letzt 0.0 == 0.00000000 == 0.

Also die Prüfung geht nach hinten los und der rest ist trivial.

Was die Typen angeht, wenn ich sie noch richtig im Kopf hab: (f)loat, (L)ong double für Gleitpunktzahlen (l)ong, (u)nsigned und (u)nsigned (l)ong also (ul) für Ganze Zahlen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ja, wie gesagt, ditt is nur ne sehr frühe Alpha-Version von 2009.

An pow() hab ich auch schon gedacht. Das Problem sind aber häufig die CPU´s. Während die eine CPU den logisch gedacht richtigen Wert in seinen Registern hat, kann das bei ner anderen CPU wieder ganz anders ausschauen. Die ersten Dezimalstellen hinterm Komma, schaffen alle gleich gut. Sobald wir aber weiter nach rechts rücken, kommt es von CPU zu CPU zu teils gravierenden Ungenauigkeiten. D.h. man muss deshalb jegliche Situationen abfangen, wenn unter jedem System und jeder CPU korrekt gerechnet werden soll. Ich sage ja nicht, dass der Code perfekt ist. ALPHA-Version sagt, denke ich schon ne ganze Menge aus. Der Code ist mitlerweile komplett umgeschrieben und wesentlich komplexer. CPU´s und Std-Libs, können schon ärgerlich sein. Jeder kocht sein eigenes Süppchen. Da ist es nicht gerade leicht, ein einheitlich und übergreifendes Framework / Lib zu schreiben, welche(s) auch überall gleich funktioniert.

Grundsätzlich neige mitlerweile dazu, alles mit ganzen Zahlen umzusetzen. Rechnet sich eh schneller und eleganter. Nur bei der Konvertierung und Ausgabe, muss man dann noch aufpassen, ist aber halb so wild.

Damals war ich noch nicht so weit, long double-Überläufe abzufangen, drum hab ichs so gemacht. Verzeiht mir bitte! ;)

Der obige Code funktioniert trotzdem. Lässt sich auch übersetzen. Er soll aber nicht als produktiv betrachtet werden, sondern vielmehr zeigen, in welche Richtung es gehen sollte. Ich zwinge ja auch keinen dazu, diese Grütze ;) durchn Kompiler zu jagen. Wer es trotzdem machen möchte, muss aber noch ein bissl Hand anlegen, ist nämlich an einigen Stellen, Borland-spezifisch, z.B. vcl.h oder String.

Alles andere ist sonst in jeder guten Std-Lib vertreten und ANSI-C.

pow(10, iDecimals) ausdrücken und zu guter letzt 0.0 == 0.00000000 == 0

Aus Interesse, kannste das mal weiter erläutern? Steh gerade irgendwie aufn Schlauch.

Grüße

Schlitzauge :) :) :) :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

@Schlitzauge: Was willst Du damit eigentlich bezwecken? Es gibt für Gleitkommadaten eine Norm IEEE 754

Runden kann man in C++ mit ceil - C++ Reference und floor - C++ Reference (zusätzlich kann man auch noch fmod - C++ Reference und modf - C++ Reference

verwenden), Zusätzlich gibt es für Gleitkommadaten limits - C++ Reference womit man eben korrekt die Epsilonumgebung prüfen / erzeugen kann (siehe dazu numeric_limits - C++ Reference )

Eine Umwandlung von einem String in einen Gleitkommadatentyp lässt sich z.B. mit lexical_cast - Boost 1.46.1 oder mit stringstream - C++ Reference realisieren

Dein ganzer Code bezüglich des Rundens kann ich mit den Standardfunktionen weitgehend korrekt abbilden

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...