Vinnaren i pepparkakshustävlingen!
  • 2
  • 3
2020-01-20, 06:16
  #25
Medlem
Citat:
Ursprungligen postat av grabb1948
Vissa beräkningar beror helt på ordningen de utförs i.
int a= 10*1/3.
Om nu 1 delas med 3 får man heltalet 0 som ger a= 10*0=0.
Däremot ger 10*1 =10 som ger a= 3 efter division.
Detta "problem" fixas vid optimering men troligen även vid "out of order".

Med parenteser så kan du få kompilatorn att ta en annan ordning, den innersta parentesen brukar tas först, operatorn * och / går före + och minus. Se dokumentationen om operandernas ordning
Citera
2020-12-04, 04:25
  #26
Medlem
Bumpar tråden:
Citat:
Ursprungligen postat av SittFint
Kompilatorn är fri att spotta ur sig vilken maskinkod som helst så länge dess observerbara beteende inte förändras. Det inkluderar att ta bort död kod. Och om din kod innehåller något som är UB så får den spotta ur sig exakt vad som helst.
UB =Undefined Behaviour, Odefinierat Beteende. Japp vi hade en diskussion för riktigt många år sedan med tex Bjarne Stroustrup och Linus Torvalds. Och slutsatsen av den diskussionen var att det går inte attt skriva en kompilator som både ska klara av att kompilera korrekt kod, och som dessutom kan lära en newbie att programmera. Det går inte att utifrån de möjliga kombinationer av kod som "ser bra ut" men som är felaktig, att dessutom kunna designa ett varnings/error-meddelande som gör att newbies förstår vilket fel de gör.
Inte minst gäller detta tex deklarationen av templates, vilket blir extra konstig felutskrift pga att headerfilerna är uppbyggda som de är. Om man tex har skrivit initieringsdeklarationen felaktigt.

Således så låter tesen som så att är koden felaktigt skriven så får kompilatorn spotta ur sig vad som helst. Ett tag så pågick det tävlingar i att skriva så genomusel C-kod att datorn och kompilatorn skulle gå bananas, och den som fick de flesta felutskrifterna vann. De andra fick bjuda på öl förstås.
Både kompilatorn skulle gå bananas helst och även när koden kördes sedan.
Dessa "experiment" kördes förstås på virtuella maskiner så man enkelt kunde terminera dem.

Annars så kunde de ju dra ner hela OSet i ett slags "koma" ett katatoniskt tillstånd. Men då blev ju risken stor för förlust av filer, dvs de flushades inte, och stängdes inte korrekt.
Mycket av POSIX-standarden går ut på att undvika sådana tillstånd. Men var man tillräckligt kreativ på jävelskap så gick det ibland ändå, hehe

Vi lyckades vid något tillfälle få en kompilator att riktigt gå bananas, i en oändlig loop. Och den buggen vart rättad, förstås. Minns dock ej riktigt hur det var, men kompilatorn förväntade sig att hitta ett radslut i main, vilket jag på rent jävelskap hade tagit bort. En annan gång tvingade vi fram en oändlig rekursion pga att kompilatorn med nästlade #if och #includes fastnade i en sådan loop.
Nu tror jag att alla väldesignade kompilatorer terminerar sådana loopar själv. Längesedan jag testade.
Citat:
Ursprungligen postat av DieTrolle
Jag förstår inte riktigt vad du håller på med. Du skriver felaktig kod och sedan försöker du dra slutsatser av resultatet som många gånger blir odefinierat p g a den felaktiga koden... Ibland så går koden att köra då kompilatorn optimerat bort buggarna. Känns bara snurrigt. Kanske du borde lära dig att skriva korrekt kod istället för att slösa bort din tid på dessa i mitt tycke rena strunttesterna.
Mer till din fråga
Kod:
    w= b/z6;
