Weird printf :\

Pages: 12
Hi everyone... I have code in three different files. I would like you to have a look at it.

MersenneTwister.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef MERSENNETWISTER_H
#define	MERSENNETWISTER_H

#include <stdlib.h>
#define SZ_STATE        624
#define KNUTH_MUL       1812433253

typedef unsigned long long UINT64;
typedef unsigned int       UINT32;
typedef unsigned short int UINT16;

UINT64 * initializeGenerator (UINT32);
UINT64   extractNumber(UINT16);
UINT64 * generateNumbers(UINT64 *);
UINT64 * randStream(UINT64);
UINT64   randNumber(UINT64);

#endif	/* MERSENNETWISTER_H */ 


MersenneTwister.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include "MersenneTwister.h"

/*-----------------------------------------------------------------------------
 Create a new generator state vector and fill it with Knuth's feedback shift
 register algorithm
-----------------------------------------------------------------------------*/
UINT64 * initializeGenerator (UINT32 Seed) {
    UINT64 * generatorState = NULL;                                             // Define placeholder for generator state
    if (!generatorState) {                                                      // Just checking...
        generatorState = (UINT64 *) malloc (SZ_STATE * sizeof(UINT64));         // Allocate memory
        if (!generatorState) return NULL;                                       // If not possible, return NULL to indicate FAILURE
    }
    
    generatorState[0] = (UINT64) Seed;                                          // Cast 32-bit seed to 64-bit placeholder and store
    UINT16 Count; for (Count=1; Count<SZ_STATE; Count++) {                     // From [1] to [623] fill state vector with Knuth's
        generatorState[Count] = 
                ((KNUTH_MUL * ((generatorState[Count-1]) ^ 
                ((generatorState[Count-1])>>30)) + Count) << 32) >> 32;         // Rotate MT[i-1] 30-right, XOR with MT[i-1], multiply
    }                                                                           // Knuth's multiplier, add i, truncate to 32-bits
    return generatorState;
}
unsigned long   ExtractNumber(unsigned short Index){
    
}
unsigned long * GenNumbers(unsigned long * currentState){
    
}
unsigned long * RandStream(unsigned long Seed){
    
}
unsigned long   RandNumber(void){
    
}


main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
#include <stdlib.h>
#include "MersenneTwister.h"

int main() {
    
    UINT64 *State;
    State = initializeGenerator(62742);
    
    UINT16 n; for(n=0;n<SZ_STATE;n++){
        printf("%u: %llx\n", n, State[n]);
    }
    return (EXIT_SUCCESS);
}


In case anyone is still wondering, I'm trying to write a very basic implementation of Mersenne Twister (http://en.wikipedia.org/wiki/Mersenne_twister). Now, the implementation is not complete, but the initializeGenerator was somewhat complete. So I thought I'd look at the state vector (an array of 64-bit integers) that it generates.

I'm compiling with gcc 4.6.3. It compiles fine. No errors, no warnings. When I execute it, the output is not right.

When I run it in GNOME terminal, it runs fine, output 624 number, one on each line. When I run it in Netbeans terminal, it sometimes runs 200 something times and exits with code 0 and sometimes runs 495 times and sticks, no indication of successful or unsuccessful exit.

It may be a bug in Netbeans, but I'm not sure I'm doing it right. Could you answer a few questions after having a look at the code?

- Why is the output not right in Netbeans terminal? Do you spot a serious blunder somewhere in there?
- If it indeed is a problem with Netbeans terminal, can you spot some examples of bad programming practice in my code? You know, something that may be unsafe or not recommended?
- How would you do it?


Thank you for your time, gentlemen.
closed account (o3hC5Di1)
Hi there,

I'm sorry to say that I'm not really able to answer your questions with a definite answer.

There is one small thing I noticed in your code though which I believe is generally advised against, so I thought I'd share it with you anyway.

The use of C libraries is considered "to be avoided" whenever possible.
In your case, I think it's possible to use manipulators on std::cout rather than printf.
You would use headerfile <iomanip>, instead of <stdio.h>.
For more information on manipulators: http://cplusplus.com/reference/iostream/manipulators/

Also, for as far as I know, it's most common to use return 0; as a successful return value, this has the benefit of allowing you to specify other numbers each indicating a different type of error.

Again, I do apologise for not being able answering your question directly, but I thought you'd like to know these things anyway.

All the best,
NwN
That isn't C++ code, it's C.

