0

I am creating random numbers for my code and I am using the seeding method for the purpose of debugging. What I want to do is to store the return value of time(NULL) function which will be used by the srand() function. The value is to be stored in a log text file so that it can be used to analyze problems that occur in the code.

So how should I printf the exact value used as the seed in the srand function?

KulaDamian
  • 154
  • 2
  • 14
  • 1
    Unspecified. If it is POSIX, cast it to unsigned long long int. Note that `time_t` need not even be an *integer* in C, but POSIX requires this. – Antti Haapala -- Слава Україні Oct 02 '17 at 13:10
  • Store the result in the largest unsigned integer type supported by your system (usually a `uint64_t`) print it as such? That's the only way I could see this being in any way close to portable (considering that `time_t` *usually* is an integer type). The problem is that the actual type of `time_t` is implementation defined, it could be a floating point type, or even a structure. So the only *truly* portable way to print it, is as an actual textual date-time stamp. – Some programmer dude Oct 02 '17 at 13:11
  • OTOH, in any case you can convert the `time_t` value to `unsigned long long` *first*, and then use *that* value as the random seed – Antti Haapala -- Слава Україні Oct 02 '17 at 13:13
  • @AnttiHaapala I'm not entirely sure about that duplicate, because I smell an XY-Problem here, at least if I understand OPs intention correctly: to be able to reproduce a program run with "random" numbers in case something went wrong ... –  Oct 02 '17 at 13:20
  • @FelixPalmen what do you suggest then? rewrite the entire question so that it doesn't ask that :D I just remembered that `srand` eats unsigned int so perhaps just cast to `unsigned int` then. – Antti Haapala -- Слава Україні Oct 02 '17 at 13:26
  • @AnttiHaapala I agree the way it is asked makes it look like a dupe :) But yes, that would be my suggestion as well. There's just no need to store a `time_t` here... –  Oct 02 '17 at 13:27
  • @AnttiHaapala Well thanks, I hope I didn't misunderstand the intention behind the question ;) –  Oct 02 '17 at 13:33
  • 1
    I think you have an XY problem. If you want to have reproducable pseudo random generation, just chose a "random" but fixed value for the initialization and keep it. There is no point at all that this would be the return value of `time()`. – Jens Gustedt Oct 02 '17 at 13:47

2 Answers2

4

As already commented, time_t can be virtually anything, the description even changed with versions of the standard, so the only thing you know is that it is a number. I'd say the only portable way to write it to a file is to read the bytes of its representation and store them (*), e.g. in hex format, or directly as binary using fwrite(). For hex format, you could alias it with a char * and read the bytes by indexing from 0 to sizeof(time_t) - 1.

But then, you don't need the exact return value of time() for what you want to achieve, you only need the seed that was actually used! If you look at the srand() function, it takes an unsigned int. So just convert whatever time(NULL) returns to an unsigned int first and store that.

Note that the inner workings of the PRNG aren't specified in the standard either, so if you obtain a logfile from a user, there's no guarantee you can reproduce the same sequence of random numbers from it if he linked against a different C library.


(*) This of course is not portable at runtime between different implementations, as they will have different representations. I guess the question isn't about that, but for completeness, if you really want to store a time value, the way to go would be to store e.g. the components of a struct tm or use something like strftime().

  • `srand` initialization is not portable between platforms because the `rand` algorithm is unspecified and thus could differ. If you need consistent PRN sequences between platforms, you need to use a clearly specified algorithm, including a specified seeding procedure which will use a clearly-defined bitwidth for the seed. As you say, it doesn't matter what the source of the seed is; only the seed itself. – rici Oct 02 '17 at 15:14
  • @rici you did read my whole answer? I think I mentioned this issue as well :) –  Oct 02 '17 at 15:32
  • Looking carefully at your answer, no. I read and upvoted the original and then saw the last edit which I responded to. I missed the intermediate edit. Sorry. – rici Oct 02 '17 at 16:34
1

The function time() returns time_t type which can be any integer or real-floating type.

But you can cast it to a known type:

printf("%lld\n", (long long) time(NULL));

If you just want to store the binary time_t value in order to read it back later you could do:

Write:

time_t t = time(NULL);
/* ... open file handle */
fwrite(&t, sizeof(t), 1, file);

Read:

time_t t = 0;
/* ... open file handle */
fread(&t, sizeof(t), 1, file);

When doing this you have to make sure that wrting and reading is done by the same binary (or different binaries but same compiler).

arminb
  • 2,036
  • 3
  • 24
  • 43
  • But will the exact value (long long) time(NULL) be used in the srand function or will another value go in srand? Because I need to store the exact value of time(NULL) that will be used in srand(time(NULL))? – KulaDamian Oct 02 '17 at 13:15
  • See your own reference where a comment says "That assumes the platform supports (long long)." and another solution proposes `difftime` which is double. – Paul Ogilvie Oct 02 '17 at 13:16