Forum: PC-Programmierung C# double Type nächst kleineren darstellbaren Wert finden


von Be B. (bebo)


Lesenswert?

Hallo,

gibt es eine Möglichkeit eine Variable vom Typ double in C# um den 
kleinstmöglichen Wert zu verringern, der darstellbar ist?

Problem:
Ich habe eine Zeitspanne, die in Sekunden (mit Nachkommastellen) 
angegeben ist. Ich möchte wissen, wie viel 5 Sekunden Blöcke nötig sind. 
Also rechne ich (int)(Zeitspanne / 5). Raus kommen soll also folgendes:

größer 0 bis 5 = 1
größer 5 bis 10 = 2
größer 10 bis 15 = 3

4.99/5 ist immer noch Null, da mit der int Konvertierung die 
Nachkommastellen wegfallen. Nun könnte ich einfach +1 rechnen. Nur was 
mache ich, wenn der Wert genau 5 ist. 5/5 = 1 und jetzt noch +1 ergibt 
2. Aber wie oben zu sehen soll auch bei 5 noch 1 und bei 10 noch 2 
herauskommen.
Die Lösung wäre nun, daß ich die Zeitspanne minimal verringere, so daß 5 
minus irgend etwas sehr kleines schon mal weniger als 5 ist und dann 
reicht es durch 5 zu teilen und die Nachkommastellen weg zuschmeißen.

Also wie verringere ich einen double Wert so, daß es keinen weiteren 
darstellbaren Wert zwischen dem ursprünglichen und dem verringerten Wert 
gibt. Also wie ziehe ich eine Einheit von der Mantisse des double Werts 
ab?

von D. I. (Gast)


Lesenswert?

Be Bo schrieb:
> 4.99/5 ist immer noch Null, da mit der int Konvertierung die
> Nachkommastellen wegfallen.

Aber genau dieses Verhalten entspricht doch deiner Definition? 
Andernfalls würdest du das Problem doch nur verschieben.

von Peter II (Gast)


Lesenswert?

int x = wert / 5;

if ( x * 5 < wert ) {
   x++;
}

von Yalu X. (yalu) (Moderator)


Lesenswert?

In C geht es so:
1
n = (int)ceil(t / 5);

Die ceil-Funktion heißt in C# m.W. Math.Ceiling.

Die Edith hat gerade folgendes erfolgreich ausprobiert:
1
int n = (int)Math.Ceiling(x / 5);

und
1
Int32 n = (Int32)Math.Ceiling(x / 5);

und
1
Int32 n = Convert.ToInt32(Math.Ceiling(x / 5));

von Be B. (bebo)


Lesenswert?

ich möchte von 0.000...001 bis 5 den Wert 0 herausbekommen und von 
5.000...001 bis 10 den Wert 1.

Ich bekomme aber nur von 0 bis 4,999...9999 den Wert 0 und von 5 bis 
9.999...999 den Wert 1, wenn ich durch 5 Teile.

Letztlich möchte ich wissen, wie ich einen double Wert um den 
kleinstmöglichen Wert verringere. Da die Mantisse auf 15-16 Stelle 
begrenzt ist, ist der kleinstmögliche darstellbare Wert abhängig vom 
Exponenten.

@Peter II:
ist x=wert/5 und anschließendes x*5 wirklich wieder "wert"? Ich bin mir 
da bei der 15. oder 16. Nachkommastelle nicht mehr so sicher?

von Rolf M. (rmagnus)


Lesenswert?

Be Bo schrieb:
> Letztlich möchte ich wissen, wie ich einen double Wert um den
> kleinstmöglichen Wert verringere. Da die Mantisse auf 15-16 Stelle
> begrenzt ist, ist der kleinstmögliche darstellbare Wert abhängig vom
> Exponenten.

Und du bist sicher, daß du auch wirklich die vollen 15 Stellen 
Genauigkeit brauchst, und das auch über einen größeren Zahlenbereich, 
also z.B. eine Zeitspanne von 31 Jahren auf eine Mikrosekunde genau, 
aber auch eine Zeitspanne von einer Sekunde auf eine Femtosekunde genau? 
Wenn nicht, würde ich irgendeinen einen Wert nehmen, der einfach klein 
genug für deine Anforderungen ist.

von Be B. (bebo)


Lesenswert?

Na ja, im Moment verwende ich 0.0001 Sekunde, daß paßt noch. Dann werde 
ich auch damit weitermachen.

Dachte nur, es gäbe vielleicht ein Möglichkeit so wie -1 bei int.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Hast du meinen Beitrag von oben gelesen? Was du doch suchst, ist eine
Funktion, die das Ergebnis der Division durch 5 aufrundet, und die gibt
es schon fertig in der Mathebibliothek.

