Trädvy Permalänk
Medlem
Registrerad
Mar 2017

Slumpgenerator C++

Hej,

Jag är ny inom programmering och skall skapa en slumgenerator men får gult felmeddelande.
Förstår inte varför, kan någon förklara?

Felmeddelandet är vid: srand(time(0));

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

int main()
{

srand(time(0));

for (int x = 1; x < 25; x++) {
cout << rand()%2 << endl;
}

}

Trädvy Permalänk
Medlem
Plats
Göteborg
Registrerad
Maj 2012

Pröva "srand(time(NULL))" istället, bör lösa problemet!

Main i7 7700k - msi Z170 Krait Gaming - msi GTX 1080 FE - Corsair LPX 16GB 2800 mhz - 2x intel 530 240GB [RAID 0] - be quiet! Straight Power e9 680w - Asus Xonar Essence STX - H100i

Laptop MacBook Air 13" early 2014

Kringutrustning Acer XB271HU - HHKB Professional 2 Purple Sliders - Realforce 88UB - IBM model M - Logitech G400 - Beyerdynamic DT-770 PRO 80Ω - Sennheiser HD6xx - Woo Audio WA6 - Blue Snowball

Trädvy Permalänk
Medlem
Plats
Härnösand
Registrerad
Jan 2016

Prova något i stil med.

#include<iostream>
#include<cstdlib>
#include<ctime>
using namespace std;

int main () {
int x;
int const slagg = 60000;
int const sexa = 6;
int sexor = 0;

srand(time(0)); // skulle också kunna köra NULL istället än 0.

for (int slaag=0; slaag<slagg; slaag++){
x = rand() % 6 + 1;
if (x == sexa)
sexor++;
}
cout << sexor << endl;
system("PAUSE");
}

Trädvy Permalänk
Medlem
Plats
Jämtland
Registrerad
Aug 2009

@apan82ful:
Föreslår att du kikar på dessa:
http://www.cplusplus.com/reference/cstdlib/rand/
http://www.cplusplus.com/reference/cstdlib/srand/
http://www.cplusplus.com/reference/ctime/time/

Nu var det jättelänge sen jag programmerade överhuvudtaget, men vill minnas att srand ändrar vad rand börjar på för siffra. Som du kan läsa där så kallas det "seed".
Om du bara kör rand funktionen så skulle du få samma följd av siffror varje gång.
Genom att använda srand(time(NULL)); så ändrar du seeden till vad tiden är just nu, skulle du köra programmet exakt samma tid två gånger, dvs om du ändrar klockan på datorn och lyckas göra den exakt samtidigt, så skulle du få samma resultat två gånger.
Någon får gärna rätt mig om jag har fel, men så jag minns det iaf.

*Citera för svar*
Work smart, not hard.

Trädvy Permalänk
Medlem
Registrerad
Mar 2017

Jag prövade båda sätten men det blir samma felmeddelande, allt fungerar som det skall ändå.
Det står: implicit conversation loses integer precision: 'time_t' (aka 'long') to 'unsigned int'

unsigned in menas väl att jag måste skapa en variabel som tillhör srand?

Trädvy Permalänk
Medlem
Registrerad
Mar 2017

@Purrfected:
Vad jag har förstått så är det först när jag skriver in time 0 som den börjar gå på klockan. annars om det bara står srand ock ett nr så får man samma resultat varje gång.
Som den är nu så fungerar den och slumpar olika tal varje gång jag kör den men dock med ett felmeddelande!

Trädvy Permalänk
Medlem
Plats
Linköping
Registrerad
Jun 2007
Skrivet av apan82ful:

Jag prövade båda sätten men det blir samma felmeddelande, allt fungerar som det skall ändå.
Det står: implicit conversation loses integer precision: 'time_t' (aka 'long') to 'unsigned int'

unsigned in menas väl att jag måste skapa en variabel som tillhör srand?

Problemet är att time() returnerar en long medan srand() förväntar sig en int, och på plattformen du kör så är long större än en int. Detta betyder att värdet som time() returnerar implicit kommer trunkeras, vilket kompilatorn ger en varning för. I just det här fallet spelar det ju ingen roll eftersom du bara vill ha ett värde att seeda med, men för att bli av med varningen så måste du göra konverteringen explicit:

srand(static_cast<unsigned int>(time(0))); // Eller om du använder modern C++, använd hellre: srand(static_cast<unsigned int>(time(nullptr)));

NULL som en del rekommenderade istället för 0 är en gammal relik från C, som för det mesta är definierad till just 0. Det kan leda till en del problem, eftersom 0 kan betyda både talet 0 eller en null-pekare. I C++11 så infördes därför nullptr istället, som endast har värdet av en null-pekare. Kompilatorn du använder bör ha stöd för C++11 om den är någorlunda modern, men ibland kan man behöva slå på det.

rand() och srand() är för övrigt också gamla C-funktioner, och rand() är oftast rätt dålig på att vara slumpmässig. I C++11 så introducerades en massa nya slumpgeneratorer i random. De fungerar genom att man använder en generator tillsammans med en distribution för att få ut slumptal som beter sig som man önskar. T.ex.:

#include <iostream> #include <random> int main() { std::default_random_engine generator; // Använd standard-generatorn, troligtvis samma som rand() std::uniform_int_distribution<int> distribution(1, 6); // En distribution som ger slumptal mellan 1 och 6. std::cout << "Die roll: " << distribution(generator) << std::endl; }

Fördelen med detta är att man kan välja en generator enligt önskad slumpmässighet och prestanda, samt en distribution som ger slumptal med den fördelning man önskar. I ditt exempel med rand() % 2 så skulle man istället t.ex. kunna använda bernoulli_distribution med p = 0.5, som då returnerar true eller false med samma sannolikhet.

Trädvy Permalänk
Medlem
Registrerad
Mar 2017

@perost:

Toppen! Tack!