C++ integers, long och long long vad är egentligen rätt?

Trädvy Permalänk
Medlem
Registrerad
Maj 2012

C++ integers, long och long long vad är egentligen rätt?

Hej!

Har börjat och försökt lärt mig C++ på egen hand, har kollat mycket YouTube klipp och det går mycket framåt.

Har även sökt denna fråga på Google och får relativt bra svar, jag vill bara vara säker som inget slår tillbaka.

Har fastnat vid en integer fråga, är osäker på long, int och long long.

Har förstått att man kan använda "long" framför int, som vid "short int" och får således ett lägre int tal som därmed blir lägre sparad information på minnet.

Men när jag kör en test så är "long int" och int samma värde, när jag kollade på en video och sökte information så kunde "long int" vara > eller = int.

När jag kör en test som denna tex,

int main() { __int64 int64 = 100; unsigned __int64 unsigned_int64 = 100; unsigned int unsigned_int = 100; long int long_int = 100; int normal_int = 100; short int short_int = 100; cout << "__INT64 " << _I64_MAX << " - " << _I64_MIN << endl; cout << "Size on system: " << sizeof(int64) << " bytes" << endl << endl; cout << "UNSIGNED __INT64 " << _UI64_MAX << " - " << 0 << endl; cout << "Size on system: " << sizeof(unsigned_int64) << " bytes" << endl << endl; cout << "UNSIGNED INT " << UINT_MAX << " - " << 0 << endl; cout << "Size on system: " << sizeof(unsigned_int) << " bytes" << endl << endl; cout << "INT " << INT_MAX << " - " << INT_MIN << endl; cout << "Size on system: " << sizeof(normal_int) << " bytes" << endl << endl; cout << "LONG INT " << LONG_MAX << " - " << LONG_MIN << endl; cout << "Size on system: " << sizeof(long_int) << " bytes" << endl << endl; cout << "SHORT " << SHRT_MAX << " - " << SHRT_MIN << endl; cout << "Size on system: " << sizeof(short_int) << " bytes" << endl << endl; long long x = 9223372036854775807; cout << "LONG LONG, stored value: " << x << endl; cout << "Size on system: " << sizeof(x) << " bytes" << endl << endl; system("pause"); }

Får jag detta som svar,

__INT64 9223372036854775807 - -9223372036854775808 Size on system: 8 bytes UNSIGNED __INT64 18446744073709551615 - 0 Size on system: 8 bytes UNSIGNED INT 4294967295 - 0 Size on system: 4 bytes INT 2147483647 - -2147483648 Size on system: 4 bytes LONG INT 2147483647 - -2147483648 Size on system: 4 bytes SHORT 32767 - -32768 Size on system: 2 bytes LONG LONG, stored value: 9223372036854775807 Size on system: 8 bytes

Min stora fråga är, vad ska jag använda?

Vad är vitsen med long int, varför inte bara använda "int" som har precis samma värden?
Jag förstår vitsen och meningen med int, short, unsigned och __int64. Men inte long int eftersom det är samma som int.

Ska jag eller kan jag bara använda int eller kommer något slå mig i bakhuvudet om jag gör det?

Long long verkar också kunna lagra samma värden som __int64, varför inte bara använda __int64?

Är lite trött men jag hoppas ni förstår min fråga, varför använda long long och long int när jag kan använda __int64 och int istället?

Annan intressant information Integer Limits, Microsoft Visual Studio 2015

Använder Visual Studio 2015.

Tack ni som orkade läsa igenom min halv vackra text!

Speldator: [Intel Core i7 4790K] [ASUS Matrix GTX 780Ti x2] [ASUS MAXIMUS VII HERO] [Corsair Dominator Platinum 32GB] [Windows 7] [Logitech G400S] [Microsoft Ergonomic 4000] [BenQ XR3501 35" (HDMI)] [BenQ G900W 19" (VGA)]

Serverdator: [Intel Core i7 6850K] [ASUS X99-E WS] [Corsair Vengeance LPX 64GB] [2x Crucial MX300 1TB] [Cooler Master V1200] [CentOS 7]

Trädvy Permalänk
Medlem
Plats
Skellefteå
Registrerad
Okt 2008