as to why it works in one console and not another I couldn't say, perhaps it has to do with those typedefs, afaik UINT64 isn't the same as an unsigned long long int, since it depends on the compiler/OS
Thank you guys for your input.

@NwN: As the post above says, it's C. I will do the same in C++ later. I have always been afraid of the object oriented model. This was meant to be an exercise with an ultimate objective of getting rid of that irrational fear. My plan is to develop a working implementation in C and then design the same in C++ with the whole generator as an object. I shall use Standard Template Libraries when I'm programming in C++, but for now I'm stuck with glibc.

@Zephilinox: That was exactly what I was afraid of. I have absolutely no idea how to ensure type safety. I read earlier that long long means different word-lengths in different operating systems and compilers. I am at Linux 3.2.0-27 x86_64, right now, with 4.6.3. Since I'm using Netbeans, the compiling part isn't completely transparent. I have not knowingly changed flags to m64 but I am not sure if gcc would automatically do that, or even if that really does effect the size of long long. But as far as I know, long long should mean 64-bit integer on most machines.

Once again, your input is really valuable to me. I love this forum because of you guys and guys like you. I haven't had such a great support anywhere else. Cheers.
Although I've never used C, I know it doesn't support classes (I think it supports structures, but you have to typedef those or something, right?), OOP might be a lot easier in C++ so I'd try and start there.

I did find this

http://en.wikipedia.org/wiki/Stdint.h#stdint.h

so if you include that library, instead of UINT64 use uint64_t, it might or might not work.
long long isn't a standard type, not until C++11 was released anyways. A lot of compilers came up with their own standard (some made long long the same size as long int) which makes your code do weird things. There are ways around this, but the simplest would be to upgrade to a C++11 compatible compiler.
unsigned long is guaranteed to be at least 32 bits.
unsigned long long is guaranteed to be at least 64 bits.
@Zephilinox: Yes, that's what I'm doing. But since I'm using Mersenne Twister as an objective exercise, I should first have a working algorithm in C. It's not that I have never done OOP in C++. I have, a few times. It's just that I am not comfortable with it.
And you are right, C supports structures instead of classes, and you may or may not typedef them, depends on the application.
And oh, I did this:
1
2
3
4
5
6
7
8
#include <stdio.h>
#include <stdlib.h>

int main() {
        int a = sizeof(unsigned long long);
        printf("Size of long long: %i\n",a);
        return EXIT_SUCCESS;
}

and compiled it with:
gcc -m64 -o int64sz main.c and also gcc -o int64sz_32 main.c
and this is the output in both cases:

$ ./int64sz 
Size of long long: 8

$ ./int64sz_32 
Size of long long: 8


I guess at least on my system, with my compiler, long long really is 8-byte or 64-bit wide. :)
Although it still poses portability problems. :(

EDIT: Isn't uint64_t defined the same way I defined my UINT64? I know it's smug, but if both are same, I'd better go with my own personal UINT64, hehe!


@Volatile Pulse: I am not using C++ or C++ compiler. gcc is a C compiler, and as far as I know, it is the standard. Cheers! :)
Last edited on
it isn't just long long that you need to check, but all the others as well.

have you tried uint{bits}_t yet?

edit:

oh, I see, you haven't done this before, so you want to get it right in C then port it over to C++ OOP? TBH that doesn't make much sense to me, you'll have to change your code even before you try to compile it without it being OOP.
Last edited on
Ok... I tested all others as well...

Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <stdlib.h>

int main (void) {
	int sz_char = sizeof(unsigned char);
	int sz_short = sizeof(unsigned short int);
	int sz_stint = sizeof(unsigned int);
	int sz_long = sizeof(unsigned long);
	int sz_llong = sizeof(unsigned long long);

	printf("Size of unsigned char:\t\t%i\n", sz_char);
	printf("Size of unsigned short:\t\t%i\n", sz_short);
	printf("Size of unsigned int:\t\t%i\n", sz_stint);
	printf("Size of unsigned long:\t\t%i\n", sz_long);
	printf("Size of unsigned long long:\t%i\n", sz_llong);

	return EXIT_SUCCESS;
}


Compile Command 1:
gcc TypeTest.c -m64 -o TypeTest_64
Output:

$ ./TypeTest_64 
Size of unsigned char:		1
Size of unsigned short:		2
Size of unsigned int:		4
Size of unsigned long:		8
Size of unsigned long long:	8


