Dice Program: C and Java Side-by-side


The two programs: Differences between these two programs are highlighted in red and are explained after the listings.

C Dice Program Equivalent Java Dice Program

/* dice: Gather statistics about rolling
* two dice. A Monte Carlo simulation using
* the random number generator rand()
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void initarray(int d[]);
void printarray(int d[]);
void printstar(int n);
void fancyprint(int d[]);
int roll(void);

int numrolls;

int main(void) {

int d[13]; /* 2-12 hold num of rolls */
int i; /* loop variable */
int
starttime = time(NULL); /* clock time */
srand((long)starttime);
printf
("Enter # of rolls ---> ");
scanf("%i", &numrolls); /* need & on var */

initarray(d);
printf("Total rolls: %1d ", numrolls);

for (i = 0; i < numrolls; i++)
d[roll() + roll()]++;
printarray(d);
fancyprint(d);
printf("Elapsed time: %ld seconds ",
time(NULL) - starttime);
return 0;
}
/* initarray: initialize statistic array */
void initarray(int d[]) {
int i;
for (i = 2; i < 13; i++)
d[i] = 0;
}
/* printarray: print each num of rolls */
void printarray(int d[]) {
int i;
double e[] = {0, 0,
1.0/36.0, 2.0/36.0, 3.0/36.0, 4.0/36.0,
5.0/36.0, 6.0/36.0, 5.0/36.0, 4.0/36.0,
3.0/36.0, 2.0/36.0, 1.0/36.0};
printf("Sum Times Frequency");
printf(" Exact Diff ");
for (i = 2; i < 13; i++)
printf("%2d %7d %11.7f %10.7f %8.4f ",
i,
d[i],
(double)d[i]/numrolls*100.0,

e[i]*100.0,
((double)(d[i]) -
e[i]*numrolls)/numrolls*100.0);
}

/* printstar: print n stars */
void printstar(int n) {
while (n > 0) {
printf("*");
n--;
}
}

/* fancyprint: print bar graph */
void fancyprint(int d[]) {
int i;
printf(" ");
for (i = 2; i < 13; i++) {
printf("Sum:%3d |", i);

printstar(300*d[i]/numrolls);

printf(" ");
}
printf(" ");
}

/* roll: simulate rolling a die */
int roll(void) {
return (int) (6.0*(rand()/(double)RAND_MAX)
+ 1.0);
}

