2016-07-05 20 views
1

dieser Code gegeben, dass mein Professor uns in einer Prüfung gab, die bedeutet, dass wir den Code noch verwenden Sie die Funktion aus anderen Bibliotheken nicht ändern können (außer stdio.h):Von einem Schwimmer auf eine ganze Zahl

float x; 

(suppose x NOT having an integer part) 
while (CONDITION){ 
    x = x*10 
} 

I haben Finden Sie die Bedingung , die sicherstellt, dass x keine gültige Zahl rechts vom Dezimalpunkt hat nicht auf die Probleme der Genauigkeit einer Gleitkommazahl (Nach dem Komma müssen wir nur Nullen haben). Ich habe versucht, diesen Zustand:

while ((fmod((x*10),10))){ 
    X = X*10 
} 
printf(" %f ",x); 

Beispiel:

INPUT x=0.456; --------> OUTPUT: 456.000 
INPUT X=0.4567;--------> OUTPUT; 4567.000 
It is important to be sure that after the decimal point we don't have any   
significant number 

Aber ich hatte math.h Bibliothek enthalten, aber mein Professor erlaubt uns nicht, es in diesem speziellen Fall zu verwenden (ich bin nicht sogar erlaubt (lang) zu benutzen, da wir es nie in der Klasse gesehen haben).

Also, was ist die Bedingung, die das Problem ohne diese Bibliothek richtig lösen?

+2

Diese Regel macht keinen Sinn, da Fließkomma nicht genau die meisten Zahlen darstellen können und werden so viele Dezimalstellen haben, wie es insgesamt Präzision ist. – 2501

+0

Sie könnten [Float-Typ] (https://en.wikipedia.org/wiki/IEEE_754-1985t) studieren und einige Tests an internen Bits durchführen – purplepsycho

+1

_Ich darf nicht einmal (long) verwenden, da wir nie gesehen haben es in der Klasse_ Das macht keinen Sinn .... Cast ist der einfachste Weg, dies zu tun, obwohl, wie @ 2501 bereits schrieb, nicht korrekt ist. – LPs

Antwort

0

Es gibt Unschärfen ("nicht auf die Probleme der Genauigkeit einer float Zahl" in der Frage, aber ich denke, eine gesuchte Antwort ist unten, zuweisen x zu einem ganzzahligen Typ, bis x nicht mehr einen Bruchteil hat.

Der Erfolg dieser Methode hängt von INT_MIN <= x <= INT_MAX ab. Dies wird erwartet, wenn die Anzahl der Bits in der Signifikanz von float die Wertbits int nicht überschreitet. Obwohl dies üblich ist, wird es nicht von C spezifiziert.Als Alternative könnte Code mit einem breiteren ganzzahligen Typ wie long long mit einer weit geringeren Wahrscheinlichkeit des Bereichsbeschränkungsproblems verwendet werden.

die Rundung mit *10 eingeführt gegeben, ist diese Methode nicht eine gute Grundlage für float zu-Text-Konvertierung.

float Dipok(float x) { 
    int i; 
    while ((i=x) != x) { 
     x = x*10; 
    } 
    return x; 
} 

#include <assert.h> 
#include <stdio.h> 
#include <float.h> 

void Dipok_test(float x) { 
    // suppose x NOT having an integer part 
    assert(x > -1.0 && x < 1.0); 
    float y = Dipok(x); 
    printf("x:%.*f y:%.f\n", FLT_DECIMAL_DIG, x, y); 
} 

int main(void) { 
    Dipok_test(0.456); 
    Dipok_test(0.4567); 
    return 0; 
} 

Ausgabe

x:0.456000000 y:456 
x:0.456699997 y:4567 
+0

... und 'Dipok_test (0,001);' ergibt 'x: 0,001000 y: 10000001' auf meinem Rechner. –

+0

siehe auch http://ideone.com/lf3sQv –

+1

@undur_gongor Ein typisches 'float' mit dem Format [binary32] (https://en.wikipedia.org/wiki/Single-precision_floating-point_format) mit' float x = 0.001 'wird' x' auf den exakten Wert von '0,001000000047497451305389404296875' setzen. Es ist dieser Wert, den Dipok (float x) erhält. In Anbetracht der Tatsache, dass OP angegeben hat, "die Probleme der Genauigkeit einer Gleitkommazahl nicht zu beachten", ist die Antwort von "10000001" in Ordnung. OP verwendet dies sicherlich als Basis für andere Anwendungen und wird die Schleifenanzahl von while ((i = x)! = X) verwenden, um "100", "10000001" oder was auch immer weiter zu verarbeiten. – chux

0

Wie bereits von 2501 gezeigt, ist dies einfach nicht möglich.

Schwimmer sind nicht genau. Abhängig von Ihrer Plattform wird der Gleitkommawert für 0,001 tatsächlich als etwa 0,0010000001 dargestellt.

Was würden Sie erwarten, dass der Code berechnet: 10000001 oder 1?

Jede Lösung funktioniert nur für einige Werte.

+0

Typische 'float' haben 6+ Stellen mit _relativer_ Dezimalgenauigkeit. Ihre Werte sind genau. Das Problem ist, dass viele _operations_ on 'floats' eine Rundung wie die Zuweisung von' float x = 0.001; 'verursachen. – chux

2

Wie bereits hier zuvor aus: Durch die Genauigkeit der Schwimmer dies nicht wirklich möglich ist, aber ich denke, Ihr Prof etwas wie

while (x - (int)x != 0) 

oder

while (x - (int)x >= 0.00000001) 

Sie können loswerden will bekommen der Nullen mit dem G-Modifikator anstelle von f:

printf(" %g \n",x); 
+1

Dies wird fehlschlagen, wenn der tatsächliche Float-Wert etwas kleiner ist als der beabsichtigte Wert. –

0

Ich versuche, auf meine Prüfung Quest zu beantworten Bitte, wenn ich etwas falsches sage, korrigiere mich!

Es ist nicht möglich, eine ordnungsgemäße Bedingung zu finden, die sicherstellt, dass keine gültige Nachkommastelle existiert. Zum Beispiel: Wir wollen das Ergebnis von 0,4 * 20 wissen, welche 8,000 aber wegen Ungenauigkeit Probleme ist der Ausgang anders sein:

f=0.4; 
for(i=1;i<20;i++) 
    f=f+0.4; 
printf("The number f=0.4*20 is "); 
if(f!=8.0) {printf(" not ");} 
printf(" %f ",8.0); 
printf("The real answer is f=0.4*20= %f",f); 

Unsere ausgegeben:

The number f=0.4*20 is not 8.000000 

The real answer is f=0.4*20= 8.000001 
+0

Ich sollte nicht die Funktion von anderen Bibliotheken außer stdio.h verwenden, ich habe nur printf nur um zu zeigen, dass die Float-Nummern nicht präzise sind. – Dipok

+0

Oh, Entschuldigung, danke für's Bemerken! – Dipok

Verwandte Themen