Det var länge sedan jag jonglerade med C/C++ men det är av historiska skäl som long "beter sig" så där (från 16-bit-systemens tid troligen), och har inte ändrats pga bakåtkompatibilitet. Har ingen specifik rekommendation, men om antalet bitar för dina heltal är viktigt så är det väl bäst att explicit specificera det (dvs __int64 kommer ju alltid att bli 64-bit, signed, oberoende av eventuella framtida förändringar och kompilatorer).

1800X, 1080 SLI, 4K

Trädvy Permalänk
Medlem
Registrerad
Mar 2013
Skrivet av Dalslandan:

Min stora fråga är, vad ska jag använda?

Vad är vitsen med long int, varför inte bara använda "int" som har precis samma värden?

Nu är jag inte jättehaj på just c++, men ska försöka svara. En long kan lagra större värden än en vanlig int32 eftersom den använder 64 bitar för att lagra värden, istället för 32 (på samma sätt som short int använder 16 bitar istället för 32). Vad du ska använda beror på. Ett exempel är om du vill mäta hur lång tid en viss bit kod tar att köra. I java brukar man anropa System.currentTimeMillis() för en start och en slutpunkt och beräkna differensen. System.currentTimeMillis() returnerar en long (motsvarande long int i c++), helt enkelt för att antalet millisekunder från 00:00 1:a januari 1970 är ett för stort tal för att lagra i en vanlig int. I de allra flesta fall fungerar vanliga ints, men om du nån gång behöver spara tal större än 2'147'483'647, då använder du long int.

Jag hoppas att jag inte missförstod frågan

edit: Vad jag förstår spelar det ingen roll om du väljer __int64 eller long, eller __int16 eller short; bara du är konsekvent, för stilens skull.

MSI z170a SLI-Plus - i7 6700K @ 4,6GHz - MSI GTX 770 Gaming 4GB- 32GB HyperX Fury DDR4 2666Mhz - Fractal Design arc midi r2 - Kelvin S36

Trädvy Permalänk
Medlem
Plats
Kristinehamn
Registrerad
Aug 2014
Skrivet av GiletteRazor:

Nu är jag inte jättehaj på just c++, men ska försöka svara. En long kan lagra större värden än en vanlig int32 eftersom den använder 64 bitar för att lagra värden, istället för 32 (på samma sätt som short int använder 16 bitar istället för 32). Vad du ska använda beror på. Ett exempel är om du vill mäta hur lång tid en viss bit kod tar att köra. I java brukar man anropa System.currentTimeMillis() för en start och en slutpunkt och beräkna differensen. System.currentTimeMillis() returnerar en long (motsvarande long int i c++), helt enkelt för att antalet millisekunder från 00:00 1:a januari 1970 är ett för stort tal för att lagra i en vanlig int. I de allra flesta fall fungerar vanliga ints, men om du nån gång behöver spara tal större än 2'147'483'647, då använder du long int.

Jag hoppas att jag inte missförstod frågan

edit: Vad jag förstår spelar det ingen roll om du väljer __int64 eller long, eller __int16 eller short; bara du är konsekvent, för stilens skull.

Det spelar roll eftersom long är inkonsekvent med storleken vid kompilering. Det är betydligt bättre att använda __intXX för dina variabler, speciellt om man har koll på hur stora värden man avser lagra i dem.

Kör Linux - Yes! We are the 2 percent! And growing... Föreslå inte ens något Windows-exklusivt om jag inte specifikt frågar efter något till Win.
2600K - 18GB RAM - 1TB HDD - 64GB SSD - GTX 650 Ti Boost
Minnesvärda trådar: 1, 2

Trädvy Permalänk
Medlem
Registrerad
Maj 2012
Skrivet av backfeed:

Det var länge sedan jag jonglerade med C/C++ men det är av historiska skäl som long "beter sig" så där (från 16-bit-systemens tid troligen), och har inte ändrats pga bakåtkompatibilitet. Har ingen specifik rekommendation, men om antalet bitar för dina heltal är viktigt så är det väl bäst att explicit specificera det (dvs __int64 kommer ju alltid att bli 64-bit, signed, oberoende av eventuella framtida förändringar och kompilatorer).