/* Dice: Gather statistics about rolling
* two dice. A Monte Carlo simulation using
* the random number generator Math.random()
*/
import java.io.*;
public class Dice{

static java.text.DecimalFormat sixDigits =
new java.text.DecimalFormat("0.000000");




static
int numRolls;

public static void main(String[] args)
throws IOException {
int[] d = new int[13];

long startTime = System.currentTimeMillis();

System.out.print
("Enter # of rolls ---> ");
int ch;
numRolls = 0;
for (;;) {
ch = System.in.read();
if (!Character.isDigit((char)ch)) break;
numRolls = numRolls*10 + (ch - '0');
}

initArray(d);
System.out.println("Total rolls: " +
numRolls + " ");
for (int i = 0; i < numRolls; i++)
d[roll() + roll()]++;
printArray(d);
fancyPrint(d);
System.out.println("Elapsed time (millis) " +
(System.currentTimeMillis() - startTime));

}

/* initArray: initialize statistic array */
static void initArray(int[] d) {

for (int i = 2; i < 13; i++)
d[i] = 0;
}

/* printArray: print each num of rolls */
static void printArray(int[] d) {

double[] e = {0, 0,
1.0/36.0, 2.0/36.0, 3.0/36.0, 4.0/36.0,
5.0/36.0, 6.0/36.0, 5.0/36.0, 4.0/36.0,
3.0/36.0, 2.0/36.0, 1.0/36.0};
System.out.println("Sum Times Freq (%)" +
" Exact (%) Diff ");
for (int i = 2; i < 13; i++)
System.out.println(
i + " " +
d[i] + " " +
sixDigits.format((double)d[i] /
numRolls*100.0) + " " +
sixDigits.format(e[i]*100.0) + " " +
sixDigits.format(((double)d[i] -
e[i]*numRolls) / numRolls*100.0));
}

/* printStar: print n stars */
static void printStar(int n) {
while (n > 0) {
System.out.print("*");
n--;
}
}

/* fancyPrint: print bar graph */
static void fancyPrint(int[] d) {

System.out.print(" ");
for (int i = 2; i < 13; i++) {
System.out.print("Sum: ");
if (i < 10) System.out.print(" ");
System.out.print(i + " |");

printStar(300*d[i]/numRolls);
System.out.print(" ");
}
System.out.print(" ");
}

/* roll: simulate rolling a die */
static int roll() {
return (int) (6.0*Math.random()
+ 1.0);
}
}
Common Output (more-or-less)
% java Dice
Enter # of rolls ---> 1000000
Total rolls: 1000000
Sum Times Freq (%) Exact (%) Diff
2 27869 2.786900 2.777778 0.009122
3 55791 5.579100 5.555556 0.023544
4 83005 8.300500 8.333333 -0.032833
5 111011 11.101100 11.111111 -0.010011
6 138791 13.879100 13.888889 -0.009789
7 166755 16.675500 16.666667 0.008833
8 139048 13.904800 13.888889 0.015911
9 110890 11.089000 11.111111 -0.022111
10 83280 8.328000 8.333333 -0.005333
11 55980 5.598000 5.555556 0.042444
12 27580 2.758000 2.777778 -0.019778
Sum: 2 |********
Sum: 3 |****************
Sum: 4 |************************
Sum: 5 |*********************************
Sum: 6 |*****************************************
Sum: 7 |**************************************************
Sum: 8 |*****************************************
Sum: 9 |*********************************
Sum: 10 |************************
Sum: 11 |****************
Sum: 12 |********
Elapsed time (millis) 11490


Commentary about the programs: These programs are more similar that it might seem from all the red above.

  1. Structure of the C program: This is a fairly standard way to write a program such as this, assuming it is all given in a single file. It consists of a main function followed by definitions of other functions called from main and from each other. In each C source file, one ought to give either a function prototype or a function definition before each use of the function. (In C++ this is required.) With this program it would be possible to write the functions in a specific order so that all definitions precede their use, and then no prototypes would be needed. More commonly, one writes a complete set of prototypes, so that the functions can be defined in any order. In case of mutual recursion (A calls B, and B calls A), prototypes are required.

  2. Structure of the Java program: This is not the way one would normally write this program in Java: with all static functions and one static variable at the class level. However, this matches the C program. Notice that in Java the functions can be defined in any order and there are no prototypes (except in interfaces). All 6 functions were enclosed in a single class.

  3. Names: Variable and function names in both languages can be almost anything, but the two languages have customary ways of naming objects. In C, only lower-case is used for all but named constants (all upper-case). The variables are typically run together, as with printarray, although C sometimes uses an underscore: print_array. Java, on the other hand, starts names with a lower-case letter, followed by lower-case, but with an upper-case letter starting each subsequent part. Thus Java uses printArray. Both languages stick in digits also. Classes in Java start with an upper-case letter. All of this is just by convention and not required.

  4. Arrays as formal parameters: In Java a 1-dimensional array d is usually declared as a formal parameter as int[] d, while in C or C++ it must be declared as int p[]. (In Java you can also use the C form, but that is not recommended.)

  5. Declaring the loop variable: In both Java and C++, you can declare the loop variable as part of the for loop: for (int i = 2; i < 13; i++). The scope of i is limited to the for loop. This is not allowed in C.

  6. Printing: C uses a special "print formatted" function printf which is powerful and handy, but not type-safe. This function is now in the latest version of Java (1.5.0) as System.out.printf.

  7. Array allocation: Java only has dynamic array allocation, as in int[] d = new int[13];. C and C++ allow dynamic array allocation, but the more normal method is to allocate on the run-time stack, using just: int d[13];. The array d could have been declared outside the main function in the C program, as it could have been in the Java program also.


    Created By Dr. Neal Wager : The University of Texas at San Antonio