C++ wie kann man bei einem float die Nachkommastellen als Ganzzahl speichern?

8 Antworten

Vom Fragesteller als hilfreich ausgezeichnet

Bevor man mit dem Programmieren beginnt, müssen erst Fakten klar sein:

§1: Quelle der Daten:

a) Bruch wie 11111/109 ist nicht einfach eine Zahl mit 14 oder 15 Nachkommastellen, sondern unendlich viele mit einer Periode 108 Ziffern

101.93577981651376146788990825688073394495412844...

b) Quelle ist eine Variable vom Typ Double dann sollte man es auch als Double {Array} speichern. Später hat man dann alle Freiheiten des Abschneidens usw.

§2: was darf verloren gehen? Verlustbehaftete Komprimierung erlaubt?

(also interessieren Dich immer nur 15 Ziffern)

c) Was ist mit Vorkommastellen?

§3: Priorität: Geschwindigkeit oder Speicherplatz sowohl beim Speichern (Einpacken) als auch beim Laden (Auspacken) 

§4: soll es leicht verständlich & flexibel sein? Dann sind Strings ideal:

- leicht lesbar & leicht zu Debuggen

- leicht speicherbar

- mit jedem Editor anzeigbar

Aber langsam und verbraucht viel Speicher.

Beispiel:

Wenn man 0 Verluste haben will, hohe Komprimierung (besonders bei irrationalen Zahlen) und höchste Geschwindigkeit an beliebiger Stelle (auch ab Position 1 Mrd. dann x Stellen)...

nehme ich das vom Weltmeister der Pi-Berechnung verwendete Format ycd.

Das ist vorn ein Header (Info, was ab wann wie verschlüsselt ist; kann aber auch entfallen, wenn man nur immer das selbe Format verwendet) und dahinter ein Array aus 64 Bit uint. Falls Deine Quelle Brüche sind, kann z.B. immer Zähler und dann Nenner gespeichert werden.

In uint64 kann man ein Block aus 19 Ziffern sehr schnell speichern und später auch sehr schnell auspacken, ohne die Mio. Stellen davor beachten zu müssen (was bei reiner Umwandlung sehr großer Zahlen in das HEX-Format tun müsste).

Die Komprimierungsrate liegt bei irrationalen Zahlen wie Pi konst. bei etwa 42% {100% wäre eine reine txt mit den Ziffern} und ist damit immer besser als ZIP, RAR usw.

Für die über 22 TB an Daten ist dieses Format in jeglicher Hinsicht unschlagbar.

Nachteil: für Anfänger etwas schwer verständlich und der HEX-Code ist wie bei jedem komprimierten Datei für normale Editoren nichtssagend ("Brei von Bytes").

  Du brauchst eine Funktion, die die Zahl ( 17/19 ) in eine Stringvariable schreibt ( z.B. Code in Fortran ) Dann suchst du das Komma mittels der Indexfunktion, die bestimmt in sämtlichen Programmiersprachen existiert.

13

Ja hab das mittlerweile auch schon herausgefunden aber danke ^^ 

0

Ich würde für den Anwendungsfall wahrscheinlich nicht double oder float nehmen - die Datentypen bringen aufgrund der Art, wie sie Zahlen speichern, Ungenauigkeiten und Rundungsfehler mit sich. 

Stattdessen würde ich eine Library dafür installieren, z.B.

https://gmplib.org/

und die bringt sicherlich auch ihre eigene String-Funktion mit. Ich bin in C++ nicht so sattelfest, ich weiß nicht, ob GMP dafür die beste Wahl ist.

13

Naja. Ich versuche eigentlich sogut wie Möglich alle "fremde" Bibliotheken zu meiden. Irgendwie wurden diese schließlich auch gemacht -> heißt ich müsste das mit lernen auch selber machen können.

0
42
@katersaid11

Du kannst das auch selber machen. Das halte ich aber für unnötig aufwändig, wozu das Rad ständig neu erfinden? 

Die Art und Weise, wie Programmiersprachen Fließkommazahlen abspeichern, ist in diesem Standard abgespeichert. 