Okej, jo C++ är ju speciellt eftersom det går att köra på så många olika system. Långt ifrån alla har ju t.ex. 32 bit, men är ju mycket vanligare idag såklart. Som sagt, jag är i upplärningsfasen som det bästa jag förstår är att använda int och __int64 istället och inte bry sig mera för tillfället? Tack för svar,

Skrivet av GiletteRazor:

Nu är jag inte jättehaj på just c++, men ska försöka svara. En long kan lagra större värden än en vanlig int32 eftersom den använder 64 bitar för att lagra värden, istället för 32 (på samma sätt som short int använder 16 bitar istället för 32). Vad du ska använda beror på. Ett exempel är om du vill mäta hur lång tid en viss bit kod tar att köra. I java brukar man anropa System.currentTimeMillis() för en start och en slutpunkt och beräkna differensen. System.currentTimeMillis() returnerar en long (motsvarande long int i c++), helt enkelt för att antalet millisekunder från 00:00 1:a januari 1970 är ett för stort tal för att lagra i en vanlig int. I de allra flesta fall fungerar vanliga ints, men om du nån gång behöver spara tal större än 2'147'483'647, då använder du long int.

Jag hoppas att jag inte missförstod frågan

Hej, när jag kör t.ex.

long int x = 2147483648;

Så går den runt och tillbaka på -2147483648 igen, x86 som x64.

Som värdet blir ju lite fel :/, det finns i exemplet jag gjorde ovanför mer information.

Tack för svar.

Speldator: [Intel Core i7 4790K] [ASUS Matrix GTX 780Ti x2] [ASUS MAXIMUS VII HERO] [Corsair Dominator Platinum 32GB] [Windows 7] [Logitech G400S] [Microsoft Ergonomic 4000] [BenQ XR3501 35" (HDMI)] [BenQ G900W 19" (VGA)]

Serverdator: [Intel Core i7 6850K] [ASUS X99-E WS] [Corsair Vengeance LPX 64GB] [2x Crucial MX300 1TB] [Cooler Master V1200] [CentOS 7]

Trädvy Permalänk
Medlem
Registrerad
Maj 2012
Skrivet av Erwya:

Det spelar roll eftersom long är inkonsekvent med storleken vid kompilering. Det är betydligt bättre att använda __intXX för dina variabler, speciellt om man har koll på hur stora värden man avser lagra i dem.

Nämen klockrent, hade ingen aning man kunde göra sådär!

Man tackar så mycket!

Speldator: [Intel Core i7 4790K] [ASUS Matrix GTX 780Ti x2] [ASUS MAXIMUS VII HERO] [Corsair Dominator Platinum 32GB] [Windows 7] [Logitech G400S] [Microsoft Ergonomic 4000] [BenQ XR3501 35" (HDMI)] [BenQ G900W 19" (VGA)]

Serverdator: [Intel Core i7 6850K] [ASUS X99-E WS] [Corsair Vengeance LPX 64GB] [2x Crucial MX300 1TB] [Cooler Master V1200] [CentOS 7]

Trädvy Permalänk
Medlem
Plats
Linköping
Registrerad
Jun 2007

I C++ så är int garanterad att vara minst 16 bitar, medan en long är minst 32 bitar. Det är också garanterat att long är minst lika stor som int. Så int och long kan vara lika stora, men long kan också vara större. På mitt 64-bitars Linux-system så är t.ex. int 32 bitar och long 64 bitar. Du kan läsa mer om vilka regler som gäller för typerna här.

Om du vill ha en datatyp med en fast garanterad storlek så kan du inkludera cstdint och använda dessa datatyper. __int64 o.s.v. bör du undvika eftersom det är datatyper specifika för Microsofts C++-kompilator, och därmed inte standard C++.

Man behöver för övrigt inte skriva ut int när man använder short, long, signed eller unsigned. D.v.s. istället för unsigned int så räcker det att bara använda unsigned.

Trädvy Permalänk
Medlem
Registrerad
Maj 2012
Skrivet av perost:

I C++ så är int garanterad att vara minst 16 bitar, medan en long är minst 32 bitar. Det är också garanterat att long är minst lika stor som int. Så int och long kan vara lika stora, men long kan också vara större. På mitt 64-bitars Linux-system så är t.ex. int 32 bitar och long 64 bitar. Du kan läsa mer om vilka regler som gäller för typerna här.