Compile Command 2:
gcc TypeTest.c -o TypeTest_32
Output:

$ ./TypeTest_32
Size of unsigned char:		1
Size of unsigned short:		2
Size of unsigned int:		4
Size of unsigned long:		8
Size of unsigned long long:	8


It seems that long and long long are the same in my setup. But that does not matter as I have not used unsigned long anywhere in my code.

I want unsigned int as UINT32 -- PASS
I want unsigned short as UINT16 -- PASS
I want unsigned long long as UINT64 -- PASS

The only difference is, I can use unsigned long instead of unsigned long long but according to that Wikipedia article on integers, on Windows and DOS machines, unsigned long is 32 bits wide, same as unsigned int.


EDIT:
you'll have to change your code even before you try to compile it without it being OOP

Well, that's the fun in it, isn't it?
Last edited on
and you get those results regardless of the terminal you view it in?

EDIT: Isn't uint64_t defined the same way I defined my UINT64? I know it's smug, but if both are same, I'd better go with my own personal UINT64, hehe!

I just saw your edit, I'm not sure if it is, I wouldn't see the point otherwise, give it a go, I doubt the C developers made a library type because they were too lazy to type unsigned long long int

but this could all just be unnecessary and not even the problem, I don't think I can help, you might want to ask on a forum dedicated to C, they might know.
Last edited on
and you get those results regardless of the terminal you view it in?

Umm... No! I did the testing only in gnome terminal... I don't know about the C developers, but I'm definitely too lazy to test in Netbeans terminal. At the time I'm assuming Netbeans terminal is just a viewport displaying gnome terminal. Although it my assumption does not explain why it was not showing the proper output in the first place.

And I just checked the stdint.h in my include directory.
1
2
3
4
5
6
#if __WORDSIZE == 64
typedef unsigned long int	uint64_t;
#else
__extension__
typedef unsigned long long int	uint64_t;
#endif 


Ha! I'll go with UINT64 instead of uint64_t... I hate underscores in code. ;)

EDIT: And I just figured out how to get past that incompatibility between UNIX and DOS system over unsigned long... I'll do this:

MersenneTwister.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef MERSENNETWISTER_H
#define	MERSENNETWISTER_H

#include <stdlib.h>
#define SZ_STATE        624
#define KNUTH_MUL       1812433253

#if __WORDSIZE == 64
    typedef unsigned long      UINT64;
#else
    typedef unsigned long long UINT64;
#endif
typedef unsigned int       UINT32;
typedef unsigned short int UINT16;

UINT64 * initializeGenerator (UINT32);
UINT64   extractNumber(UINT16);
UINT64 * generateNumbers(UINT64 *);
UINT64 * randStream(UINT64);
UINT64   randNumber(UINT64);

#endif	/* MERSENNETWISTER_H */ 
Last edited on
I stand corrected ^^
I'm planning on taking another dangerous path... I'm gonna change
UINT64 * initializeGenerator (UINT32);
to
UINT32 * initializeGenerator (UINT32);
and in the definition I'm going to allocate memory to a SZ_STATE sized array of type UINT32 and then in a for loop, I'm going to cast all elements of generatorState to UINT32 and I'm going to return this array of UINT32 numbers instead of previously used UINT64 numbers as generator state.

I'll come back here as soon as I'm stuck. :p
Fortunately or unfortunately, I did not get stuck. And by that, of course, I mean the compiler did not give any errors or warnings.

Here is the finalized MersenneTwister.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include "MersenneTwister.h"

/*-----------------------------------------------------------------------------
 Create a new generator state vector and fill it with Knuth's feedback shift
 register algorithm
-----------------------------------------------------------------------------*/
UINT32 * initializeGenerator (UINT32 Seed) {
    UINT64 * generatorState = NULL;                                             // Define placeholder for generator state
    if (!generatorState) {                                                      // Just checking...
        generatorState = (UINT64 *) malloc (SZ_STATE * sizeof(UINT64));         // Allocate memory
        if (!generatorState) return NULL;                                       // If not possible, return NULL to indicate FAILURE
    }
    
    generatorState[0] = (UINT64) Seed;                                          // Cast 32-bit seed to 64-bit placeholder and store
    UINT16 Count; for (Count=1; Count<SZ_STATE; Count++) {                      // From [1] to [623] fill state vector with Knuth's
        generatorState[Count] = 
                ((KNUTH_MUL * ((generatorState[Count-1]) ^ 
                ((generatorState[Count-1])>>30)) + Count) << 32) >> 32;         // Rotate MT[i-1] 30-right, XOR with MT[i-1], multiply
    }                                                                           // Knuth's multiplier, add i, truncate to 32-bits
    
    
    UINT32 * returnState = NULL;                                                // Define placeholder for returnable vector
    if (!returnState) {                                                         // Just checking...
        returnState = (UINT32 *) malloc (SZ_STATE * sizeof(UINT32));            // Allocate memory
        if (!returnState) return NULL;                                          // If not possible, return NULL to indicate FAILURE
    }
    
    for (Count=1; Count<SZ_STATE; Count++) {
        returnState[Count] = (UINT32) generatorState[Count];                    // From [1] to [623] cast 64-bit numbers to 32-bit numbers
    }
    
    return returnState;                                                         // Return the 32-bit version of generatorState
}

