Frage

Was ist der einfachste Weg, um eine C ++ float Variable gestutzt, der einen Wert von 0,6000002 auf einen Wert von 0,6000 hat und speichern Sie es zurück in die Variable?

War es hilfreich?

Lösung

Zunächst ist es wichtig zu wissen, dass Gleitkommazahlen angenähert werden. Siehe den von @ Greg Hewgill angegebenen Link zu verstehen, warum dieses Problem nicht vollständig auflösbar ist.

Aber hier sind ein paar Lösungen für das Problem, die Ihren Bedarf wahrscheinlich treffen werden:

Wahrscheinlich die bessere Methode ist aber weniger effizient:

char sz[64];
double lf = 0.600000002;
sprintf(sz, "%.4lf\n", lf); //sz contains 0.6000

double lf2 = atof(sz);

//lf == 0.600000002;
//lf2 == 0.6000

printf("%.4lf", lf2); //print 0.6000

Die effizientere Art und Weise, aber wahrscheinlich weniger genau:

double lf = 0.600000002;
int iSigned = lf > 0? 1: -1;
unsigned int uiTemp = (lf*pow(10, 4)) * iSigned; //Note I'm using unsigned int so that I can increase the precision of the truncate
lf = (((double)uiTemp)/pow(10,4) * iSigned);

Andere Tipps

Ich denke, die Frage, die hier gestellt werden soll ist: Warum brauchen Sie es abgeschnitten?

Wenn sein für einen Vergleich zwischen den Werten, sollten Sie vielleicht mit dem Epsilon-Test prüfen. (Mit einem zusätzlichen Toleranzwert, in Ihrem Fall, da es viel größer ist als das allgemein akzeptierte epsilon zu sein scheint).

Wenn Sie wollen es einfach als 0,6000 auszudrucken, verwenden Sie die Methoden andere vorgeschlagen haben.

roundf(myfloat * powf(10, numDigits)) / powf(10, numDigits);

Zum Beispiel, in Ihrem Fall Sie Kürzen drei Ziffern (numDigits). Sie würden verwenden:

roundf(0.6000002 * 1000) / 1000
// And thus:
roundf(600.0002) / 1000
600 / 1000
0.6

(Sie würde wahrscheinlich das Ergebnis von powf speichern irgendwo, da Sie es zweimal verwenden.)

Aufgrund wie Schwimmer sind normalerweise auf Computern gespeichert, würde es wahrscheinlich Ungenauigkeiten sein. Das ist, was Sie für die Verwendung von Schwimmern bekommen, though.

verwenden:

floor(0.6000002*10000)/10000

Für C 11 ++ Sie std::round definiert in Header <cmath> verwenden können:

auto trunc_value = std::round(value_to_trunc * 10000) / 10000;

Hier ist eine Funktion, die Beratung in anderen Antworten und ein Beispiel für die Verwendung mit:

#include <iostream>
#include <cmath>

static void Truncate(double& d, unsigned int numberOfDecimalsToKeep);

int main(int, char*[])
{

  double a = 1.23456789;
  unsigned int numDigits = 3;

  std::cout << a << std::endl;

  Truncate(a,3);

  std::cout << a << std::endl;

  return 0;
}

void Truncate(double& d, unsigned int numberOfDecimalsToKeep)
{
    d = roundf(d * powf(10, numberOfDecimalsToKeep)) / powf(10, numberOfDecimalsToKeep);
}

Ähnlich wie bei anderen Antworten, aber Sie müssen diese Runde nicht vergessen, Boden und trunc definitionsgemäß unterschiedlich sind. Siehe die Definition und Ausgabebeispiel der folgenden Optionen:

http://www.cplusplus.com/reference/cmath/trunc/

In diesem Fall müssen wir mit einer Genauigkeit von 4 Dezimalstellen trucate und loszuwerden nicht-signifikanter Dezimalstellen:

trunc(valueToTrunc*10000)/10000

oder

value = (double)((int)(valueToTrunc*10000))/(double)10000
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top