srand (time (null)) вызывает предупреждение компилятора: неявное преобразование теряет целочисленную точность

извинения, если этот вопрос уже был дан ответ.

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

using namespace std;

int main () {

srand( time(NULL) );
cout << rand();
}

"неявное преобразование теряет целочисленную точность:' time_t '(он же 'long') в 'unsigned int'"

это сообщение об ошибке Im, получаемое при выполнении кода выше. Я использую xcode 4.6.1. Теперь, когда я использую другой complier, такой как один из codepad.org он отлично работает, генерируя то, что кажется случайными числами, поэтому я предполагаю, что это проблема xcode, которую мне нужно работать вокруг?

Я только начал программировать, поэтому я полный новичок, когда дело доходит до этого. Есть ли проблема с моим кодом или это мой компилятор?

любая помощь будет оценили!

5 ответов


"неявное преобразование теряет целочисленную точность:' time_t '(он же 'long') в 'unsigned int'"

вы теряете точность неявно, потому что time() возвращает long который больше, чем unsigned int на вашей цели. Чтобы обойти эту проблему, вы должны явно привести результат (таким образом, удалив "неявную потерю точности"):

srand( static_cast<unsigned int>(time(NULL)));

учитывая, что сейчас 2017 год, я редактирую этот вопрос, чтобы предложить вам рассмотрим функции, предоставляемые std::chrono::* определена в <chrono> как часть C++11. Ваш любимый компилятор предоставляет C++11? Если нет, то так и должно быть!

чтобы получить текущее время, вы должны использовать:

#include <chrono>

void f() {
    const std::chrono::time_point current_time = std::chrono::system_clock::now();
}

зачем мне беспокоиться об этом, когда time() работает?

IMO, достаточно одной причины: четкие, явные типы. Когда вы имеете дело с большими программами среди достаточно больших команд, зная, представляют ли передаваемые значения интервалы времени или "абсолютные" времена, и какие величины являются критическими. С std::chrono вы можете проектировать интерфейсы и структуры данных, которые являются портативными и пропустить блюз is-that-timeout-a-deadline-or-milliseconds-from-now-or-wait-was-it-seconds.


как упоминалось в "nio", чистым обходным путем было бы явно ввести приведение.

более глубокое объяснение:

srand () требует в качестве параметра unsigned int (srand(unsigned int)) но time () возвращает длинный int (long int time()) и это не принимается srand (), поэтому, чтобы исправить это, компилятор должен просто typecast (преобразовать) "long int" в "unsigned int".

но в вашем случае компилятор предупреждает вас об этом (как разработчики компилятор думал, что вы должны знать, что все).

Так простой

srand( (unsigned int) time(NULL) );

будет делать трюк!

(простите меня, если я сделал что-то не так, это мой первый ответ на StackOverflow)


функция srand имеет unsigned int в качестве типа аргумента, time_t-длинный тип. верхние 4 байта из long удаляются, но в этом нет никаких проблем. srand рандомизирует алгоритм rand с 4 более низкими байтами времени, поэтому вы предоставляете больше данных, чем необходимо.

Если вы получаете ошибку, попробуйте просто явно привести тип time_t к unsigned int:

srand( (unsigned int) time(NULL) );

еще одна интересная вещь заключается в том, что если вы запустите свою программу дважды в одну и ту же секунду, вы получите одно и то же случайное число, которое иногда нежелательно, потому что если вы засеете алгоритм rand теми же данными, он будет генерировать ту же случайную последовательность. Или это может быть желательно, когда вы отлаживаете какой-то фрагмент кода и вам нужно снова проверить то же поведение... тогда вы просто используете что-то вроде srand(123456)


Это не ошибка. Код действителен и его значение четко определено; если компилятор отказывается его компилировать, компилятор не соответствует определению языка. Скорее всего, это предупреждение, и это говорит вам, что автор компилятора думает, что вы могли сделать ошибку. Если вы настаиваете на устранении предупреждающих сообщений, вы можете добавить приведение, как предлагали другие. Я не большой поклонник переписывания действительного, значимого кода, чтобы удовлетворить некоторое представление компилятора о хорошем стиле; я бы отключил предупреждение. Если вы это сделаете, вы можете пропустить другие места, где преобразование теряет данные, которые вы не намеревались.


#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;
}