https://de.wikipedia.org/wiki/IEEE_754

Deswegen ergibt z.B. 0.1 + 0.2 in der Programmierung nicht 0.3, sondern 0.30000000000000004.

Du müsstest dir ein eigenes Zahlenformat (für den Anfang wahrscheinlich stringbasiert) überlegen und darauf all die Rechenregeln anwenden. Sprich: die vier Grundrechenarten schriftlich untereinander ausführen, so wie du es in der Grundschule gelernt hast. In deinem Fall müsstest du das hier

http://www.frustfrei-lernen.de/mathematik/rechnen-kommazahlen-addieren-subtrahieren-multiplizieren-dividieren-mathematik.html

in Code pressen. Ein guter Programmierer macht nicht alles selbst, sondern weiß auch, wann "selbst machen" aufwandsmäßig in keinem Verhältnis mehr steht. 

0
13
@ceevee

Ich hab schonmal einen String Taschenrechner mithilfe von int gemacht welches nur mit positiven und Ganzzahlen rechnen kann. Ich würde mich aber auch nicht als Programmierer bezeichnen von daher ist das schon ok ^^

0

Mehrere Variablen gleichzeitig in Java ausgeben?

Hi, ich möchte in Java mehrere Variablen gleichzeitig ausgeben, aber möchte jedoch nicht ständig das System.out.println wiederholen. Wenn ich folgende Variablen habe:
float a = 6.8f;

float b = 2.8976f;
double c = 1.987654329d;

int d = -7890;

float e = -0.00007f;

Dann kann ich ja nicht in das System.out.println a+b+c+d+e schreiben, da das sonst addiert wird. Wie würde man da vorgehen?

Danke euch :)

...zur Frage

Java befehl random macht nur die selbe zahl?

double b00= Math.random(); b00 = 25*+1; int a10 = (int) b00;

das spuckt immer 25 aus, woram liegt das? und was muss ich machen, damit das zahlen von 1 bis 25 ausspuckt!

...zur Frage

C-Programmierung Aufgabe

Hallo =) ich programmier gerade einen Zinseszinsrechner in C. Hierbei habe ich bisher folgendes Programm:

float CalcFloatInterest(float amount, float intInPercent, int days); double CalcDoubleInterest(double amount, double intInPercent, int days);

int main(void) { float amount = 0; float intInPercent = 0; int days = 0;

printf("Bitte Betrag eingeben: ") ; scanf("%f", &amount); printf("Bitte Zinssatz in %% eingeben: ") ; scanf("%f", &intInPercent); printf("Laufzeit in Tagen eingeben: ") ; scanf("%d", &days); printf("Die Zinsen mit float bei %d Tagen betragen: %.2f", days, CalcFloatInterest(amount, intInPercent, days) - amount); printf("\nDie Zinsen mit double bei %d Tagen betragen: %.2f", days, CalcDoubleInterest(amount, intInPercent, days) - amount);

return 0;

}

float CalcFloatInterest(float amount, float intInPercent, int days){

float interest = intInPercent / 100; int n;

for(n = 1; n <= days; n++){

amount = amount * ( 1+ (interest / 365));

    }

return amount;

}

double CalcDoubleInterest( double amount, double intInPercent, int days){

double interest = intInPercent / 100; int n;

for(n = 1; n <= days; n++){

amount = amount * ( 1+ (interest / 365));

    }

return amount;

}

Nun ist die nächte AUfgabe folgende:

Implementieren Sie die Funktion CalcSpan(). Sie berechnet die Laufzeit eines Darlehens, bei gegebenem Zinssatz,Betrag und monatlicher Rate.

Als Vereinfachung gehen wir davon aus, dass Monate genau 30 Tage lang sind: alle 30 Tage wird die Rate vom Darlehen

abgezogen. Die erste Rate wird dabei sofort zu Beginn fällig. Für die Zinseszins-Berechnung gilt das gleiche wie bei Teilaufgabe 1: der Zins wird täglich bezogen auf den aktuellen Betrag berechnet. Geben Sie die Zeitspanne inTagen zurück. Das Darlehen gilt als abbezahlt, wenn der Betrag mit der monatlichen Rate Null oder negativ wird. Begrenzen Sie Ihre Funktion auf eine maximale Laufzeit von 10 Jahren, d.h. benötigt ein Darlehen mehr als