a må vara känt men det är inte z6...
Koden är ju i princip undefined eftersom flera variabler i din kod är odefinierade vid start. Med odefinierad menar jag att enligt C/C++ standarden inte automatiskt initierar nya variabler till noll. Utan de kan innehålla vilka värden som helst. Du måste alltså se till att explicit (= uttryckligen) definiera varje variabel till ett känt värde.
Undantaget utgör globala variabler som brukar initieras till noll ,även om du inte ger dem något värde (beror dock på vilken utgåva av C-kompilator, och vilket OS som körs, vet ej hur det ligger till med de tidiga C++, detta beror på att man tog lätt på uttrycket "standard" i standard C, det kunde alltså vara lite hur som helst med sådant).

Varje körning kan därmed i princip bli mycket olika, så frågan om olika typer av optimeringar saknar (nästan) betydelse.

Vid sådana jämförelser så bör man ha en grundförutsättning, grundkonfiguration att utgå ifrån.
Som man sedan jämför med i de olika utfallen.
Det blir i regel ett stort antal variabler i kringmiljön att ta hänsyn till.
På tex en vanlig Windows PC snurrar ett stort antal systemprocesser samtidigt med att CPU-load varierar kraftigt från tillfälle till tillfälle.
Så man bör se till att man har en relativt "ren maskin" att utgå ifrån.
PCn är liksom en ganska lömsk miljö på det viset att du har ingen som helst kontroll över hur mycket CPU-load dina systemprocesser och andra program tar från tillfälle till tillfälle.
Och därför kan mätvärdena bli rejält "skeva" eller "tiltade"(*).
Man skulle kanske kunna tro att genom att köra programmet genom debuggern/profilern så skulle man få ett rättvist mätvärde, men debuggern ger ingen garanti den heller.

Vill man ha något riktigt rättvisande så måste man köra sina testprogram i virtuella maskiner som kontrolleras extra noggrant. Men mätvärdet ska då egentligen ges i CPU-cykler.

Ett tips dock, float defaultar (= förutbestäms) i vissa (nu nästan alla) miljöer till att räkna doubles istället för float. Detta eftersom (32-bit) float har otillräcklig precision för de allra flesta ändamål.
Därför bör man deklarera alla floats som doubles.
Men för tex grafik så används (32-bit) floats frekvent, och duger bra till det.
Double står för double precision och är definitionsmässigt 64-bits, men internt på alla Intel x86 av senare modell räknar internt med 80-bits (extended) precision.

Frågan om optimering är lönsamt eller inte går inte att avgöra utifrån koden som sådan.
Det går bara att testa sig fram.
Den första optimeringen man genomförde hos digitala maskiner var att införa extra register som man kunde lagra mellanresultat i tex en uträkning i.
Och en lång uträkning med många tecken och parenteser körs ibland baklänges, dvs de sista uttrycket körs först.
Eller ibland körs det "innersta uttrycket" först, dvs i typ i ett långt uttryck med parenteser.
Närapå all optimering utgick från de principerna som har med uträkningar att göra.
Många bibliotek tex math.h kan ha en massa extra hjälpvariabler inne i biblioteket.
Och tex i trigonometrin så kan man köra med tabelluppslagning istället, beroende på vilken noggrannhet man eftersträvar.

Det här snacket om att optimera hit och dit, det är så mycket programmerarna tar för självklart idag. Tex begreppen heap och stack fanns inte för riktigt länge sedan. Programmen man skrev hade alltså inte tillgång till dessa, pga att minnesutrymmet var så in i helvete litet. Utan man fick i stort sett skriva det från scratch, och pilla med de register som fanns.
En hel del av de registerna de återanvändes då till en mängd ändamål.
Därför så såg koden i regel rent för jävlig ut, typ oläslig.

C-språket var så att säga nydanande eftersom det förutsatte att heap och stack fanns från början, och att det var operativsystemet som fixade det. Programmeraren skulle vanligen inte behöva tänka på den petitessen.
Men det gjorde ibland att när man var tvungen att optimera koden bättre, man var tvungen att grotta ner sig i dessa detaljer. Till ren förbannelse för de programmerare som efter några år skulle lägga till nya funktioner och rätta buggar.