Om du vill ha en datatyp med en fast garanterad storlek så kan du inkludera cstdint och använda dessa datatyper. __int64 o.s.v. bör du undvika eftersom det är datatyper specifika för Microsofts C++-kompilator, och därmed inte standard C++.

Man behöver för övrigt inte skriva ut int när man använder short, long, signed eller unsigned. D.v.s. istället för unsigned int så räcker det att bara använda unsigned.

Mycket intressant, bra att du påpekade mina fel.

Bra beskrivet, man tackar så mycket.

Edit: Jätte informativ sida du länkade.
Inga konstigheter alls, förstår precis hur det ligger till nu.

Speldator: [Intel Core i7 4790K] [ASUS Matrix GTX 780Ti x2] [ASUS MAXIMUS VII HERO] [Corsair Dominator Platinum 32GB] [Windows 7] [Logitech G400S] [Microsoft Ergonomic 4000] [BenQ XR3501 35" (HDMI)] [BenQ G900W 19" (VGA)]

Serverdator: [Intel Core i7 6850K] [ASUS X99-E WS] [Corsair Vengeance LPX 64GB] [2x Crucial MX300 1TB] [Cooler Master V1200] [CentOS 7]

Trädvy Permalänk
Datavetare
Plats
Stockholm
Registrerad
Jun 2011

C++ standarden säger endast detta om char, short int, int och long int:

  • long int kan hålla minst lika stort tal som int

  • int kan hålla minst lika stort tal som short int

  • short int kan hålla minst lika stort tal som char

D.v.s. den garanti som finns är sizeof(char) <= sizeof(short int) <= sizeof(int) <= sizeof(long int)

Standarden säger också att sizeof(char) == 1. Så en fullt kompatibel implementation kan alltså ha long int där sizeof(long int) == 1!!! Tittar man på t.ex. 8-bitars AVR (används i de flesta Arduino-kort) och PIC så är sizeof(int) == 1 och kan därmed hålla tal -128..127.

Du ska använda int när du behöver hantera ett heltal som inte är jättestort, enda egentliga garanti du har är att int är av en storlek som är effektiv för underliggande arkitektur. Exakt hur stor dessa typer är bestäms både av CPU och OS. Jämför du Windows och Linux på x86_64 så är sizeof(long int) olika, den är 4 på Windows och 8 på Linux då 64-bitars Windows använder sig av en standard som kallas LLP64 (endast long long int och pekare är 64-bitars) medan Linux kör med LP64 (long int och pekare är 64-bitars). sizeof(int) är 4 både för IA32 (32-bitars x86) och x86_64, både i Windows och Linux.

Om du behöver en viss storlek använd standardtyperna för detta. __int64 är Windows-specifika och ska undvikas, standard C++ (och standard C) har idag intN_t och uintN_t där N är 8, 16, 32 eller 64. Så för att deklarera en heltalsvariabel som garanterat är 64 bitar, gör detta

#include <cstdint> ... int64_t myvar; ...

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Trädvy Permalänk
Medlem
Registrerad
Maj 2012
Skrivet av Yoshman:

C++ standarden säger endast detta om char, short int, int och long int:

  • long int kan hålla minst lika stort tal som int

  • int kan hålla minst lika stort tal som short int

  • char kan hålla minst lika stort tal som short int

D.v.s. den garanti som finns är sizeof(char) <= sizeof(short int) <= sizeof(int) <= sizeof(long int)

Standarden säger också att sizeof(char) == 1. Så en fullt kompatibel implementation kan alltså ha long int där sizeof(long int) == 1!!! Tittar man på t.ex. 8-bitars AVR (används i de flesta Arduino-kort) och PIC så är sizeof(int) == 1 och kan därmed hålla tal -128..127.

Du ska använda int när du behöver hantera ett heltal som inte är jättestort, enda egentliga garanti du har är att int är av en storlek som är effektiv för underliggande arkitektur. Exakt hur stor dessa typer är bestäms både av CPU och OS. Jämför du Windows och Linux på x86_64 så är sizeof(long int) olika, den är 4 på Windows och 8 på Linux då 64-bitars Windows använder sig av en standard som kallas LLP64 (endast long long int och pekare är 64-bitars) medan Linux kör med LP64 (long int och pekare är 64-bitars). sizeof(int) är 4 både för IA32 (32-bitars x86) och x86_64, både i Windows och Linux.

