Srand (time (null)) вызывает предупреждение компилятора: неявное преобразование теряет целую точность
Извиняется, если на этот вопрос уже был дан ответ.
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main () {
srand( time(NULL) );
cout << rand();
}
"неявное преобразование теряет целую точность: 'time_t' (aka 'long') до 'unsigned int'
Является ли сообщение об ошибке Im получающим, когда я выполняю приведенный выше код. Я использую xcode 4.6.1. Теперь, когда я использую другой компилятор, например, код codepad.org, он отлично выполняет генерацию, что похоже на случайные числа, поэтому я предполагаю, что это проблема xcode, с которой мне нужно работать?
У меня JUST началось программирование, поэтому я начинаю начинать, когда дело доходит до этого. Есть ли проблема с моим кодом или это мой комплимент?
Любая помощь будет оценена!
Ответы
Ответ 1
"неявное преобразование теряет целую точность: 'time_t' (aka 'long') до 'unsigned int'
Вы теряете точность неявно, потому что time()
возвращает long
, который больше, чем unsigned int
для вашей цели. Чтобы обойти эту проблему, вы должны явно указать результат (таким образом удалив "неявную потерю точности" ):
srand( static_cast<unsigned int>(time(NULL)));
Учитывая, что сейчас 2017, я редактирую этот вопрос, предлагая рассмотреть функции, предоставленные std::chrono::*
, определенные в <chrono>
, как часть С++ 11. Ваш любимый компилятор предоставляет С++ 11? Если нет, это действительно должно быть!
Чтобы получить текущее время, вы должны использовать:
#include <chrono>
void f() {
const std::chrono::time_point current_time = std::chrono::system_clock::now();
}
Зачем мне это беспокоиться, когда time()
работает?
IMO, достаточно одной причины: ясных, явных типов. Когда вы имеете дело с большими программами среди достаточно больших команд, зная, проходят ли значения, представляющие временные интервалы или "абсолютные" времена, и какие величины являются критическими. С помощью std::chrono
вы можете проектировать интерфейсы и структуры данных, которые переносимы и пропускать сингл "time-out-a-deadline-or-milliseconds-from-now-or-wait-was-it-seconds".
Ответ 2
Как упоминалось в "nio", чистым обходным решением было бы явно ввести приведение в действие.
Более глубокое объяснение:
Для srand() требуется unsigned int как параметр (srand(unsigned int)
), но time() возвращает long int (long int time()
), и это не принимается srand(), поэтому, чтобы исправить это, компилятор должен просто typecast (преобразовать) "long int" в "unsigned int".
НО в вашем случае компилятор предупреждает вас об этом вместо этого (поскольку разработчики компилятора думали, что вы должны знать, что все).
Итак, простой
srand( (unsigned int) time(NULL) );
сделает трюк!
(простите, если я сделал что-то не так, это мой первый ответ на stackoverflow)
Ответ 3
Функция srand имеет unsigned int как тип аргумента, time_t - длинный тип. верхние 4 байта от длинны удаляются, но в этом нет проблем.
srand будет рандомизировать алгоритм rand с 4 младшими байтами времени, поэтому вы поставляете больше данных, чем требуется.
если вы получили сообщение об ошибке, попробуйте явно указать тип time_t в unsigned int:
srand( (unsigned int) time(NULL) );
Еще одна интересная вещь: если вы запустите свою программу дважды за одну секунду, вы получите одно и то же случайное число, которое иногда может быть нежелательным, потому что, если вы засеваете алгоритм rand с теми же данными, он будет генерировать одна и та же случайная последовательность. Или это может быть желательно, когда вы отлаживаете часть кода и вам нужно снова проверить одно и то же поведение... тогда вы просто используете что-то вроде srand(123456)
Ответ 4
Это не ошибка. Код действителен и его значение четко определено; если компилятор отказывается компилировать его, компилятор не соответствует определению языка. Скорее всего, это предупреждение, и это говорит вам, что автор компилятора считает, что вы допустили ошибку. Если вы настаиваете на устранении предупреждающих сообщений, вы можете добавить бросок, как предложили другие. Я не большой поклонник переписывания действительного, содержательного кода, чтобы удовлетворить некоторое представление о хорошем стиле писателя компилятора; Я бы отключил предупреждение. Однако, если вы это сделаете, вы можете упустить другие места, где конверсия теряет данные, которые вы не намеревались.
Ответ 5
#include <stdlib.h>
#include <iostream> //rand
#include <time.h> //time
float randomizer(int VarMin, int VarMax){
srand((unsigned)time(NULL));
int range = (VarMax - VarMin);
float rnd = VarMin + float(range*(rand()/(RAND_MAX + 1.0)));
return rnd;
}