När man håller på med optimeringar och programmering så ska man alltid komma ihåg "att en kedja är aldrig starkare än sin svagaste länk". Och en hel massa hänsyn måste man ta när man närmar sig maximal prestanda. Tyvärr så är det inte alltid möjligt att förutse i förväg var taket finns någonstans. Utan det finns gott om programmeringsprojekt som avslutats i förtid pga att man kunde räkna ut i slutändan att prestandan inte räcker.

(*) Uttrycket tiltad, lutande kommer från då man spelade flipperspel, och det kunde man luta så att kulan, danken föll in i rätt fåra. Senare så satte tlllverkarna dit en sensor som lös "TILT", och stoppade poängräkningen.
Citera
2020-12-04, 09:52
  #27
Medlem
SittFints avatar
Citat:
Ursprungligen postat av NegerStryparen
Koden är ju i princip undefined eftersom flera variabler i din kod är odefinierade vid start. Med odefinierad menar jag att enligt C/C++ standarden inte automatiskt initierar nya variabler till noll. Utan de kan innehålla vilka värden som helst. Du måste alltså se till att explicit (= uttryckligen) definiera varje variabel till ett känt värde.
Undantaget utgör globala variabler som brukar initieras till noll ,även om du inte ger dem något värde (beror dock på vilken utgåva av C-kompilator, och vilket OS som körs, vet ej hur det ligger till med de tidiga C++, detta beror på att man tog lätt på uttrycket "standard" i standard C, det kunde alltså vara lite hur som helst med sådant).
Globala och statiska variabler initieras alltid till noll automatiskt om de inte initieras implicit. Har du något exempel på kompilatorer som inte gör det? Jag skulle gissa att du måste hitta en kompilator som antingen är väldigt gammal eller rätt obskyr i något avseende.

Citat:
Ett tips dock, float defaultar (= förutbestäms) i vissa (nu nästan alla) miljöer till att räkna doubles istället för float. Detta eftersom (32-bit) float har otillräcklig precision för de allra flesta ändamål.
Därför bör man deklarera alla floats som doubles.
Men för tex grafik så används (32-bit) floats frekvent, och duger bra till det.
Double står för double precision och är definitionsmässigt 64-bits, men internt på alla Intel x86 av senare modell räknar internt med 80-bits (extended) precision.
Nja, standarden ger minimikrav på dessa typer. En double är inte definierad till 64 bit. Det är minimikravet.

Citat:
C-språket var så att säga nydanande eftersom det förutsatte att heap och stack fanns från början, och att det var operativsystemet som fixade det.
Inte sant. Visserligen förutsätter C att malloc går att använda, men orden heap och stack förekommer inte överhuvudtaget i standarden.

Men bra, roligt och informativt inlägg i övrigt.
__________________
Senast redigerad av SittFint 2020-12-04 kl. 09:59.
Citera
2020-12-04, 10:43
  #28
Medlem
Min tanke från början var att hitta ett program som visar skillnaden mellan mina olika Raspberry Pi & Tinker Board eftersom vissa har "out of order" men andra saknar detta. Då visste jag inte att division går via software på ARM1176 så att detta dominerar för alla 32bitars Raspberry Pi (om man dividerar).
Nu har jag detta program:

Kod:
#include <ctime>
#include <iostream>
#include <math.h>
using namespace std;

