<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Subtraktion mit Double (falsches Resultat)]]></title><description><![CDATA[<p>Hallo Zusammen.</p>
<p>Ich habe folgendes Problem.<br />
Ich habe 3 Variabeln vom Typ &quot;double&quot;;</p>
<p>Die Variabeln werden mit folgenden Werten gefüllt;</p>
<pre><code class="language-cpp">double dDateVal1;
double dDateVal2;
double dCurrentVal;

dDateVal1=39923.861817;
dDateVal2=39923.86174;

//Hier kommt ==&gt; 6.6678246842E-05
//statt ==&gt; 0.000077
dCurrentVal = dDateVal1 - dDateVal2;
</code></pre>
<p>Was mache ich hier falsch?<br />
Eigentlich sollte diese Anzahl an Kommastellen ja kein Problem darstellen oder sehe ich das falsch.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/239218/subtraktion-mit-double-falsches-resultat</link><generator>RSS for Node</generator><lastBuildDate>Tue, 22 Sep 2026 13:01:46 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/239218.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 20 Apr 2009 18:52:18 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Subtraktion mit Double (falsches Resultat) on Mon, 20 Apr 2009 18:52:18 GMT]]></title><description><![CDATA[<p>Hallo Zusammen.</p>
<p>Ich habe folgendes Problem.<br />
Ich habe 3 Variabeln vom Typ &quot;double&quot;;</p>
<p>Die Variabeln werden mit folgenden Werten gefüllt;</p>
<pre><code class="language-cpp">double dDateVal1;
double dDateVal2;
double dCurrentVal;

dDateVal1=39923.861817;
dDateVal2=39923.86174;

//Hier kommt ==&gt; 6.6678246842E-05
//statt ==&gt; 0.000077
dCurrentVal = dDateVal1 - dDateVal2;
</code></pre>
<p>Was mache ich hier falsch?<br />
Eigentlich sollte diese Anzahl an Kommastellen ja kein Problem darstellen oder sehe ich das falsch.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1698833</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1698833</guid><dc:creator><![CDATA[Deforation]]></dc:creator><pubDate>Mon, 20 Apr 2009 18:52:18 GMT</pubDate></item><item><title><![CDATA[Reply to Subtraktion mit Double (falsches Resultat) on Mon, 20 Apr 2009 18:57:46 GMT]]></title><description><![CDATA[<p>Google mal nach &quot;Fließkomma Genauigkeit&quot; und informier dich über die binäre Darstellung von Fließkommazahlen, dann verstehst du warum <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /><br />
1/3 kann man im 10er System mit endlicher Genauigkeit darstellen: 0.333333<br />
3* (1/3) ist eigentlich 1, aber im 10er-System mit 6 Stellen Genauigkeit ist das 3 * 0.333333 = 0.999999 und nicht 1 <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1698835</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1698835</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Mon, 20 Apr 2009 18:57:46 GMT</pubDate></item><item><title><![CDATA[Reply to Subtraktion mit Double (falsches Resultat) on Mon, 20 Apr 2009 21:36:17 GMT]]></title><description><![CDATA[<p>Wenn eine so hohe Genauigkeit wichtig für deine Anwendung ist wäre eine Möglichkeit z.B. erstmal mit __int64 (oder größer falls deine Platform das kann) zu rechnen und erst am Ende in ein double zurückzurechnen.</p>
<p>In deinem Beispiel sowas:</p>
<pre><code class="language-cpp">__int64 iDateVal1;
__int64 iDateVal2;
__int64 iCurrentVal;

iDateVal1 = 39923861817; // 39923.861817 * 1.000.000
iDateVal2 = 39923861740; // 39923.86174  * 1.000.000

iCurrentVal = iDateVal1 - iDateVal2;

doulbe dCurrentVal = iCurrentVal / 1000000.0; //spätestens hier ist Schluss mit der hohen Genauigkeit.
</code></pre>
<p>Sowas bringt aber sehr viele Probleme:<br />
- du musst darauf achten die Grenzen deines Typs(z.B. __int64) nicht zu überschreiten<br />
- wenn du mit einer Zahl rechnen willst die mehr Nachkommestellen als deine bisherigen hat musst du alle erstmal anpassen<br />
- spätestens beim Zurückrechnen in einen double-Wert geht ein Teil der Genauigkeit wieder flöten<br />
- Divisionen liefern dir maximal deine voreingestellte Genauigkeit (im oberen Beispiel 6 Stellen hinterm Koma)<br />
- etc.</p>
<p>Daher sollte das nur im sehr kleinen Rahmen und wenn du ganz genau weißt was du tust verwendet werden.</p>
<p>Eine bessere Alternative wäre <a href="http://www.c-plusplus.net/forum/viewtopic-var-t-is-151578.html" rel="nofollow">Punkt 4 der FAQ</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1698895</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1698895</guid><dc:creator><![CDATA[rean]]></dc:creator><pubDate>Mon, 20 Apr 2009 21:36:17 GMT</pubDate></item><item><title><![CDATA[Reply to Subtraktion mit Double (falsches Resultat) on Mon, 20 Apr 2009 22:59:10 GMT]]></title><description><![CDATA[<p>Hallo</p>
<p>Ich werde mir dies mal anschauen.<br />
Ich habe das ganze nun nochmals durchgeschaut, und ich benötige 5 Nachkomma stellen.</p>
<p>In gewissen fällen, wird es korrekt gerechnet. Dann wieder nicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1698907</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1698907</guid><dc:creator><![CDATA[Deforation]]></dc:creator><pubDate>Mon, 20 Apr 2009 22:59:10 GMT</pubDate></item><item><title><![CDATA[Reply to Subtraktion mit Double (falsches Resultat) on Mon, 20 Apr 2009 23:38:09 GMT]]></title><description><![CDATA[<p>Deforation schrieb:</p>
<blockquote>
<p>In gewissen fällen, wird es korrekt gerechnet. Dann wieder nicht.</p>
</blockquote>
<p>Da ist mir nicht ganz klar, was du meinst.</p>
<p>Der oben dargestellte Fall muss funktionieren. Der Unterschied ist bei einer einfachen Subtraktion viel zu groß um mit &quot;Fließkomma Genauigkeit&quot; erklärt zu werden.</p>
<p>Mit welchem System arbeitest du?<br />
Wie groß ist double bei dir? sizeof(double)<br />
Wie gibst du das Ergebnis aus bzw. woher stammt die Zahl 6.6678246842E-05?</p>
<p>Also, etwas mehr Informationen (Programmcode) würden helfen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1698909</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1698909</guid><dc:creator><![CDATA[Mitleid]]></dc:creator><pubDate>Mon, 20 Apr 2009 23:38:09 GMT</pubDate></item><item><title><![CDATA[Reply to Subtraktion mit Double (falsches Resultat) on Tue, 21 Apr 2009 18:06:35 GMT]]></title><description><![CDATA[<blockquote>
<p>Deforation schrieb:<br />
In gewissen fällen, wird es korrekt gerechnet. Dann wieder nicht.</p>
<p>Da ist mir nicht ganz klar, was du meinst.</p>
</blockquote>
<p>Zur Erläuterung:<br />
Ich möchte habe einen Countdown programmiert (in einem separaten Thread).</p>
<p>Dort ermittle ich stets die Differenz zwischen dem Zieldatum + Zeit zum jetzigen Datum + Zeit.<br />
Anschliessend werden diese umgerechnet und als Tage:Stunden:Minuten:Sekunden dargestellt.</p>
<p>Problem:<br />
Die Rechnung funktioniert stets, ausser wenn die Differenz zwischen den Zeiten 0-9 Sekunden beträgt. Denn dann erhalte ich &quot;komische&quot; Werte.<br />
Wie z.B. 275:547:12:5<br />
was ich darauf zurückführen konnte, dass die Subtraktion ein ungenaues Resultat zurückgibt.</p>
<p>Hier ein Auszug aus dem Code (Geschrieben mit dem C++Builder 2009):</p>
<pre><code class="language-cpp">double dDateVal1;
double dDateVal2;
double dCurrentVal;
double dSeconds;
double dMinutes;
double dHours;
double dDays;
UnicodeString sValue;
UnicodeString sDays;
UnicodeString sHours;
UnicodeString sMinutes;
UnicodeString sSeconds;
UnicodeString sNegative;

dDateVal1=StrToDateTime(tdSynchroDate.FormatString(&quot;dd.mm.yyyy&quot;) + &quot; &quot; + ttSynchroTime.FormatString(&quot;HH:NN&quot;) + &quot;:01&quot;,*tfsDateFormat).Val;
dDateVal2=Date().CurrentDateTime().Val;
dCurrentVal=dDateVal1 - dDateVal2;

if ((i==0 &amp;&amp; tdSynchroDateFeiertag.Val!=0) || i==1) {
	if (dCurrentVal&lt;0){
		sNegative=&quot;- &quot;;
		dCurrentVal*=-1;
	}
	else
              	sNegative=&quot;&quot;;

	//Berechnen der Teilzeiten
	sValue=FloatToStr(dCurrentVal,*tfsDateFormat);

	//Generieren der Zeitangaben
	//Ermitteln der Tage
	dDays=StrToFloat(sValue.SubString(0,sValue.Pos(&quot;.&quot;)-1),*tfsDateFormat);

	//Ermitteln der Stunden
	dCurrentVal-=dDays;
	dCurrentVal=(dCurrentVal&lt;0) ? dCurrentVal*-1 : dCurrentVal;
	dCurrentVal*=24;
	sValue=FloatToStr(dCurrentVal,*tfsDateFormat);
	dHours=StrToFloat(sValue.SubString(0,sValue.Pos(&quot;.&quot;)-1),*tfsDateFormat);

	//Ermitteln der Minuten
	dCurrentVal-=dHours;
	dCurrentVal=(dCurrentVal&lt;0) ? dCurrentVal*-1 : dCurrentVal;
	dCurrentVal*=60;
	sValue=FloatToStr(dCurrentVal,*tfsDateFormat);
	dMinutes=StrToFloat(sValue.SubString(0,sValue.Pos(&quot;.&quot;)-1),*tfsDateFormat);

	//Ermitteln der Sekunden
	dCurrentVal-=dMinutes;
	dCurrentVal=(dCurrentVal&lt;0) ? dCurrentVal*-1 : dCurrentVal;
	dCurrentVal*=60;
	sValue=FloatToStr(dCurrentVal,*tfsDateFormat);
	dSeconds=StrToFloat(sValue.SubString(0,sValue.Pos(&quot;.&quot;)-1),*tfsDateFormat);

	//Formatieren, so das jedes Glied mindestens 2 Stellen hat
	sDays=FloatToStr(dDays,*tfsDateFormat);
	sHours=FloatToStr(dHours,*tfsDateFormat);
	sMinutes=FloatToStr(dMinutes,*tfsDateFormat);
	sSeconds=FloatToStr(dSeconds,*tfsDateFormat);

	if (sDays.Length()==1)
		sDays=&quot;0&quot; + sDays;
	if (sHours.Length()==1)
		sHours=&quot;0&quot; + sHours;
	if (sMinutes.Length()==1)
		sMinutes=&quot;0&quot; + sMinutes;
	if (sSeconds.Length()==1)
		sSeconds=&quot;0&quot; + sSeconds;

	//Setzen der Zeitangaben
	if (i==0)
		lblCountdownFeiertag-&gt;Caption=sNegative + sDays + &quot;:&quot; + sHours+ &quot;:&quot; + sMinutes + &quot;:&quot; + sSeconds;
	else if (i==1)
		lblCountdownTask-&gt;Caption=sNegative + sDays + &quot;:&quot; + sHours+ &quot;:&quot; + sMinutes + &quot;:&quot; + sSeconds;
</code></pre>
<p><strong>Nun zu den Fragen:</strong><br />
Mit welchem System arbeitest du?<br />
- Windows XP 32-Bit Service Pack 3<br />
- C++ Builder 2009</p>
<p>Wie groß ist double bei dir? sizeof(double)?<br />
- double ==&gt; 8</p>
<p>Wie gibst du das Ergebnis aus bzw. woher stammt die Zahl 6.6678246842E-05?<br />
- Diese Zahl wird mir beim Debugger angezeigt (in der Liste der Lokalen Variabeln)<br />
- Ist der Wert &quot;genau&quot;, so wird dieser dort auch richtig angezeigt<br />
. Ist er eben nicht genau, wird ein Wert wie oben beschrieben angezeigt.</p>
<p>Wichtig:<br />
Ich habe die Datumswerte auch auf 5 Kommastellen gekürzt. (Diese Anzahl brauche ich ja, da 1 = 1 Tag ist und ich das ganze Sekundengenau benötige.</p>
<p>Ich hoffe, ich konnte mit diesen Informationen mein Problem ein wenig verdeutlichen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1699319</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1699319</guid><dc:creator><![CDATA[Deforation]]></dc:creator><pubDate>Tue, 21 Apr 2009 18:06:35 GMT</pubDate></item><item><title><![CDATA[Reply to Subtraktion mit Double (falsches Resultat) on Tue, 21 Apr 2009 19:23:17 GMT]]></title><description><![CDATA[<p>Deforation schrieb:</p>
<blockquote>
<p>...</p>
</blockquote>
<p>1. Befindest du dich im ANSI C++ Forum, dein Code ist jedenfalls VCL<br />
2. Solltest du dir mal die Hilfsfunktionen für Datum/Zeit/Zeitabstände... in der VCL betrachten, ich bin mir Sicher, das dein Code sich a) lesbarer und b) deutlich kürzer schreiben kannst.<br />
3. Sollte es dich selbst schon zum Nachdenken bringen wie viele Konvertierungen du im Code durchführst.</p>
<p>cu André</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1699356</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1699356</guid><dc:creator><![CDATA[asc]]></dc:creator><pubDate>Tue, 21 Apr 2009 19:23:17 GMT</pubDate></item><item><title><![CDATA[Reply to Subtraktion mit Double (falsches Resultat) on Tue, 21 Apr 2009 21:35:45 GMT]]></title><description><![CDATA[<p>Deforation schrieb:</p>
<blockquote>
<p>Ich hoffe, ich konnte mit diesen Informationen mein Problem ein wenig verdeutlichen.</p>
</blockquote>
<p>Also, ich versuche erst gar nicht da durchzusteigen und werfe das Handtuch. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /><br />
Es ist jedenfalls deutlich mehr involviert als die Subtraktion in deinem ersten Beitrag, das wird jetzt klar.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1699436</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1699436</guid><dc:creator><![CDATA[Mitleid]]></dc:creator><pubDate>Tue, 21 Apr 2009 21:35:45 GMT</pubDate></item><item><title><![CDATA[Reply to Subtraktion mit Double (falsches Resultat) on Wed, 22 Apr 2009 08:30:12 GMT]]></title><description><![CDATA[<p>Es sieht in jedem Fall so aus, als würdest ein paar mehr Operationen mit deinen Variablen durchführen, als nur eine Subtraktion.</p>
<p>Hast du mal konstant überprüft, wie sich deine Variablen während deinem Programm verändern und welchen Fehler du damit mitschleppst, oder beziehen sich deine Werte auf &quot;die schieb ich oben rein und das kommt unten raus&quot;?</p>
<p>Im zweiten Fall wird deine Ungenauigkeit schlichtweg durch das Ausführen von sehr vielen Gleitkommaoperationen hintereinander immer größer..</p>
<p>Sieh dir mal die einzelnen Subtraktionen separat an, dann wirst du, denke ich, sehen, wie da kleine Ungenauigkeiten immer größer werden. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1699532</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1699532</guid><dc:creator><![CDATA[cerotidinon]]></dc:creator><pubDate>Wed, 22 Apr 2009 08:30:12 GMT</pubDate></item><item><title><![CDATA[Reply to Subtraktion mit Double (falsches Resultat) on Wed, 22 Apr 2009 11:59:38 GMT]]></title><description><![CDATA[<p>Das Problem tritt bei folgenden Zeilen auf:</p>
<pre><code>dDateVal1=StrToDateTime(tdSynchroDate.FormatString(&quot;dd.mm.yyyy&quot;) + &quot; &quot; + ttSynchroTime.FormatString(&quot;HH:NN&quot;) + &quot;:01&quot;,*tfsDateFormat).Val;
dDateVal2=Date().CurrentDateTime().Val;
dCurrentVal=dDateVal1 - dDateVal2;
</code></pre>
<p>das heisst, dass dCurrentVal nun einen komischen Wert hat.<br />
Und da wird noch nichts gemacht ausser eine Subtrakton.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1699635</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1699635</guid><dc:creator><![CDATA[Kreilon]]></dc:creator><pubDate>Wed, 22 Apr 2009 11:59:38 GMT</pubDate></item><item><title><![CDATA[Reply to Subtraktion mit Double (falsches Resultat) on Wed, 22 Apr 2009 12:25:49 GMT]]></title><description><![CDATA[<p>Ich bin zu faul, mir den ganzen Code durchzulesen. Aber in der VCL kann man direkt mit Datums- / Zeitwerten rechnen. Siehe TDateTime.<br />
Es gibt auch eine Funktion SecondsBetween(), mit der sich die Sekunden zwischen zwei Datumswerten ermitteln lassen. Da brauxhst Du dann gar keine double-Variablen mehr...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1699651</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1699651</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Wed, 22 Apr 2009 12:25:49 GMT</pubDate></item></channel></rss>