3650 Tage zum Zurückzahlen, dann bricht die Funktion ab und gibt -1 zurück.

Verwenden Sie folgenden Prototypen:

int CalcSpan(double amount,double intInPercent,double monthlyRate);

Fügen Sie am Ende Ihre

r main()-Funktion eine Eingabeaufforderung mitscanf() ein, um die monatliche Rate einzulesen.Geben Sie im Anschluss die mit CalcSpan() berechnete Laufzeit in Jahren und Tagen, z.B. 8 Jahre, 20 Tage, aus. Übersetzen und Testen Sie Ihr Programm. Geben Sie das funktionstüchtige Programm ab. Die Ausgabe könnte nun wie folgt aussehen:

Bitte Betrag eingeben:1000 Bitte Zinssatz in % eingeben: 5.41 Laufzeit in Tagen eingeben: 365 Die Zinsen mit float bei 365 Tagen betragen: 55.59 Die Zinsen mit double bei 365 Tagen betragen: 55.59 Bitte die monatliche Rate eingeben:247 Die Laufzeit beträgt: 0

Hierzu fehlt mir leider jeglicher Ansatz :/ Kann vllt jemand helfen?

...zur Frage

C++ Funktion zur Berechnung der Dauer in Sekunden?

Hallo liebe Community,

und zwar sollte ich ein Programm schreiben, dass den Benutzer nach einer Zahl in Sekunden abfragt und dann mit dem abgefragten Wert die Stunden und Minuten ausrechnet und wieder ausgibt.

Bisheriger Code:

#include <iostream> 
#include <string>
    
using namespace std;
    
    double dauerInSekunden(double stunden) {
        double ergStunden;
    
        ergStunden = stunden / 3600;
    
        return ergStunden;
    }
    
    double dauerInSekunden2(double minuten) {
        double ergMinuten;
    
        ergMinuten = minuten / 60;
    
        return ergMinuten;
    }
    
    
    
    int main() {
        string Dauer;
        double Zahl;
        cout  << "Geben Sie das Format in Zahl (Sekunden) und die Einheit in die sie umrechnen \t wollen 'Stunden', 'Minuten', 'Sekunden' an!" << endl;
        cin >> Zahl;
        cin >> Dauer;
    
        if (Dauer == "Stunden") {
            cout << dauerInSekunden(Zahl) << " Stunden" << endl;
            }
        else if (Dauer == "Minuten") {
            cout << dauerInSekunden2(Zahl) << " Minuten" << endl;
            }
        else
            cout << Zahl << " Sekunden" << endl;
    
        system("pause");
    }

Meine Frage ist nun folgende ist es möglich die Funktionen auch so um zu schreiben, dass sie nur aus einer Funktion besteht und der Benutzer immer noch angeben kann in was für ein Format er umrechnen möchte?

...zur Frage

Was ist die normale Geschwindigkeit bei einem Minecraft Spieler?

Hi, ich wollte Fragen da ich ein Minecraft Plugin programmiere, wie ist die normale float zahl oder int von der geschwindigkeit eines Spielers? Was ich herausgefunden habe ist das 1 ziemlich schnell ist, da her muss es eine float zahl sein.

MfG Bleikind

...zur Frage

Java double ohne Nachkommastelle

Hallo zusammen!

Ich habe eine kurze Frage! Wenn ich in meinem Rechenprogramm einen Double habe und der eine Nachkommastelle von 0 hat ( z.b 3.0 ), soll nur die Zahl 3 angezeigt werden, da die null hinter dem Komma für anschauliche Zwecke sinnlos ist. Beim fall 3.0213, also wenn nach der 0 noch zahlen folgen, soll natürlich der ganze double angezeigt werden. Wie kann ich das in Java realisieren?

...zur Frage

Was möchtest Du wissen?