int main()
{
  
  int  a=0, b=0, c=0, d=0, e=0, f=0, g=0, h=0, i=0, j=0, k=0, l=0, m=0, n=0;
  int  o=0, p=0, q=0, r=0, s=0, t=0, u=0, v=0, w=0, x=0, y=0, z=0;
  for (a=1; a<40; a++)
   {
      for (b=40; b>0; b--)
        {
          for (c=1; c<40; c++)
            {
             for (d=40; d>0; d--)
               {
                for (e=1; e<40; e++)
                  {
                   for (f=40; f>0; f--)
                     { 
                      if ((a==b)&& (b==c)) h=h+a*b;
                      if ((b==2*b) && (2*c==d)) k=k+e+a*f; 
                      if ((d==3*c) && (b==c)) g=g+a*b;
                      if ((c==6*d) && (b==4*a)) h=h+a*c; 
                      if ((c==5*d) && (b==5*a)) i=i+a*d; 
                      if ((e==f) && (10*b==a) && (b==c)) j=j+a*c; 
                      if ((c==5*d) && (e==3*f) && (b==2*c)) j=f+a*e; 
                      if ((c==d) && (e==f) && (b==c)) o=e+e*f; 
                      if ((c==10*d) && (e==2*f) && (b==c)) p=p+e*d; 
                      if ((a==d) && (e==f) && (b==c)) q=q+a*f; 
                     }
                 }
               }
            }
       }
   }
   
cout << "  a = " << a << "\n";
cout << "  b = " << b << "\n";
cout << "  c = " << c << "\n";
cout << "  d = " << d << "\n";
cout << "  e = " << e << "\n";
cout << "  f = " << f << "\n";
cout << "  g = " << g << "\n";
cout << "  h = " << h << "\n";
cout << "  i = " << i << "\n";
cout << "  j = " << j << "\n";
cout << "  k = " << k << "\n";

cout << "  o = " << o << "\n";
cout << "  p = " << p << "\n";
cout << "  q = " << q << "\n";

}
Om jag räknar om tidsåtgången(sekunder) med alla vid 1000 MHz får jag:
Cortex-A72(64bitar) no opt-> 104,9.... -O1-> 31,4....... -O2-> 35,0.....-O3->35,0
Cortex-A72(32bitar) no opt-> 112,2.... -O1-> 51,0....... -O2-> 46,8.....-O3->46,8
Cortex-A53(32bitar) no opt-> 283,2.... -O1->115,8...... -O2-> 103,6...-O3->103,6
Cortex-A17(32bitar) no opt-> 121,7.... -O1->55,4........ -O2-> 49,0.....-O3->49,0

Den enda som saknar "out of order" är Cortex-A53 och det märks!
Citera
2020-12-04, 12:22
  #29
Medlem
Ingen av mina X86 saknar "out of order" så där är det svårare att se effekten. Programmet verkar dock svårt nog för kompilatorn. Detta är x86_64 Goldmont Plus vid 2700 MHz:
no opt ->34,7
-O1->14,3
-O2->17,2
-O3->18,5
Lätta program brukar ge en stor vinst vid -O3 men inte här.
Citera
2021-02-02, 02:49
  #30
Medlem
Citat:
Ursprungligen postat av SittFint
Globala och statiska variabler initieras alltid till noll automatiskt om de inte initieras implicit. Har du något exempel på kompilatorer som inte gör det? Jag skulle gissa att du måste hitta en kompilator som antingen är väldigt gammal eller rätt obskyr i något avseende.


Nja, standarden ger minimikrav på dessa typer. En double är inte definierad till 64 bit. Det är minimikravet.

Inte sant. Visserligen förutsätter C att malloc går att använda, men orden heap och stack förekommer inte överhuvudtaget i standarden.

Men bra, roligt och informativt inlägg i övrigt.

Nej, inga aktuella men det fanns för längesedan, utgåvor av C-kompilatorer som var betaversioner som hade en hel del konstigheter för sig.

Hehe, sedan fanns det på äldre maskiner problemet med att "kretsarna drev". Ja de överhettades så att bittarna kunde skifta läge, typ, eller det var något annat elektriskt fenomen, minns ej så noga.
Det fanns inte temperatursensorer på alla kretskort i maskinen så var det för varmt i lokalen där maskinen stod, så kunde kretsarna börja "driva".
Man kunde framkalla ett liknande tillstånd på LED-kalkylatorer, med att sänka drivspänningen. Plötsligt så hamnade kretsarna i ett instabilt läge. Eller höja drivspänningen för mycket.
Detta blev ett större problem ju större minneskretsarna blev och man införde sk ECC, som är en slags kontrollsiffra som garanterar att en byte är intakt i dess innehåll. Blev ju allt viktigare för tex kretsar som skulle sitta i satelliter. Där strålningen är en okänd faktor, och kunde korrumpera data.