/*
unsigned long   ExtractNumber(unsigned short Index){
    
}
unsigned long * GenNumbers(unsigned long * currentState){
    
}
unsigned long * RandStream(unsigned long Seed){
    
}
unsigned long   RandNumber(void){
    
}
*/


Comments, gentlemen?

EDIT: If anyone wonders why I don't do the Knuth's feedback shift register in UINT32, there's shifting and multiplication involved. If UINT32 is used, the result would be truncated somewhere in the middle of the statement and the output would turn out to be a constant number instead of Knuth's GFSR stream. The algorithm kinda requires that the operations be done on placeholders with width greater than 32-bits.
Last edited on
Does it work? and I like how you've spaced your comments, although I think you're using too many for stuff that's obvious (like returning null) but yeah, don't know what else to say.
Spaced my comments with tabs... Though I don't understand what you mean by spacing...
And I'm planning on using this code, someday, to teach programming to kids. In my personal opinion, it's a wee better example than printing dots or number of beer bottles.
I know it looks kinda dumb using comments for obvious steps, but trust me, a year from now when I look at these comments, I would be able to visualize everything that I have in my head right now.
by spacing I meant having it all line up in the text editor, rather then putting it straight after a line of code, e.g

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
UINT32 * initializeGenerator (UINT32 Seed) {
    UINT64 * generatorState = NULL; // Define placeholder for generator state
    if (!generatorState) { // Just checking...
        generatorState = (UINT64 *) malloc (SZ_STATE * sizeof(UINT64)); // Allocate memory
        if (!generatorState) return NULL; // If not possible, return NULL to indicate FAILURE
    }
    
    generatorState[0] = (UINT64) Seed;  // Cast 32-bit seed to 64-bit placeholder and store
    UINT16 Count; for (Count=1; Count<SZ_STATE; Count++) {  // From [1] to [623] fill state vector with Knuth's
        generatorState[Count] = 
                ((KNUTH_MUL * ((generatorState[Count-1]) ^ 
                ((generatorState[Count-1])>>30)) + Count) << 32) >> 32; // Rotate MT[i-1] 30-right, XOR with MT[i-1], multiply
    }  // Knuth's multiplier, add i, truncate to 32-bits
    
    
    UINT32 * returnState = NULL;  // Define placeholder for returnable vector
    if (!returnState) {   // Just checking...
        returnState = (UINT32 *) malloc (SZ_STATE * sizeof(UINT32)); // Allocate memory
        if (!returnState) return NULL; // If not possible, return NULL to indicate FAILURE
    }
    
    for (Count=1; Count<SZ_STATE; Count++) {
        returnState[Count] = (UINT32) generatorState[Count]; // From [1] to [623] cast 64-bit numbers to 32-bit numbers
    }
    
    return returnState; // Return the 32-bit version of generatorState
}


I think you'll have a hard time explaining this code to kids though :3
Last edited on
I think you'll have a hard time explaining this code to kids though :3

Hahaha. I look forward to that.

by spacing I meant having it all line up in the text editor, rather then putting it straight after a line of code, e.g

Like I said, tabs... I'm kind of a clean freak, especially when writing code. In the editor, there's a vertical bar to indicate end of printline... I just press tabs until I reach that bar. If I were to print the code directly from the IDE, the comments beyond the bar would not appear on the paper.
I could print copies and give it to students to analyze and write down what they think each statement does and how it does that... Just a thought. :) Normally, in the IDE, the bar works as a separator; code on the left side, and the algorithm on the right side.
I know how you did it, I was just pointing out I liked it.
Pages: 12