webForumDet fria alternativet

Kolla om ett tal är har decimaler

C/C++ur C/C++

10 svar · 672 visningar · startad av andreaswebb

Medlem sedan apr. 2003101 inlägg
Frågan#1

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!

Medlem sedan juli 2002581 inlägg
#2

Detta kanske fungerar:

if ( tal == float(int(tal)) )
Medlem sedan mars 20034 471 inlägg
#3

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.

Medlem sedan maj 20021 466 inlägg
#4

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)

Medlem sedan juni 20008 205 inlägg
#5

Annars kan man ju köra med

if (floor(tal) == tal) // bra nära heltal
Medlem sedan juli 2002581 inlägg
#6

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.

Medlem sedan maj 20021 466 inlägg
#7

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. :)

Medlem sedan juni 20008 205 inlägg
#8

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.

Medlem sedan juli 2002581 inlägg
#9

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;
}
Medlem sedan mars 20034 471 inlägg
#10

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.

Medlem sedan maj 20021 466 inlägg
#11

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.

141 ms totalt · 3 externa anrop · v20260731065814-full.4bcf49fe
138 ms — hämta forumlista (db)
0 ms — hämta statistik (cache)
130 ms — hämta tråd, inlägg och bilagor (db)