Kompilatorn som sådan förutsätter ju numera alltid att den ska kunna i startsekvensen av ett valfritt exe kunna allokera både tillräckligt med heap och stack. Men det är riktigt att begreppen inte är nödvändig för språket C som sådant. Men det underlättar betydligt att de finns.
Skulle ju vara rent löjligt att skriva en kompilator som kunde klara sig utan, det funkar ju inte alls.
Ja i och för sig då att main() blev tvungen att bli en enda stor monolith utan ett enda funktionsanrop, eller komplicerad uträkning.

Citat:
Ursprungligen postat av grabb1948
Min tanke från början var att hitta ett program som visar skillnaden mellan mina olika Raspberry Pi & Tinker Board eftersom vissa har "out of order" men andra saknar detta. Då visste jag inte att division går via software på ARM1176 så att detta dominerar för alla 32bitars Raspberry Pi (om man dividerar).
Nu har jag detta program:

Kod:
#include <ctime>
#include <iostream>
#include <math.h>
using namespace std;

int main()
{
  
  int  a=0, b=0, c=0, d=0, e=0, f=0, g=0, h=0, i=0, j=0, k=0, l=0, m=0, n=0;
  int  o=0, p=0, q=0, r=0, s=0, t=0, u=0, v=0, w=0, x=0, y=0, z=0;
  for (a=1; a<40; a++)
   {
      for (b=40; b>0; b--)
        {
          for (c=1; c<40; c++)
            {
             for (d=40; d>0; d--)
               {
                for (e=1; e<40; e++)
                  {
                   for (f=40; f>0; f--)
                     { 
                      if ((a==b)&& (b==c)) h=h+a*b;
                      if ((b==2*b) && (2*c==d)) k=k+e+a*f; 
                      if ((d==3*c) && (b==c)) g=g+a*b;
                      if ((c==6*d) && (b==4*a)) h=h+a*c; 
                      if ((c==5*d) && (b==5*a)) i=i+a*d; 
                      if ((e==f) && (10*b==a) && (b==c)) j=j+a*c; 
                      if ((c==5*d) && (e==3*f) && (b==2*c)) j=f+a*e; 
                      if ((c==d) && (e==f) && (b==c)) o=e+e*f; 
                      if ((c==10*d) && (e==2*f) && (b==c)) p=p+e*d; 
                      if ((a==d) && (e==f) && (b==c)) q=q+a*f; 
                     }
                 }
               }
            }
       }
   }
   
cout << "  a = " << a << "\n";
cout << "  b = " << b << "\n";
cout << "  c = " << c << "\n";
cout << "  d = " << d << "\n";
cout << "  e = " << e << "\n";
cout << "  f = " << f << "\n";
cout << "  g = " << g << "\n";
cout << "  h = " << h << "\n";
cout << "  i = " << i << "\n";
cout << "  j = " << j << "\n";
cout << "  k = " << k << "\n";

cout << "  o = " << o << "\n";
cout << "  p = " << p << "\n";
cout << "  q = " << q << "\n";

}
Om jag räknar om tidsåtgången(sekunder) med alla vid 1000 MHz får jag:
Cortex-A72(64bitar) no opt-> 104,9.... -O1-> 31,4....... -O2-> 35,0.....-O3->35,0
Cortex-A72(32bitar) no opt-> 112,2.... -O1-> 51,0....... -O2-> 46,8.....-O3->46,8
Cortex-A53(32bitar) no opt-> 283,2.... -O1->115,8...... -O2-> 103,6...-O3->103,6
Cortex-A17(32bitar) no opt-> 121,7.... -O1->55,4........ -O2-> 49,0.....-O3->49,0

Den enda som saknar "out of order" är Cortex-A53 och det märks!