Om du behöver en viss storlek använd standardtyperna för detta. __int64 är Windows-specifika och ska undvikas, standard C++ (och standard C) har idag intN_t och uintN_t där N är 8, 16, 32 eller 64. Så för att deklarera en heltalsvariabel som garanterat är 64 bitar, gör detta

#include <cstdint> ... int64_t myvar; ...

Okej, lite förvirrande med att allt ska vara olika.
Men har fått en bättre insikt nu hur det fungerar.

Tack för svar.

Speldator: [Intel Core i7 4790K] [ASUS Matrix GTX 780Ti x2] [ASUS MAXIMUS VII HERO] [Corsair Dominator Platinum 32GB] [Windows 7] [Logitech G400S] [Microsoft Ergonomic 4000] [BenQ XR3501 35" (HDMI)] [BenQ G900W 19" (VGA)]

Serverdator: [Intel Core i7 6850K] [ASUS X99-E WS] [Corsair Vengeance LPX 64GB] [2x Crucial MX300 1TB] [Cooler Master V1200] [CentOS 7]

Trädvy Permalänk
Medlem
Plats
Kristinehamn
Registrerad
Aug 2014
Skrivet av perost:

I C++ så är int garanterad att vara minst 16 bitar, medan en long är minst 32 bitar. Det är också garanterat att long är minst lika stor som int. Så int och long kan vara lika stora, men long kan också vara större. På mitt 64-bitars Linux-system så är t.ex. int 32 bitar och long 64 bitar. Du kan läsa mer om vilka regler som gäller för typerna här.

Om du vill ha en datatyp med en fast garanterad storlek så kan du inkludera cstdint och använda dessa datatyper. __int64 o.s.v. bör du undvika eftersom det är datatyper specifika för Microsofts C++-kompilator, och därmed inte standard C++.

Man behöver för övrigt inte skriva ut int när man använder short, long, signed eller unsigned. D.v.s. istället för unsigned int så räcker det att bara använda unsigned.

Skrivet av Yoshman:

C++ standarden säger endast detta om char, short int, int och long int:

  • long int kan hålla minst lika stort tal som int

  • int kan hålla minst lika stort tal som short int

  • char kan hålla minst lika stort tal som short int

D.v.s. den garanti som finns är sizeof(char) <= sizeof(short int) <= sizeof(int) <= sizeof(long int)

Standarden säger också att sizeof(char) == 1. Så en fullt kompatibel implementation kan alltså ha long int där sizeof(long int) == 1!!! Tittar man på t.ex. 8-bitars AVR (används i de flesta Arduino-kort) och PIC så är sizeof(int) == 1 och kan därmed hålla tal -128..127.

Du ska använda int när du behöver hantera ett heltal som inte är jättestort, enda egentliga garanti du har är att int är av en storlek som är effektiv för underliggande arkitektur. Exakt hur stor dessa typer är bestäms både av CPU och OS. Jämför du Windows och Linux på x86_64 så är sizeof(long int) olika, den är 4 på Windows och 8 på Linux då 64-bitars Windows använder sig av en standard som kallas LLP64 (endast long long int och pekare är 64-bitars) medan Linux kör med LP64 (long int och pekare är 64-bitars). sizeof(int) är 4 både för IA32 (32-bitars x86) och x86_64, både i Windows och Linux.

Om du behöver en viss storlek använd standardtyperna för detta. __int64 är Windows-specifika och ska undvikas, standard C++ (och standard C) har idag intN_t och uintN_t där N är 8, 16, 32 eller 64. Så för att deklarera en heltalsvariabel som garanterat är 64 bitar, gör detta

#include <cstdint> ... int64_t myvar; ...

Tack för korrigeringen, var (u)intN_t jag egentligen var ute efter.

Kör Linux - Yes! We are the 2 percent! And growing... Föreslå inte ens något Windows-exklusivt om jag inte specifikt frågar efter något till Win.
2600K - 18GB RAM - 1TB HDD - 64GB SSD - GTX 650 Ti Boost
Minnesvärda trådar: 1, 2