von C#Rechner (Gast)


Lesenswert?

Also wenn ich das richtig verstanden habe willst du eine Aktion 
ausführen die sich nach den Ergebnissen von 1, 2, oder 3 richtet ?
Wie wäre es denn wenn du die Aktion einfach ausführst indem du mit If 
Anweisungen arbeitest ? Wäre zwar ganz ohne Berechnungen und Boxing, 
könnte aber genau so funktionieren.

if (Zeitspanne > X)
else if (Zeitspanne > X)
.
.
.

von amateur (Gast)


Lesenswert?

Warum schaust Du Dir nicht explizit den Fraktionalteil der kastrierten 
Zahl an. Wenn es nur um die Neuner geht, so bastele doch eine Abfrage in 
der Form: >= 0.999?? rein und handel danach.

Andere geben einen Angstzuschlag in Form von: +0,01 oder so hinzu.

Egal, was Du auch machst: Du verschiebst das Problem nur. Auch sollte 
man nicht vergessen 30 ist nur für das menschliche Auge eine gerade 
Zahl.
Computy sieht das ganz anders.

von Be B. (bebo)


Lesenswert?

Yalu hat recht.

Habe wohl den Sinn der Ceiling Funktion erst falsch verstanden. Aber sie 
funktioniert, so wie ich es möchte.

Danke

von Sebastian (Gast)


Lesenswert?

Also naiv hätte ich's von der Idee her wie C#Rechner gemacht nur dass 
man die ifs anders verschachteln muss

If(x>0)
{
   i=1;
   If(x>5)
   {
       i++;
       If(x>10)
       {
          i++;
       }
    }
}

Ich denke so funktionierte genauso wie ceil nur verständlicher.
Immer darauf achten dass ein nächster dass mal bearbeiten muss und dann 
nicht auf Anhieb versteht was ceil macht.
Und in c# geht's nicht um die paar Zeilen mehr.

von Sebastian (Gast)


Lesenswert?

Oder

For(i=0;x>i*5;i++)

Wenn x nicht nur in ein paar Bereichen sein kann

von D. I. (Gast)


Lesenswert?

Sebastian schrieb:
> nicht auf Anhieb versteht was ceil macht.

Der sollte sich dann einen anderen Job suchen bevor jemand dein 
Konstrukt umsetzt, da rollt es einem ja die Zehennägel hoch.

von Sebastian (Gast)


Lesenswert?

Ich kann es zwar Grade nicht testen aber was komm raus wenn 5 nur um 
epsilon größer (also kleinster Double abstand) durch 5 geteilt wird und 
dann aufgerundet wird. Per Anforderung muss 2 rauskommen. Wenn das nicht 
der fall ist, erfüllt ceil im Grunde die Anforderung nicht. Mein Ansatz 
wenn auch naiv erfüllt die Anforderung auf jeden fall und natürlich weiß 
ich dass es grundsätzlich mit ceil einfach und verständlich ist. Nur 
wenn der TO schon die Numerik anpackt dann muss einen sowas auch ins 
Auge springen auch wenn's hässlich ist.

von C#Rechner (Gast)


Lesenswert?

D. I. schrieb:
> Der sollte sich dann einen anderen Job suchen

Also wenn jemand hier im Mikrocontroller Forum bei so einem Problem nach 
Hilfe fragt, macht er es bestimmt nicht Beruflich sondern rein zum 
privaten Vergnügen.
Und im privaten Bereich muß nicht immer alles in einer Zeile stehen, 
nicht perfekt sein und schon gar nicht "toll aussehen".


Außerdem finde ich Aussagen wie "das ist kacke" und "das machst du/ihr 
alles falsch" wenig konstruktiv, wenn man schon solche Dinge von sich 
gibt sollte man auch einen Lösungsweg präsentieren. (Hausaufgaben mal 
ausgenommen)

Das ist nur meine Meinung, möchte damit niemandem auf den Schlips 
treten...

von D. I. (Gast)


Lesenswert?

C#Rechner schrieb:
> Also wenn jemand hier im Mikrocontroller Forum bei so einem Problem nach
> Hilfe fragt, macht er es bestimmt nicht Beruflich sondern rein zum
> privaten Vergnügen.
> Und im privaten Bereich muß nicht immer alles in einer Zeile stehen,
> nicht perfekt sein und schon gar nicht "toll aussehen".

Ich spielte auf den Passus an, dass der Code einfacher sei wenn ihn 
jemand anders zu Gesicht bekäme weil er ihn bearbeiten müsse. Das kommt 
dann im privaten nicht so häufig vor denke ich.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.