Citat:
Ursprungligen postat av grabb1948
Ingen av mina X86 saknar "out of order" så där är det svårare att se effekten. Programmet verkar dock svårt nog för kompilatorn. Detta är x86_64 Goldmont Plus vid 2700 MHz:
no opt ->34,7
-O1->14,3
-O2->17,2
-O3->18,5
Lätta program brukar ge en stor vinst vid -O3 men inte här.

Beroende på utgåvor av dels kompilator och dels deras associerade libs och headers så är ju utgången av olika optimeringar liiite svårt att jämföra. Och jämföras efter vad?
Man måste ju identifiera ett slags standardtillstånd som man jämför med.
Förr några år sedan var L1-cachens storlek av stor betydelse för hur fort ett program snurrade om det var ett stort program alltså. Ifall att cache-missar inträffade frekvent, dvs CPUn var tvungen att hämta data från det långsammare DDR3 RAM, så syntes det tydligt på tidsåtgången.
Idag är cacharna större och DDR4 betydligt snabbare och därför är den flaskhalsen mer eller mindre borta.

Tankeexempel: Antag att du har en kompilator med många fler optimeringsmöjligheter, den kompilatorn kunde rentav räkna igenom din loop och förstå att resultatet alltid är deterministiskt, och ger samma output för varje körning, här är resultatet av din kods körning, Linux gcc:

Citat:
noname@noname-HP-EliteBook-9470m:~/MyProjectsC_CPP/MyProject011/bin/Debug$ ls
MyProject011
noname@noname-HP-EliteBook-9470m:~/MyProject011/bin/Debug$ MyProject011
MyProject011: command not found
noname@noname-HP-EliteBook-9470m:~/MyProject011/bin/Debug$ ./MyProject011
a = 40
b = 0
c = 40
d = 0
e = 40
f = 0
g = 110728800
h = 1292506800
i = 1572480
j = 1534
k = 0
o = 1560
p = 88920
q = 23727600
noname@noname-HP-EliteBook-9470m:~/MyProject011/bin/Debug$


Så skulle din kompilator kunna opitimera din kod till det här istället, förutsatt att den var
tillräckligt klyftig, eller hur:
Kod:
#include <ctime>
#include <iostream>
#include <math.h>
using namespace std;

int main()
{
cout << "  a = " << (int)  40 << "\n";
cout << "  b = " << (int)    0 << "\n";
cout << "  c = " <<  (int) 40 << "\n";
cout << "  d = " << (int)    0 << "\n";
cout << "  e = " << (int)  40 << "\n";
cout << "  f = " << (int)    0 << "\n";
cout << "  g = " << (int) 110728800 << "\n";
cout << "  h = " << (int) 1292506800 << "\n";
cout << "  i = " << (int)  1572480 << "\n";
cout << "  j = " << (int)  1534 << "\n";
cout << "  k = " << (int)   0 << "\n";

cout << "  o = " << (int) 1560 << "\n";
cout << "  p = " << (int) 88920 << "\n";
cout << "  q = " << (int) 23727600 << "\n";
}

(Jag satt dit casting operatorn (int) för att markera att det är en int som ska presenteras. Flashback saknar ju syntax highlightning med färger så man kan ju tro att man menar något annat än en int.)

De olika optimeringsalternativen är inte standardiserade så det går inte i förväg att räkna ut att en viss kod ska rulla tex 15% snabbare med en viss optimering.
För att kunna jämföra så brukar man definiera någon slags standardkod som körs i en tänkt standardmaskin.
Om man ska jämföra olika optimeringsmetoder och kodningsmetoder så kan det vara bra att köra koden i en virtuell maskin där man aktivt väljer en viss lägre hastighet, och sedan kör man alla optimeringsswitchar i denna virtuella maskin och jämför.
Det är ett snårigt område. Och lätt att röra till det
Många nya kretslösningar och tex grafikort körs i emulerat virtuellt miljö i proffsens utvecklingsmiljöer för att ge ungefärliga fingervisningar om den utlovad prestandaökningen som kan ligga inom räckhåll.

