Hej!
Jag är rätt ny på det här med c++, men jag skulle vilja veta hur man kollar om ett tal har decimaler med någon form ac if-sats, någon som vet?
Mycket tacksam för svar!
10 svar · 672 visningar · startad av andreaswebb
Hej!
Jag är rätt ny på det här med c++, men jag skulle vilja veta hur man kollar om ett tal har decimaler med någon form ac if-sats, någon som vet?
Mycket tacksam för svar!
Antar att talet 4,000000 räknas som ett tal utan decimaler? :q I så fall kan du göra så här:
if (tal == (int) tal)
Om tal är 7 har (int) 7 ingen effekt, så det blir 7 == 7 som ju stämmer.
Om tal är float 7,0 så blir det: (int)7,0 ==> 7 som jämförs med 7,0. Jämförelsen kommer att konvertera 7 tillbaka till 7,0 alltså stämmer det.
Om tal är 3,1415 blir (int) 3,1415 = 3 Jämförelsen konverterar 3 till motsvarande float ==> 3,0. Nu står det 3,1415 == 3,0 vilket inte stämmer....
Om du däremot räknar 3,000000 som ett tal med decimaler så är du ute efter att kolla om tal är ett heltal, eftersom float alltid har decimaler.
Ett flyttal kan bara vara exakt 0. Det kan aldrig vara exakt något annat tal. Därför fungerar inte tipsen ovan.
Ett tal som presenteras som 7,00 kan egentligen vara 7,000001. Du måste istället kolla om talet är nära ett heltal.
Detta kan fungera:
float tal2 = tal - (int)tal;
if(tal2 > -0.0001f && tal2 < 0.0001f)
Marcus E skrev:
Ett flyttal kan bara vara exakt 0. Det kan aldrig vara exakt något annat tal. Därför fungerar inte tipsen ovan.
Åjo, nog fungerar de alltid.
Visst har du rätt i att exakt 7 ofta ej kan representeras som flyttal, men det gäller ju även det tal som du jämför med.
Detta program returnerar 1 i VC++ 7.1:
int main()
{
float f = 7;
if (f == int(f))
return 1;
return 0;
}
Byter du ut 7 mot 7.01 returnerar det 0.
Skillnaden mellan min kod och era koder är min kod tar hänsyn till att värdet inte är exakt 7. Era koder kan få problem med det. Nu vet jag inte hur ofta problemet kommer. Om det är 1 av 2 gånger, 1 av 1000 gånger eller aldrig, men möjligheten finns. Du verkar ha testat ett tal på en dator med en kompilator. Inte särskilt mycket till bevis. :)
Ja, det stämmer att din version är mindre exakt, men Sang-draxs version funkar också. Notera att uttrycket float == int översätts till float == float(int), så det spelar ingen roll om man exakt kan representera 7 med en float eller ej. Uttrycket 7.0f == float(7) blir alltid sant.
Marcus E skrev:
Skillnaden mellan min kod och era koder är min kod tar hänsyn till att värdet inte är exakt 7. Era koder kan få problem med det.
Nej.
Marcus E skrev:
Nu vet jag inte hur ofta problemet kommer. Om det är 1 av 2 gånger, 1 av 1000 gånger eller aldrig, men möjligheten finns. Du verkar ha testat ett tal på en dator med en kompilator. Inte särskilt mycket till bevis. :)
#define nagotTal <vilket heltal du vill>
float f = nagotTal; //Nu innehåller f en inexakt representation av talet
När vi nu vill kolla om f är ett heltal så skriver vi som följer:
if ( f == float(int(f)) )
vilket motsvarar koden
int iTemp = f; //Decimaldelen av f försvinner och heltalsdelen lagras i iTemp
float fTemp = iTemp; //fTemp innehåller exakt samma inexakta representation som f om f var ett heltal
if (f == fTemp)
Det förutsätts att detta gäller:
float f = 7;
int(f) != 6; //Förutsättning
Om detta resonemang ej tillfredställer dig, kanske följande program kan övertyga lite. Det returnerar 1 på min dator.
int main()
{
const int limit = 1000000;
for (int i = -limit; i <= limit; ++i)
{
double f = i;
if (f != double(int(f)) )
return 0;
if (f+0.1 == double(int(f)) )
return 0;
}
return 1;
}
Sang-drax, det Marcus E menar är att om man har gjort beräkningar på sitt tal innan man vill kolla om det är ett heltal så kan oexaktheten i representationen göra att våra lösningar ger false när man skulle vilja ha svaret true.
Om du har talet 7,0000000000000001 och VILL att det ska räknas som heltalet 7, så ger våra enklare lösningar fel svar. Det har han rätt i. Så det beror bl. a. på var siffran man ska jämföra med kommer ifrån om våra lösningar är tillräckligt OK eller ej.
assah verkar förstår vad jag menar. Så fort man gör någon beräkning på talet så förlorar det sin precision.
Följande exempel demonstrerar:
bool MarcusHeltal(float tal)
{
float tal2 = tal - floor(tal + 0.5f);
if(tal2 > -0.0001f && tal2 < 0.0001f)
return true;
else
return false;
}
int _tmain(int argc, _TCHAR* argv[])
{
for(float tal = -100; tal <= 100; tal++)
{
float tal2 = tal + 0.1f;
tal2 -= 0.1f;
bool heltal = MarcusHeltal(tal2);
//bool heltal = (tal == float(int(tal)) );
printf("%f %s\r\n", tal2, heltal ? "Heltal" : "Fel");
}
}
Med din bortkommenterade funktion fungerar det ej. Med min funktion visar det att det alltid är heltal, trots att talen ofta slutar med ,999999 och liknande.