Den lägre hastigheten i den virtuella maskinen jämfört med värdmaskinens hastighet är som att köra med bromsen åtdragen, men ger jämna och fina men framförallt jämförbara värden. Oberoende av om värdmaskinen är 50 eller 90% belastad för tillfället.

Och används gärna för tidskritiska kodsnuttar tex device drívers, kernel daemons mm.
Lättara att beskriva i diagram och liknande, än i ren text. Lite svårt att lära ut bara så här.
Hoppas ni förstår principen i alla fall. Lycka Till !!!
Citera
2021-02-02, 09:49
  #31
Medlem
kaks avatar
Citat:
Ursprungligen postat av NegerStryparen
(Jag satt dit casting operatorn (int) för att markera att det är en int som ska presenteras. Flashback saknar ju syntax highlightning med färger så man kan ju tro att man menar något annat än en int.)

Kod:
#include <ctime>
#include <iostream>
#include <math.h>
using namespace std;

int main()
{
cout << "  a = " << (int)  40 << "\n";
cout << "  b = " << (int)    << "\n";
cout << "  c = " <<  (int) 40 << "\n";
cout << "  d = " << (int)    << "\n";
cout << "  e = " << (int)  40 << "\n";
cout << "  f = " << (int)    << "\n";
cout << "  g = " << (int) 110728800 << "\n";
cout << "  h = " << (int) 1292506800 << "\n";
cout << "  i = " << (int)  1572480 << "\n";
cout << "  j = " << (int)  1534 << "\n";
cout << "  k = " << (int)   << "\n";

cout << "  o = " << (int) 1560 << "\n";
cout << "  p = " << (int) 88920 << "\n";
cout << "  q = " << (int) 23727600 << "\n";

Citera
2021-02-02, 11:54
  #32
Medlem
Citat:
Ursprungligen postat av kak
Kod:
#include <ctime>
#include <iostream>
#include <math.h>
using namespace std;

int main()
{
cout << "  a = " << (int)  40 << "\n";
cout << "  b = " << (int)    << "\n";
cout << "  c = " <<  (int) 40 << "\n";
cout << "  d = " << (int)    << "\n";
cout << "  e = " << (int)  40 << "\n";
cout << "  f = " << (int)    << "\n";
cout << "  g = " << (int) 110728800 << "\n";
cout << "  h = " << (int) 1292506800 << "\n";
cout << "  i = " << (int)  1572480 << "\n";
cout << "  j = " << (int)  1534 << "\n";
cout << "  k = " << (int)   << "\n";

cout << "  o = " << (int) 1560 << "\n";
cout << "  p = " << (int) 88920 << "\n";
cout << "  q = " << (int) 23727600 << "\n";

Haha ! Snyggt !! Tackar tackar
Sicken dum jävel man är Missade alternativet CODE/PHP, det dök inte upp inatt här nere i morsans källare. Med mina flaskbottnar till brillor och att gömma datorn under täcket så att morsan inte märker att jag skriver sådan här skit på Flashback, på nätterna. Så då blir det svårt med redigeringen-

- Tack på mig själv

Skulle ju stått typ
Kod:
cout << "  p = " << (int) 88920 << "\n"

Morsan har hotat med att hon ska hälla lim i tangentbordet, om jag inte går iväg och köper två paket Prince, två påsar chips, en sexpack folköl och två lådor lådvin nu på en gång så, det är bara att lyda nu.....
Castingsoperatorn (int) behövs ju inte men jag lade bara dit den dels för att läsaren ska förstå att det är en int med fast värde som skrivs ut, färgläggningen saknades ju.
Citera
  • 2
  • 3

Stöd Flashback

Flashback finansieras genom donationer från våra medlemmar och besökare. Det är med hjälp av dig vi kan fortsätta erbjuda en fri samhällsdebatt. Tack för ditt stöd!

Stöd Flashback