473,398 Members | 2,427 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,398 software developers and data experts.

rolling dice

Let's say I have m dice having n sides, such that n^m is not going to bust
int as a datatype. With m=4 and n=6, an outcome might be {2, 5, 1, 2}.
What is a good way to represent this in c so that I can check cases by brute
force? EC
Sep 30 '06 #1
101 6285

"Elijah Cardon" <in*****@invalid.netwrote in message
news:12*************@corp.supernews.com...
Let's say I have m dice having n sides, such that n^m is not going to bust
int as a datatype. With m=4 and n=6, an outcome might be {2, 5, 1, 2}.
What is a good way to represent this in c so that I can check cases by
brute force? EC
Depends on your meory

typedef struct
{
int m;
int n;
int *roll; /* allocated dice with malloc */
} DICEROLL;

Is the obvious way if you have memory to burn.
However you already know all the possible dice in the roll set. So you can
generate the rolls from an index number by taking modulus and dividing.
--
www.personal.leeds.ac.uk/~bgy1mm
freeware games to download.
Sep 30 '06 #2
Elijah Cardon wrote:
Let's say I have m dice having n sides, such that n^m is not going to bust
int as a datatype. With m=4 and n=6, an outcome might be {2, 5, 1, 2}.
What is a good way to represent this in c so that I can check cases by brute
force? EC
One way that comes to mind are n-adic numbers; start your results
at 0 (i.e. subtract 1 if necessary), then you get digits of a range
from 0 to n-1. This can be (using ^ to express powers) represented
as
a[m-1]*n^(m-1)+....+a[1]*n^1+a[0]*n^0.
I.e. the above can be represented as
(2-1)*216+(5-1)*36+(1-1)*6+(2-1)*1
In most cases, I'd rather use an array containing the digits -- for
many n, it is easier to debug. If you then really want to be able
to squeeze it into an int, then you can do it as soon as the rest
works.

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Sep 30 '06 #3
Malcolm posted:
typedef struct
{
int m;
int n;
int *roll; /* allocated dice with malloc */
} DICEROLL;

I strongly advocate the use of ALL CAPS for macros and for macros only.

--

Frederick Gotham
Sep 30 '06 #4
Elijah Cardon posted:
Let's say I have m dice having n sides, such that n^m is not going to
bust int as a datatype.

By "bust", do you mean overflow? The highest number reliably stored in an int
is 32767. If "n" is 6, then "m" can be as large as 5.

With m=4 and n=6, an outcome might be {2, 5, 1,
2}. What is a good way to represent this in c so that I can check cases
by brute force? EC

I don't know what you mean by "check cases". The programming language is
invariably spelled with an uppercase C, just so you know.

--

Frederick Gotham
Sep 30 '06 #5

"Malcolm" <re*******@btinternet.comwrote in message
news:RK********************@bt.com...
>
"Elijah Cardon" <in*****@invalid.netwrote in message
news:12*************@corp.supernews.com...
>Let's say I have m dice having n sides, such that n^m is not going to
bust int as a datatype. With m=4 and n=6, an outcome might be {2, 5, 1,
2}. What is a good way to represent this in c so that I can check cases
by brute force? EC
Depends on your meory

typedef struct
{
int m;
int n;
int *roll; /* allocated dice with malloc */
} DICEROLL;
For the moment, I want to stay away from mallocs and structs. I think the
above approach would favor object orientation.
Is the obvious way if you have memory to burn.
However you already know all the possible dice in the roll set. So you can
generate the rolls from an index number by taking modulus and dividing.
Rolling the dice is what I'm not going to do. I'm going to enumerate the
outcomes. Memory is plentiful, and stdout will never run out of paper.
#define m 4
#define n 6

I don't see what good the first #define will do me when I need to hard code
the number of '[n]' in the statement

int a[n]a[n]a[n]a[n];

Any comment appreciated. EC
Sep 30 '06 #6
Elijah Cardon posted:
Rolling the dice is what I'm not going to do. I'm going to enumerate
the outcomes.

Bitwise manipulation might be handy for minimising memory consumption. For
instance, if a dice has 6 sides, then we only need 3 bits to log each
individual roll:

000 == Rolled 1 on the dice.
001 == Rolled 2 on the dice.
010 == Rolled 3 on the dice.
011 == Rolled 4 on the dice.
100 == Rolled 5 on the dice.
101 == Rolled 6 on the dice.

For even more conservative use of memory, we can find a multiple of 6 which
is also a integral power of 2 (unfortunately though, any such number is
quite large).

This problem would be far better solved with an OO language, but if you
want to use C, then so be it. Maybe something like:

#include <stddef.h>
#include <limits.h>
#include <assert.h>
#include <stdlib.h>

typedef struct EnumInfo {
unsigned bits_per_outcome;
size_t quant_bytes;
char unsigned *p;
} EnumInfo;

unsigned BitsNeeded(unsigned combinations)
{
/* I'm pretty sure there's a far
better way of implementing this
function.
*/

int const assert_dummy = (assert(!!combinations),0);

unsigned bits = 1;

--combinations;

while(combinations >>= 1) ++bits;

return bits;
}

EnumInfo EnumerateResults(unsigned const throws,unsigned const sides)
{
EnumInfo info;

info.bits_per_outcome = BitsNeeded(sides);

info.quant_bytes = info.bits_per_outcome * (throws/CHAR_BIT +1);
/* A few bytes wasted */
/* We might want a few checks to make sure
the size_t hasn't overflowed. */

info.p = malloc(info.quant_bytes);

/* Write the results to memory */

return info;
}

It will be a little tricky if CHAR_BIT isn't evenly divisible by
"bits_per_outcome" (which will happen quite a lot for 6-sided die on a
system with 8-Bit bytes). The complexity could be greatly reduced however
if you used an OO language which allowed you to implement a BitHandle which
could encapsulate the nitty-gritty of the bit manipulation away from your
other code -- but still, it's achievable in C.

--

Frederick Gotham
Sep 30 '06 #7

"Michael Mair" <Mi**********@invalid.invalidwrote in message
news:4o************@individual.net...
Elijah Cardon wrote:
>Let's say I have m dice having n sides, such that n^m is not going to
bust int as a datatype. With m=4 and n=6, an outcome might be {2, 5, 1,
2}. What is a good way to represent this in c so that I can check cases
by brute force? EC

One way that comes to mind are n-adic numbers; start your results
at 0 (i.e. subtract 1 if necessary), then you get digits of a range
from 0 to n-1. This can be (using ^ to express powers) represented
as
a[m-1]*n^(m-1)+....+a[1]*n^1+a[0]*n^0.
I.e. the above can be represented as
(2-1)*216+(5-1)*36+(1-1)*6+(2-1)*1
In most cases, I'd rather use an array containing the digits -- for
many n, it is easier to debug. If you then really want to be able
to squeeze it into an int, then you can do it as soon as the rest
works.

#include "stdio.h"
#define n 6

int main(int argc, char* argv[])
{
int i1, i2, a[n][n];

for (i1 = 0; i1 < n; i1 ++)
{
for (i2 = 0; i2 < n; i2 ++)
{
/*what here */
}
}
printf("Hello World!\n");
return 0;
}
I was thinking that arrays were the way to go, but as I start to write the
control loops, it's the dummies themselves that I want. And I would
re-write the loops to go from 1 to n, as opposed to the matrix-friendly 0 to
n-1 . Where I have the comment, I could test for whether the dummies add to
seven and keep a counter of those that do, and those that don't. I would
then have the probability I'm looking for.

What I don't see is how I would take this approach and have a program that
isn't totally hard-coded for every dimension. EC
Sep 30 '06 #8
Frederick Gotham wrote:
For even more conservative use of memory, we can find a multiple of 6 which
is also a integral power of 2 (unfortunately though, any such number is
quite large).
If by power of 2 you mean a number of the form
2^k then no such number can be a multiple of 6.

Sep 30 '06 #9
Frederick Gotham wrote:
[...]
For even more conservative use of memory, we can find a multiple of 6 which
is also a integral power of 2 (unfortunately though, any such number is
quite large).
I can think of only one such integer, but it isn't very
large at all ...

--
Eric Sosman
es*****@acm-dot-org.invalid
Sep 30 '06 #10
Spiros Bousbouras posted:
Frederick Gotham wrote:
>For even more conservative use of memory, we can find a multiple of 6
which is also a integral power of 2 (unfortunately though, any such
number is quite large).

If by power of 2 you mean a number of the form
2^k then no such number can be a multiple of 6.

Yes, I mean two non-zero positive integers, "k" and "x", which satisfy the
following equation:

(unsigned)pow(2,k) % (6 * x) == 0

I played around with my calculator and gave up when I went as far as 2048.
Being a non-mathematician, I'm not great at spotting these things straight
away ;).

--

Frederick Gotham
Sep 30 '06 #11
Elijah Cardon wrote:
"Michael Mair" <Mi**********@invalid.invalidwrote
>>Elijah Cardon wrote:
>>>Let's say I have m dice having n sides, such that n^m is not going to
bust int as a datatype. With m=4 and n=6, an outcome might be {2, 5, 1,
2}. What is a good way to represent this in c so that I can check cases
by brute force? EC

One way that comes to mind are n-adic numbers; start your results
at 0 (i.e. subtract 1 if necessary), then you get digits of a range
from 0 to n-1. This can be (using ^ to express powers) represented
as
a[m-1]*n^(m-1)+....+a[1]*n^1+a[0]*n^0.
I.e. the above can be represented as
(2-1)*216+(5-1)*36+(1-1)*6+(2-1)*1
In most cases, I'd rather use an array containing the digits -- for
many n, it is easier to debug. If you then really want to be able
to squeeze it into an int, then you can do it as soon as the rest
works.

#include "stdio.h"
#define n 6

int main(int argc, char* argv[])
{
int i1, i2, a[n][n];

for (i1 = 0; i1 < n; i1 ++)
{
for (i2 = 0; i2 < n; i2 ++)
{
/*what here */
}
}
printf("Hello World!\n");
return 0;
}
I was thinking that arrays were the way to go, but as I start to write the
control loops, it's the dummies themselves that I want. And I would
re-write the loops to go from 1 to n, as opposed to the matrix-friendly 0 to
n-1 . Where I have the comment, I could test for whether the dummies add to
seven and keep a counter of those that do, and those that don't. I would
then have the probability I'm looking for.

What I don't see is how I would take this approach and have a program that
isn't totally hard-coded for every dimension. EC
I am still not sure what you want but variable dimension can
be coded straightforward via recursion:

,---
#include <stdio.h>

int countSumOccurrences(int n, int m, int sum);
void countSumOccurrences_Rec(int n, int m, int sum, int *pCount);

int main (void)
{
int i;
for (i = 1; i <= 5; ++i)
printf("%d 6 sided dices; occurrence of sum %d: %d times\n",
i, 2*i, countSumOccurrences(6, i, 2*i));
return 0;
}

int countSumOccurrences(int n, int m, int sum)
{
int count = 0;
countSumOccurrences_Rec(n, m, sum, &count);
return count;
}

void countSumOccurrences_Rec(int n, int m, int sum, int *pCount)
{
#define VALUE_ADJUSTMENT(v) ((v)+1)
if (m == 1) {
if (sum >= VALUE_ADJUSTMENT(0) && sum < VALUE_ADJUSTMENT(n)) {
++*pCount;
}
}
else if (m 1) {
int i;
for (i = 0; i < n && i <= sum; ++i) {
countSumOccurrences_Rec(n, m - 1,
sum - VALUE_ADJUSTMENT(i), pCount);
}
}
}
`---

Note that you can always get rid of a recursion via using a stack.
You probably want to get rid of the VALUE_ADJUSTMENT in this case.
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Sep 30 '06 #12
Elijah Cardon wrote:
Where I have the comment, I could test for whether the dummies add to
seven and keep a counter of those that do, and those that don't. I would
then have the probability I'm looking for.
What probability are you looking for ? You still
haven't explained what problem you're trying to
solve.

Sep 30 '06 #13
Frederick Gotham wrote:
Spiros Bousbouras posted:
Frederick Gotham wrote:
For even more conservative use of memory, we can find a multiple of 6
which is also a integral power of 2 (unfortunately though, any such
number is quite large).
If by power of 2 you mean a number of the form
2^k then no such number can be a multiple of 6.


Yes, I mean two non-zero positive integers, "k" and "x", which satisfy the
following equation:

(unsigned)pow(2,k) % (6 * x) == 0
For a large enough k this will be satisfied simply because
pow(2,k) will wrap around to 0. But without wraparound it
will never be true.

Sep 30 '06 #14

"Michael Mair" <Mi**********@invalid.invalidwrote in message
news:4o************@individual.net...
Elijah Cardon wrote:
>"Michael Mair" <Mi**********@invalid.invalidwrote
>>>Elijah Cardon wrote:

Let's say I have m dice having n sides, such that n^m is not going to
bust int as a datatype. With m=4 and n=6, an outcome might be {2, 5, 1,
2}. What is a good way to represent this in c so that I can check cases
by brute force? EC

#include <stdio.h>

int countSumOccurrences(int n, int m, int sum);
void countSumOccurrences_Rec(int n, int m, int sum, int *pCount);

int main (void)
{
int i;
for (i = 1; i <= 5; ++i)
printf("%d 6 sided dices; occurrence of sum %d: %d times\n",
i, 2*i, countSumOccurrences(6, i, 2*i));
return 0;
}

int countSumOccurrences(int n, int m, int sum)
{
int count = 0;
countSumOccurrences_Rec(n, m, sum, &count);
return count;
}

void countSumOccurrences_Rec(int n, int m, int sum, int *pCount)
{
#define VALUE_ADJUSTMENT(v) ((v)+1)
if (m == 1) {
if (sum >= VALUE_ADJUSTMENT(0) && sum < VALUE_ADJUSTMENT(n)) {
++*pCount;
}
}
else if (m 1) {
int i;
for (i = 0; i < n && i <= sum; ++i) {
countSumOccurrences_Rec(n, m - 1,
sum - VALUE_ADJUSTMENT(i), pCount);
}
}
}
`---

Note that you can always get rid of a recursion via using a stack.
You probably want to get rid of the VALUE_ADJUSTMENT in this case.
This is the line I wanted to take this in, but I gotta get my head around
the notions of recursion and stack depth. To that I end I ask this
question:
long factorial(int n) {
if (n == 1)
return 1;
return n * factorial(n - 1);
}

What is the stack depth as a function of n? If you look at the discussion
in chp 10 of _C Unleashed_, it follows the execution of this source. At the
end, there are n-1 paragraphs that begin:
Back on line ....
, so I think the stack depth is n-1 . If I'm wrong that it's near n, I
don't see how stack depth could be less than (n-1)! . EC

Sep 30 '06 #15
Spiros Bousbouras wrote:
>
Frederick Gotham wrote:
Spiros Bousbouras posted:
Frederick Gotham wrote:
>
>For even more conservative use of memory,
>we can find a multiple of 6
>which is also a integral power of 2
>(unfortunately though, any such number is quite large).
>
If by power of 2 you mean a number of the form
2^k then no such number can be a multiple of 6.

Yes, I mean two non-zero positive integers,
"k" and "x", which satisfy the following equation:

(unsigned)pow(2,k) % (6 * x) == 0

For a large enough k this will be satisfied simply because
pow(2,k) will wrap around to 0.
Why do you think that pow(2,k) will wrap around to 0?
pow(2, 10000) is an infinity on my machine.

--
pete
Sep 30 '06 #16

"Elijah Cardon" <in*****@invalid.netwrote in message
news:12*************@corp.supernews.com...
>
"Malcolm" <re*******@btinternet.comwrote in message
news:RK********************@bt.com...
>>
"Elijah Cardon" <in*****@invalid.netwrote in message
news:12*************@corp.supernews.com...
>>Let's say I have m dice having n sides, such that n^m is not going to
bust int as a datatype. With m=4 and n=6, an outcome might be {2, 5, 1,
2}. What is a good way to represent this in c so that I can check cases
by brute force? EC
Depends on your meory

typedef struct
{
int m;
int n;
int *roll; /* allocated dice with malloc */
} DICEROLL;
For the moment, I want to stay away from mallocs and structs. I think the
above approach would favor object orientation.
>Is the obvious way if you have memory to burn.
However you already know all the possible dice in the roll set. So you
can generate the rolls from an index number by taking modulus and
dividing.
Rolling the dice is what I'm not going to do. I'm going to enumerate the
outcomes. Memory is plentiful, and stdout will never run out of paper.
#define m 4
#define n 6

I don't see what good the first #define will do me when I need to hard
code the number of '[n]' in the statement

int a[n]a[n]a[n]a[n];
Multi-dimensional arrays don't work very well in C.
If you have five dice with six sides you could declare

int dice[6][6][6][6][6];

however you have no flexibility. You cannot easily change the number of
sides or of dice.

However can can simulate with an array

int *dice = malloc( (int) pow(n,m));

You still gobble lots of memory.

You can then write a fuction

int rolltoindex(int m, int n, int *roll)

That takes the number of dice and the number of faces as parameters, also
the rolls, and converts to an index to use in the table you malloced().
--
www.personal.leeds.ac.uk/~bgy1mm
freeware games to download.
Sep 30 '06 #17

"Spiros Bousbouras" <sp****@gmail.comwrote in message
news:11**********************@e3g2000cwe.googlegro ups.com...
Elijah Cardon wrote:
>Where I have the comment, I could test for whether the dummies add to
seven and keep a counter of those that do, and those that don't. I would
then have the probability I'm looking for.

What probability are you looking for ? You still
haven't explained what problem you're trying to
solve.
I've seen people play dice before and certainly recall hours of dice in my
hands for gaming purposes. I found myself in a situation, where I was not
only playing a dice game I'd never played before, apparently, it's called
"dice," and found myself attracted to certain aspects of the game.

Getting a one or a five means you get to roll again. So, for the purpose of
detremining whether you can roll again, you can map the six-sided die onto
the three-sided die. Someone wondered aloud what the chances are of rolling
again with 2 dice. I saw a picture in my head that looked like:
_____________
| x | o | o |
-------------
| x | o | o |
-------------
| x | x | x |
_____________
I said ,"five ninths."

Later, I'm trying to sleep, and wonder how it would look in a higher
dimension. The next would be like a Rubic's cube. First I saw x's heading
out along the orthogonals, but that would make 11 out of 27 cubes x's, and
your odds don't go down, so that was wrong. I decided I needed to add the
plane: 9 cubes to the 2 planes of residuals 9+2*5=19 x's out of 27. I
verified this number from first principles.

And with 4 dimensions? I think you add the cube to twice the residual:
27+2(19)=65 out of 81. It's getting a little tedious to verify by hand. EC
Sep 30 '06 #18
Eric Sosman wrote:
Frederick Gotham wrote:
>[...]
For even more conservative use of memory, we can find a multiple of 6
which is also a integral power of 2 (unfortunately though, any such
number is quite large).


I can think of only one such integer, but it isn't very
large at all ...
Sorry; I retract this. I misread "multiple of 6" as "power of 6,"
which admits of one solution. Restoring "multiple" instead of "power,"
the solution set dwindles slightly to an entity known as the null set.

--
Eric Sosman
es*****@acm-dot-org.invalid

Oct 1 '06 #19
Elijah Cardon wrote:
Let's say I have m dice having n sides, such that n^m is not going to bust
int as a datatype. With m=4 and n=6, an outcome might be {2, 5, 1, 2}.
What is a good way to represent this in c so that I can check cases by brute
force? EC
What's wrong with what you just showed? That is, an array of
length m. Sort it, if the dice are indistinguishable.

--
Thomas M. Sommers -- tm*@nj.net -- AB2SB

Oct 1 '06 #20

"T.M. Sommers" <tm*@nj.netwrote in message
news:45***********************@news.pa.net...
Elijah Cardon wrote:
>Let's say I have m dice having n sides, such that n^m is not going to
bust int as a datatype. With m=4 and n=6, an outcome might be {2, 5, 1,
2}. What is a good way to represent this in c so that I can check cases
by brute force? EC

What's wrong with what you just showed? That is, an array of length m.
Sort it, if the dice are indistinguishable.
What integer goes into the a[q][r][s][t] entry where q, r, s, t are less
than or equal to n-1 ?

I need a control that will go over every n-tuple and allow a decision to be
made with the n-tuple in hand. EC
Oct 1 '06 #21
Elijah Cardon wrote:
"T.M. Sommers" <tm*@nj.netwrote in message
news:45***********************@news.pa.net...
>>Elijah Cardon wrote:
>>>Let's say I have m dice having n sides, such that n^m is not going to
bust int as a datatype. With m=4 and n=6, an outcome might be {2, 5, 1,
2}. What is a good way to represent this in c so that I can check cases
by brute force? EC

What's wrong with what you just showed? That is, an array of length m.
Sort it, if the dice are indistinguishable.

What integer goes into the a[q][r][s][t] entry where q, r, s, t are less
than or equal to n-1 ?
Why do you need a 4-dimensional array, instead of a 1-dimensional
array of length 4? That is, why not use:

int roll[4] = {2, 5, 1, 2};

to use your example.
I need a control that will go over every n-tuple and allow a decision to be
made with the n-tuple in hand. EC
A for loop ought to work.

--
Thomas M. Sommers -- tm*@nj.net -- AB2SB

Oct 1 '06 #22
[snip when something boils down to null]
#include <stdio.h>

int countSomething(int n, int dummy_from_main);
void enum_rec(int n, int m, int sum, int *pCount);

int main (void)
{
int i;
for (i = 1; i <= 5; ++i)
printf("%d 6 sided dice; summed to george %d times\n",
i, countSomething(6, i));
return 0;
}

int countSomething(int n, int dummy_from_main)
{
int count = 0;
int george;

george = 5;

enum_rec(n, dummy_from_main, george, &count);
return count;
}

void enum_rec(int n, int m, int sum, int *pCount)
{
#define VALUE_ADJUSTMENT(v) ((v)+1)
if (m == 1) {
if (sum >= VALUE_ADJUSTMENT(0) && sum < VALUE_ADJUSTMENT(n)) {
++*pCount;
}
}
else if (m 1) {
int i;
for (i = 0; i < n && i <= sum; ++i) {
enum_rec(n, m - 1,
sum - VALUE_ADJUSTMENT(i), pCount);
}
}
}
I've hacked up this remarkable source from Mr. Mair. He cooked it up to
order faster than I get my meals. The actual conditions I'm testing require
that I do comparisons within the n-tuple.

This n-tuple has to be lurking in the recursive function. The value
adjustment part is clearly what we do in c to make up for lesser minds not
having made the range {1,2,3,4,5,0}, but, hey, they were trying.

The specific conditions I test are the following:
if n-tuple contains a one, then it's an x;
if n-tuple contains a five, then it's an x;
if n-tuple has three numbers alike, then it's an x;
~x's are o's;

My compiler is going nighty-night. EC

Oct 1 '06 #23
Frederick Gotham said:
Malcolm posted:
>typedef struct
{
int m;
int n;
int *roll; /* allocated dice with malloc */
} DICEROLL;


I strongly advocate the use of ALL CAPS for macros and for macros only.
Apart from the hypocrisy being shown here (you called Keith Thompson a
fascist for daring to criticise your style, and yet here you are,
criticising someone else's style), what you are overlooking is that there
is a large and influential code base which uses ALL CAPS for type names -
namely, the Win32 API. And in fact there is never any confusion, since type
names and macros are rarely if ever used in contexts where they might
conceivably be confused.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Oct 1 '06 #24
T.M. Sommers wrote:
Elijah Cardon wrote:
>"T.M. Sommers" <tm*@nj.netwrote
>>Elijah Cardon wrote:

Let's say I have m dice having n sides, such that n^m is not going
to bust int as a datatype. With m=4 and n=6, an outcome might be
{2, 5, 1, 2}. What is a good way to represent this in c so that I
can check cases by brute force? EC

What's wrong with what you just showed? That is, an array of length
m. Sort it, if the dice are indistinguishable.

What integer goes into the a[q][r][s][t] entry where q, r, s, t are
less than or equal to n-1 ?

Why do you need a 4-dimensional array, instead of a 1-dimensional array
of length 4? That is, why not use:

int roll[4] = {2, 5, 1, 2};

to use your example.
>I need a control that will go over every n-tuple and allow a decision
to be made with the n-tuple in hand. EC

A for loop ought to work.
Not necessarily. If the "dimensions'" meaning differs strongly,
then you have indeed to be able to access all "dimensions" separately.
This means either
- a loop over all dimensions, a loop over all values of a
dimension, and a stack to store the processed dimensions' values or
- a loop over the values of all dimensions combined with code to extract
the interpretations/values of all dimensions depending on the number
of dimensions (and handle its task accordingly) or
- some recursion instead of the implicit and explicit stacks above or
- something else
What you actually do depends strongly on the problem, your environmental
restrictions, and, of course, personal taste :-)

How you store the data is a separate matter which ties in with the
above.
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Oct 1 '06 #25
Richard Heathfield posted:
Apart from <snip Episode 4 of Babysisters' Club 2nd Seasonwhat you are
overlooking is that there is a large and influential code base which
uses ALL CAPS for type names - namely, the Win32 API.

And once again, the rule of thumb applies:

Don't do what Microsoft does.

I think I'd puke if I had to read through an entire header file or source
file written by Microsoft.

Just yesterday I was trying to persuade a C++ programmer to use ALL CAPS
for macros and for macros only -- I thought a C programmer would be
convinced much more easily given how they use macros on a much more regular
basis.

And in fact there is never any confusion, since type names and macros
are rarely if ever used in contexts where they might conceivably be
confused.

I can think of one problem off-hand:

typedef int *MyType;
#define MY_TYPE int*

void Func(const MyType);

void Func(const MY_TYPE arg) {}

Compile ERROR: Definition does not match declaration.

The main problem, however, is that it dullens the pinch we get every time
we see ALL CAPS. If we were to only ever see ALL CAPS for macro names, then
we'd know straight away that we're dealing with a macro, and we'd exercise
due caution (e.g. beware of mutliple evaluation of arguments). If people
start using ALL CAPS willy-nilly for all sorts of reasons, then we'll have
a "Boy Who Cried Wolf" situation, and nobody will pay a blind bit of notice
to ALL CAPS, leading to such mistakes as:

SQR(i++);

One last thing... ALL CAPS are ugly; I don't see why anyone would want to
use them for any other reason than to pinch oneself -- but then again, it
would be fascist of me to impose my dislike of ALL CAPS upon everyone else.

--

Frederick Gotham
Oct 1 '06 #26
Frederick Gotham said:
Richard Heathfield posted:
>Apart from <snip Episode 4 of Babysisters' Club 2nd Seasonwhat you are
overlooking is that there is a large and influential code base which
uses ALL CAPS for type names - namely, the Win32 API.


And once again, the rule of thumb applies:

Don't do what Microsoft does.
What a stupid rule of thumb. That's called "biting off one's own nose to
spite one's face".
Just yesterday I was trying to persuade a C++ programmer to use ALL CAPS
for macros and for macros only -- I thought a C programmer would be
convinced much more easily given how they use macros on a much more
regular basis.
*Nobody* uses macros on a regular basis. Look up "regular". It simply
doesn't apply to source code. And good C programmers tend to use macros
sparingly.
>And in fact there is never any confusion, since type names and macros
are rarely if ever used in contexts where they might conceivably be
confused.

I can think of one problem off-hand:

typedef int *MyType;
#define MY_TYPE int*
But only brainless people would use a #define to create a synonym for int *,
and the fix is simple:

typedef int *MY_TYPE; /* i.e. remove the brainlessness */

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Oct 1 '06 #27
Elijah Cardon wrote:
"Michael Mair" <Mi**********@invalid.invalidwrote
>>Elijah Cardon wrote:
>>>"Michael Mair" <Mi**********@invalid.invalidwrote
Elijah Cardon wrote:

>Let's say I have m dice having n sides, such that n^m is not going to
>bust int as a datatype. With m=4 and n=6, an outcome might be {2, 5, 1,
>2}. What is a good way to represent this in c so that I can check cases
>by brute force? EC
>>#include <stdio.h>

int countSumOccurrences(int n, int m, int sum);
void countSumOccurrences_Rec(int n, int m, int sum, int *pCount);

int main (void)
{
int i;
for (i = 1; i <= 5; ++i)
printf("%d 6 sided dices; occurrence of sum %d: %d times\n",
i, 2*i, countSumOccurrences(6, i, 2*i));
return 0;
}

int countSumOccurrences(int n, int m, int sum)
{
int count = 0;
countSumOccurrences_Rec(n, m, sum, &count);
return count;
}

void countSumOccurrences_Rec(int n, int m, int sum, int *pCount)
{
#define VALUE_ADJUSTMENT(v) ((v)+1)
if (m == 1) {
if (sum >= VALUE_ADJUSTMENT(0) && sum < VALUE_ADJUSTMENT(n)) {
++*pCount;
}
}
else if (m 1) {
int i;
for (i = 0; i < n && i <= sum; ++i) {
countSumOccurrences_Rec(n, m - 1,
sum - VALUE_ADJUSTMENT(i), pCount);
}
}
}
`---

Note that you can always get rid of a recursion via using a stack.
You probably want to get rid of the VALUE_ADJUSTMENT in this case.

This is the line I wanted to take this in, but I gotta get my head around
the notions of recursion and stack depth. To that I end I ask this
question:
long factorial(int n) {
if (n == 1)
return 1;
return n * factorial(n - 1);
}

What is the stack depth as a function of n? If you look at the discussion
in chp 10 of _C Unleashed_, it follows the execution of this source. At the
end, there are n-1 paragraphs that begin:
Back on line ....
, so I think the stack depth is n-1 . If I'm wrong that it's near n, I
don't see how stack depth could be less than (n-1)! . EC
I now have got back my copy of C Unleashed, so I know what you mean:
You have essentially the same structure as above:
if (m == 1)
do something to *pCount;
else if (m 1)
hand it to the same function with (m-1)
i.e. you have the same stack depth as for the factorial() function.
The loop is merely decoration as it will not change the stack depth.
It changes the stack's contents, though:
Let's take the second run of the loop in main()
- The "first level call" to countSumOccurrences_Rec() issues
a "second level call" for i = 0, 1, 2, 3, 4.
- The stack depth for each of the "second level calls" is the same
but you have different i values and, consequently, different sum
values in the call stack
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Oct 1 '06 #28
Elijah Cardon wrote:
[snip when something boils down to null]
#include <stdio.h>

int countSomething(int n, int dummy_from_main);
void enum_rec(int n, int m, int sum, int *pCount);

int main (void)
{
int i;
for (i = 1; i <= 5; ++i)
printf("%d 6 sided dice; summed to george %d times\n",
i, countSomething(6, i));
return 0;
}

int countSomething(int n, int dummy_from_main)
dummy_from_main?
Not a good name for something that actually is evaluated in
enum_rec()...
{
int count = 0;
int george;

george = 5;

enum_rec(n, dummy_from_main, george, &count);
return count;
}

void enum_rec(int n, int m, int sum, int *pCount)
{
#define VALUE_ADJUSTMENT(v) ((v)+1)
if (m == 1) {
if (sum >= VALUE_ADJUSTMENT(0) && sum < VALUE_ADJUSTMENT(n)) {
++*pCount;
}
}
else if (m 1) {
int i;
for (i = 0; i < n && i <= sum; ++i) {
enum_rec(n, m - 1,
sum - VALUE_ADJUSTMENT(i), pCount);
}
}
}
I've hacked up this remarkable source from Mr. Mair. He cooked it up to
order faster than I get my meals. The actual conditions I'm testing require
that I do comparisons within the n-tuple.

This n-tuple has to be lurking in the recursive function. The value
adjustment part is clearly what we do in c to make up for lesser minds not
having made the range {1,2,3,4,5,0}, but, hey, they were trying.
Note that the VALUE_ADJUSTMENT part was not intended to be permanent.
As I do not know how you want to represent your ideas and initially
gave the impression that storing the respective permutations had to
take place in as little storage as possible, I went with my original
suggestion of using n-adic numbers. In the above example, it is clearly
unnecessary but may not be so in other examples.
The specific conditions I test are the following:
if n-tuple contains a one, then it's an x;
if n-tuple contains a five, then it's an x;
if n-tuple has three numbers alike, then it's an x;
Note that up to now, you had m-tuples; changing notation in
mid-discussion can lead to some irritation for the involved parties ;-)
~x's are o's;
Preliminary thoughts:
Okay, so you have n >= 5 if starting at 1 and n >= 6 if starting at
0. If you have m 2*(n-2), then you guaranteedly have an x (as you
clearly exhausted 2 occurrences of digits neither one nor five).

For fixed n, you still could use the above approach if you replace
sum by a struct with "x indicators" evaluated when you are at the
bottom.
struct {
int hasOne;
int hasFive;
int numberOfTwos;
....
}
In fact, for your example, an array n of int is sufficient to count
the occurrences of the numbers. At bottom level, you increase count
if array[i] is >= 1 or >= 3, respectively. The structure can take
indicators for more complex situations, though. Note that there is
a difference between passing the structure and passing a pointer
to it. Remember subtracting indicators after having passed the
structure/array with adjusted indicators.

However, this programme structure does not at all fit your problem.
It is much more straightforward to explicitly generate each combination
and evaluate it:

int countSomething(int n, int m)
{
unsigned long numberOfPossibleTuples;
unsigned long currentTuple;
int *pExplicitTuple;
int i;
int retVal = 0;
/* Filter invalid input */
if (n <= 0 || m <= 0) {
return -1;
}
/* calculate pow(n, m) */
numberOfPossibleTuples = 1;
for (i = 0; i < m; ++i) {
/* Make sure unsigned long can contain pow(n,m) */
if (ULONG_MAX/n < numberOfPossibleTuples) {
return -2;
}
numberOfPossibleTuples
}
/* give us enough "digits" */
pExplicitTuple = malloc(m * sizeof *pExplicitTuple);
if (NULL == pExplicitTuple) {
return -3;
}

/* Now, nothing can go wrong */
for (currentTuple = 0;
currentTuple < numberOfPossibleTuples;
++currentTuple)
{
#define VALUE_ADJUSTMENT(v) ((v)+1)
unsigned long temp = currentTuple;
/* introduce your auxiliary variables here */
for (i = 0; i < m; ++i) {
pExplicitTuple[i] = VALUE_ADJUSTMENT(temp % m);
/* optional: evaluate pExplicitTuple[i] */
temp /= m;
}

/* evaluate pExplicitTuple, adjust retVal */
}
free(pExplicitTuple);
return retVal;
}

Note that the above is neither tested nor compiled. It ought to
suffice to get you started, though.
In this case, the VALUE_ADJUSTMENT is necessary as mapping from
the number over its n-adic representation (digits are temp%m) to
its final value in the explicit tuple.
The different negative return values indicate which kind of
error you encountered but can be tested with
ret = countSomething(....);
if (ret < 0) {
fprintf(stderr, "Heu me miserum\n");
}
else {
/*use ret*/
}

One obvious problem is signed integer overflow on retVal.
The obvious solution is changing countSomething to
int countSomething(int m, int n, unsigned long *pCount);
which returns 0 on success and something else on failure.
On success, *pCount is the number of "x"es.
Another thing is that we already have to calculate pow(n,m),
so we may as well give it back:
int countSomething(int m,
int n,
unsigned long *pCount,
unsigned long *pNumberOfTuples);
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Oct 1 '06 #29

"Michael Mair" <Mi**********@invalid.invalidwrote in message
news:4o************@individual.net...
Elijah Cardon wrote:
<snipped main>
>int countSomething(int n, int dummy_from_main)

dummy_from_main?
Not a good name for something that actually is evaluated in
enum_rec()...
That I called it by that name shows where I was on the learning curve. I
changed this to dimension. By the time I get it kicked out the door, it
might be dimension_array_entry_driver_thing .
>{
int count = 0;
int george;

george = 5;

enum_rec(n, dummy_from_main, george, &count);
return count;
}
I couldn't induce you to say, "take out george?"
>void enum_rec(int n, int m, int sum, int *pCount)
{
#define VALUE_ADJUSTMENT(v) ((v)+1)
if (m == 1) {
if (sum >= VALUE_ADJUSTMENT(0) && sum < VALUE_ADJUSTMENT(n)) {
++*pCount;
}
}
else if (m 1) {
int i;
for (i = 0; i < n && i <= sum; ++i) {
enum_rec(n, m - 1,
sum - VALUE_ADJUSTMENT(i), pCount);
}
}
}
I've hacked up this remarkable source from Mr. Mair. He cooked it up to
order faster than I get my meals. The actual conditions I'm testing
require that I do comparisons within the n-tuple.

This n-tuple has to be lurking in the recursive function. The value
adjustment part is clearly what we do in c to make up for lesser minds
not having made the range {1,2,3,4,5,0}, but, hey, they were trying.

Note that the VALUE_ADJUSTMENT part was not intended to be permanent.
As I do not know how you want to represent your ideas and initially
gave the impression that storing the respective permutations had to
take place in as little storage as possible, I went with my original
suggestion of using n-adic numbers. In the above example, it is clearly
unnecessary but may not be so in other examples.
I think VALUE_ADJUSTMENT is an extraordinarily important feature of this
prog. You'll notice on my post that I will have cut it out completely, but
that's because I have to take it down to its control structures for me to
get my head around it. We prattle on about portability and re-use around
here. I think this construct enhances both.
>The specific conditions I test are the following:
if n-tuple contains a one, then it's an x;
if n-tuple contains a five, then it's an x;
if n-tuple has three numbers alike, then it's an x;

Note that up to now, you had m-tuples; changing notation in
mid-discussion can lead to some irritation for the involved parties ;-)
If I hadn't made the error, I'd be furious with the person who did.
Clearly, we're talking about m-tuples in this prog. I don't feel like
talking about m-tuples, though, since there is a large literature on
n-tuples. I might revise the original post with respect to m and n .

>~x's are o's;

Preliminary thoughts:
Okay, so you have n >= 5 if starting at 1 and n >= 6 if starting at
0. If you have m 2*(n-2), then you guaranteedly have an x (as you
clearly exhausted 2 occurrences of digits neither one nor five).

For fixed n, you still could use the above approach if you replace
sum by a struct with "x indicators" evaluated when you are at the
bottom.
struct {
int hasOne;
int hasFive;
int numberOfTwos;
....
}
In fact, for your example, an array n of int is sufficient to count
the occurrences of the numbers. At bottom level, you increase count
if array[i] is >= 1 or >= 3, respectively. The structure can take
indicators for more complex situations, though. Note that there is
a difference between passing the structure and passing a pointer
to it. Remember subtracting indicators after having passed the
structure/array with adjusted indicators.

However, this programme structure does not at all fit your problem.
It is much more straightforward to explicitly generate each combination
and evaluate it:

int countSomething(int n, int m)
{
unsigned long numberOfPossibleTuples;
unsigned long currentTuple;
int *pExplicitTuple;
int i;
int retVal = 0;
/* Filter invalid input */
if (n <= 0 || m <= 0) {
return -1;
}
/* calculate pow(n, m) */
numberOfPossibleTuples = 1;
for (i = 0; i < m; ++i) {
/* Make sure unsigned long can contain pow(n,m) */
if (ULONG_MAX/n < numberOfPossibleTuples) {
return -2;
}
numberOfPossibleTuples
}
/* give us enough "digits" */
pExplicitTuple = malloc(m * sizeof *pExplicitTuple);
if (NULL == pExplicitTuple) {
return -3;
}

/* Now, nothing can go wrong */
for (currentTuple = 0;
currentTuple < numberOfPossibleTuples;
++currentTuple)
{
#define VALUE_ADJUSTMENT(v) ((v)+1)
unsigned long temp = currentTuple;
/* introduce your auxiliary variables here */
for (i = 0; i < m; ++i) {
pExplicitTuple[i] = VALUE_ADJUSTMENT(temp % m);
/* optional: evaluate pExplicitTuple[i] */
temp /= m;
}

/* evaluate pExplicitTuple, adjust retVal */
}
free(pExplicitTuple);
return retVal;
}

Note that the above is neither tested nor compiled. It ought to
suffice to get you started, though.
In this case, the VALUE_ADJUSTMENT is necessary as mapping from
the number over its n-adic representation (digits are temp%m) to
its final value in the explicit tuple.
The different negative return values indicate which kind of
error you encountered but can be tested with
ret = countSomething(....);
if (ret < 0) {
fprintf(stderr, "Heu me miserum\n");
}
else {
/*use ret*/
}

One obvious problem is signed integer overflow on retVal.
The obvious solution is changing countSomething to
int countSomething(int m, int n, unsigned long *pCount);
which returns 0 on success and something else on failure.
On success, *pCount is the number of "x"es.
Another thing is that we already have to calculate pow(n,m),
so we may as well give it back:
int countSomething(int m,
int n,
unsigned long *pCount,
<snipped a little too much>
Most of this is over my head. A problem that I'm having right now is that
I'm not getting much help from my debugger. I think it's probably because
stepping through, in, over statements with recursion has a different beat.
When I see assembly, I know I've misstepped, and I've seen it at the end of
my every good idea. Latest version compiles but doesn't behave:
#include <stdio.h>

long countSomething(int n, int dimension, int *pa);
void enum_rec(int n, int m, int *pa);

int main (void)
{
int i;
int a[7], *pa;
pa = a;
for (i = 1; i <= 7; ++i)
printf("%d 6 sided dice; counter is %ld times\n",
i, countSomething(7, i, pa));
return 0;
}

long countSomething(int n, int dimension, int *pa)
{
long count = 0;
/* we can evaluate a[] here
and decide whether to count it */
enum_rec(n, dimension, pa);

printf("count is %ld \n", count);
return count;
}

void enum_rec(int n, int m, int *pa)
{

if (m == 1) {

}
else if (m 1) {

int i;

for (i = 0; i < n ; ++i) {
enum_rec(n, m - 1, pa);
}
}
}

My latest great idea is to use the recursive calls to populate an array of
seven ints. Yes, this will, with a six-sided die, bust int as a datatype.
BTW, what is the format specifier for a long in fprintf? I can look at the
table in K&R all night and not figure it out.

Somewhere in the function enum_rec , this a[] will get populated and then
called by the function countSomething , where one can use all the high level
features he wants to make decisions. Memory is not a scarce resource. EC
Oct 2 '06 #30

"Michael Mair" <Mi**********@invalid.invalidwrote in message
news:4o************@individual.net...
Elijah Cardon wrote:
>"Michael Mair" <Mi**********@invalid.invalidwrote
<snip>
>This is the line I wanted to take this in, but I gotta get my head around
the notions of recursion and stack depth. To that I end I ask this
question:
long factorial(int n) {
if (n == 1)
return 1;
return n * factorial(n - 1);
}

What is the stack depth as a function of n? If you look at the
discussion in chp 10 of _C Unleashed_, it follows the execution of this
source. At the end, there are n-1 paragraphs that begin:
Back on line ....
, so I think the stack depth is n-1 . If I'm wrong that it's near n, I
don't see how stack depth could be less than (n-1)! . EC

I now have got back my copy of C Unleashed, so I know what you mean:
You have essentially the same structure as above:
if (m == 1)
do something to *pCount;
else if (m 1)
hand it to the same function with (m-1)
i.e. you have the same stack depth as for the factorial() function.
The loop is merely decoration as it will not change the stack depth.
It changes the stack's contents, though:
Let's take the second run of the loop in main()
- The "first level call" to countSumOccurrences_Rec() issues
a "second level call" for i = 0, 1, 2, 3, 4.
- The stack depth for each of the "second level calls" is the same
but you have different i values and, consequently, different sum
values in the call stack
I think that this response is partially based on the understanding that sum
values were relevant to this question, and this relies on OP.

Q2) We look at two recursive functions that are identical except that
where, e.g. one says long factorial(n){ as above }and the other long
factorial(n, m){ as follows }where n does the same darn thing and is an
analog to m, but m=42 so that we force our computer to remember a bunch of
constants, just to be jerks in a Gedankenexperiment. They will have the
same number of "level calls" but the second stack will have the same number
of entries that are a function of n, plus a like number of 42's on the
stack. What can be said about the stack depth? Can one talk of stack
breadth? EC
Oct 2 '06 #31

"Elijah Cardon" <in*****@invalid.netwrote in message
news:12*************@corp.supernews.com...
>
"Spiros Bousbouras" <sp****@gmail.comwrote in message
news:11**********************@e3g2000cwe.googlegro ups.com...
>Elijah Cardon wrote:
>>Where I have the comment, I could test for whether the dummies add to
seven and keep a counter of those that do, and those that don't. I
would
then have the probability I'm looking for.

What probability are you looking for ? You still
haven't explained what problem you're trying to
solve.
I've seen people play dice before and certainly recall hours of dice in my
hands for gaming purposes. I found myself in a situation, where I was not
only playing a dice game I'd never played before, apparently, it's called
"dice," and found myself attracted to certain aspects of the game.

Getting a one or a five means you get to roll again. So, for the purpose
of detremining whether you can roll again, you can map the six-sided die
onto the three-sided die. Someone wondered aloud what the chances are of
rolling again with 2 dice. I saw a picture in my head that looked like:
_____________
| x | o | o |
-------------
| x | o | o |
-------------
| x | x | x |
_____________
I said ,"five ninths."

Later, I'm trying to sleep, and wonder how it would look in a higher
dimension. The next would be like a Rubic's cube. First I saw x's
heading out along the orthogonals, but that would make 11 out of 27 cubes
x's, and your odds don't go down, so that was wrong. I decided I needed
to add the plane: 9 cubes to the 2 planes of residuals 9+2*5=19 x's out of
27. I verified this number from first principles.

And with 4 dimensions? I think you add the cube to twice the residual:
27+2(19)=65 out of 81. It's getting a little tedious to verify by hand.
EC
news:12*************@corp.supernews.com...
Conjecture verified in fortran. I'd bet dollars to donuts that this holds
in higher dimensions. EC
Oct 2 '06 #32

"Frederick Gotham" <fg*******@SPAM.comwrote in message
news:Zs*******************@news.indigo.ie...
Richard Heathfield posted:
>Apart from <snip Episode 4 of Babysisters' Club 2nd Seasonwhat you are
overlooking is that there is a large and influential code base which
uses ALL CAPS for type names - namely, the Win32 API.


And once again, the rule of thumb applies:

Don't do what Microsoft does.
People who know a lot about computers often like to make jokes at the
expense of Bill Gates and his software company.
Don't let that fool you into thinking that these reflect their real opinions
about Microsoft. Microsoft are the leading consumer software company in the
world, arguably the leading software company full stop.
--
www.personal.leeds.ac.uk/~bgy1mm
freeware games to download.


Oct 7 '06 #33
Malcolm posted:
People who know a lot about computers often like to make jokes at the
expense of Bill Gates and his software company.
Don't let that fool you into thinking that these reflect their real
opinions about Microsoft.

No fooling required, it _does_ reflect my real opinion.

I use Microsoft software all the time, and it rarely crashes so I find it
quite useful. What I don't like, however, is the programming snippets you
find on MSDN, things like "ZeroMemory" which render non-portable, code which
could otherwise be perfectly portable!

--

Frederick Gotham
Oct 7 '06 #34

"Frederick Gotham" <fg*******@SPAM.comwrote in message
news:v5*******************@news.indigo.ie...
Malcolm posted:
>People who know a lot about computers often like to make jokes at the
expense of Bill Gates and his software company.
Don't let that fool you into thinking that these reflect their real
opinions about Microsoft.


No fooling required, it _does_ reflect my real opinion.

I use Microsoft software all the time, and it rarely crashes so I find it
quite useful. What I don't like, however, is the programming snippets you
find on MSDN, things like "ZeroMemory" which render non-portable, code
which
could otherwise be perfectly portable!
Most PC programs don't need to be ported to other platforms. It certainly
isn't in Microsoft's interests for them to be ported to other platforms.
If your real opinion is that Microsoft is incompetent, as opposed to making
a joke, then I'm afraid you don't know very much about the computer
industry.
--
www.personal.leeds.ac.uk/~bgy1mm
freeware games to download.
Oct 7 '06 #35
Malcolm posted:
Most PC programs don't need to be ported to other platforms. It
certainly isn't in Microsoft's interests for them to be ported to other
platforms. If your real opinion is that Microsoft is incompetent, as
opposed to making a joke, then I'm afraid you don't know very much about
the computer industry.
Let's say that tomorrow, AMD announce that they've made a major
breakthrough in CPU technology, and that they have produced a 63.88 EHz CPU
which will go on the market in 2 months time. The CPU in question uses a
bit-pattern of all-one's for null pointers. If Microsoft had used:

struct MyStruct obj = {0};

instead of:

struct MyStruct obj;
ZeroMemory(&obj,sizeof obj);

, then they wouldn't have a problem.

The point I'm trying to get across is this:
Sure, there's certain things that you can't do portably... but if you
_can_ do it portably, then _do_ _it_ _portably_!

My major peeve with ZeroMemory is that I've seen no justification
whatsoever for its usage in the place of perfectly portable built-in
language functionality.

The executables that Microsoft turns out tend to be pretty good, not
crashing too often or anything. Their code is a different story.

--

Frederick Gotham
Oct 7 '06 #36
On Sat, 07 Oct 2006 10:13:47 GMT, in comp.lang.c , Frederick Gotham
<fg*******@SPAM.comwrote:
>What I don't like, however, is the programming snippets you
find on MSDN, things like "ZeroMemory" which render non-portable, code which
could otherwise be perfectly portable!
What one needs to bear in mind is that MSDN isn't a free programming
reference manual , its a free Microsoft product reference manual.
Oracle's online manuals are similarly full of oracle-isms that render
otherwise perfectly portable SQL nonportable.
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Oct 7 '06 #37
Mark McIntyre posted:
On Sat, 07 Oct 2006 10:13:47 GMT, in comp.lang.c , Frederick Gotham
<fg*******@SPAM.comwrote:
>>What I don't like, however, is the programming snippets you
find on MSDN, things like "ZeroMemory" which render non-portable, code
which could otherwise be perfectly portable!

What one needs to bear in mind is that MSDN isn't a free programming
reference manual , its a free Microsoft product reference manual.
Oracle's online manuals are similarly full of oracle-isms that render
otherwise perfectly portable SQL nonportable.

I don't think it would hurt for Microsoft to send their programmers on a one-
day course about portable programming. It would only take a matter of hours
to get them using things like the following:

struct MyStruct obj = {0};

--

Frederick Gotham
Oct 7 '06 #38
Frederick Gotham <fg*******@SPAM.comwrites:
My major peeve with ZeroMemory is that I've seen no justification
whatsoever for its usage in the place of perfectly portable built-in
language functionality.
Microsoft doesn't *want* programmers writing portable code. That's
the justification for ZeroMemory() and similar Microsoftisms.

It doesn't make technical sense, but it makes perfect business and
marketing sense (at least if such things are not contradictions in terms.)

Charlton
Oct 7 '06 #39
Charlton Wilbur posted:
>My major peeve with ZeroMemory is that I've seen no justification
whatsoever for its usage in the place of perfectly portable built-in
language functionality.

Microsoft doesn't *want* programmers writing portable code. That's
the justification for ZeroMemory() and similar Microsoftisms.

It doesn't make technical sense, but it makes perfect business and
marketing sense (at least if such things are not contradictions in terms.)

They have enough money to stop focusing on business, and start focusing on
what they actually would like to do. Bill Gates gives millions (if not
billions) to charity every year.

If they're greedy enough to write non-portable code for the sake of non-
portable code, you'd wouldn't expect them to be giving money to charity...

--

Frederick Gotham
Oct 7 '06 #40
Frederick Gotham <fg*******@SPAM.comwrites:
[...]
They have enough money to stop focusing on business, and start focusing on
what they actually would like to do. Bill Gates gives millions (if not
billions) to charity every year.

If they're greedy enough to write non-portable code for the sake of non-
portable code, you'd wouldn't expect them to be giving money to charity...
Bill Gates is not Microsoft. Bill Gates is an individual, who can do
whatever he likes with his own money. Microsoft is a business with a
fiduciary responsibility to its shareholders.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Oct 7 '06 #41
Keith Thompson posted:
Bill Gates is not Microsoft. Bill Gates is an individual, who can do
whatever he likes with his own money. Microsoft is a business with a
fiduciary responsibility to its shareholders.

Hmm... I think I just don't like business fullstop -- seems to do more harm
than good (except for giving you money and all that malarky...).

--

Frederick Gotham
Oct 7 '06 #42
"Frederick Gotham" <fg*******@SPAM.comwrote in message
>
I don't think it would hurt for Microsoft to send their programmers on a
one-
day course about portable programming. It would only take a matter of
hours
to get them using things like the following:

struct MyStruct obj = {0};
Which doesn't make it entirely obvious that the programmer's intent is to
initialise all elements to zero. Particularly if the reader isn't very
familiar with C.

I'm not saying you are wrong to say that your way is better. However the
matter isn't entirely clear cut.

--
www.personal.leeds.ac.uk/~bgy1mm
freeware games to download.
Oct 8 '06 #43

"Keith Thompson" <ks***@mib.orgwrote in message
news:ln************@nuthaus.mib.org...
Frederick Gotham <fg*******@SPAM.comwrites:
[...]
They have enough money to stop focusing on business, and start focusing
on
what they actually would like to do. Bill Gates gives millions (if not
billions) to charity every year.

If they're greedy enough to write non-portable code for the sake of non-
portable code, you'd wouldn't expect them to be giving money to
charity...
>
Bill Gates is not Microsoft. Bill Gates is an individual, who can do
whatever he likes with his own money.
True.
Microsoft is a business with a
fiduciary responsibility to its shareholders.
That's the theory, but it is not true in reality for any of the Fortune 500.
The reason is mutual funds. Ballmer is CEO. Gates is on the Board of
Directors. 14% of Microsoft stock is controlled by Gates and Ballmer.
(Interesting, Paul Allen isn't anywhere to be found in the ownership of
stock.) 67% of Microsoft is owned by Mutual funds. They own voting stock.
Three years after SEC rules to force mutual funds to reveal proxy votes, the
largest mutual funds vote in favor of management 95% of the time with the
industry as a whole voting in favor of management 74% of the time. (I would
assume 100% before July 2003 based on past Forbes articles...)
http://money.cnn.com/2006/03/28/news..._votes_ceopay/

NASDAQ's stock market (electronic transactions) caters to technology firms
which don't usually pay dividends. Also, it doesn't allow the short sales
of securities. On NYSE, a stock exchange, a stock's price can be driven
down by two forces: selling and shorting. It can be driven up (or held up)
by two forces: buying and dividends. Short selling and dividends help to
correct imbalances, usually short term, that aren't percieved or are ignored
by certain investors, usually long term. Unfortunately, a problem arises
when a NASDAQ security, like MSFT, begins paying a dividend. When the
buyers and sellers are roughly in balance, the dividend attracts more buyers
which upholds a certain price, but there is no counterbalancing force to
drive the price of the stock down if others recognize that it is actually
underperforming (i.e., no short selling). This creates an upward price
distortion on NASDAQ for dividend paying securities. Of course, the usual
method on NYSE to wrest corporate control from incompetent management is to
drive the stock price down by selling and shorting until it is delisted.
Without short selling, it is harder to delist a dividend paying NASDAQ
security. This insulates underperforming management from change. Due to
this, if MSFT was a NYSE security, it's value would be lower.

You could also study how Kerk Kerkorian, KKR, Leon Black, or Ronald
Perelman, etc. get control with small percentages of ownership.
Rod Pemberton
Oct 8 '06 #44
"Rod Pemberton" <do*********@bitfoad.cmmwrote in message
>
"Keith Thompson" <ks***@mib.orgwrote in message
news:ln************@nuthaus.mib.org...
>Frederick Gotham <fg*******@SPAM.comwrites:
[...]
They have enough money to stop focusing on business, and start focusing
on
what they actually would like to do. Bill Gates gives millions (if not
billions) to charity every year.

If they're greedy enough to write non-portable code for the sake of
non-
portable code, you'd wouldn't expect them to be giving money to
charity...
>>
Bill Gates is not Microsoft. Bill Gates is an individual, who can do
whatever he likes with his own money.

True.
>Microsoft is a business with a
fiduciary responsibility to its shareholders.

That's the theory, but it is not true in reality for any of the Fortune
500.
The reason is mutual funds. Ballmer is CEO. Gates is on the Board of
Directors. 14% of Microsoft stock is controlled by Gates and Ballmer.
(Interesting, Paul Allen isn't anywhere to be found in the ownership of
stock.) 67% of Microsoft is owned by Mutual funds. They own voting
stock.
Three years after SEC rules to force mutual funds to reveal proxy votes,
the
largest mutual funds vote in favor of management 95% of the time with the
industry as a whole voting in favor of management 74% of the time. (I
would
assume 100% before July 2003 based on past Forbes articles...)
http://money.cnn.com/2006/03/28/news..._votes_ceopay/

NASDAQ's stock market (electronic transactions) caters to technology firms
which don't usually pay dividends. Also, it doesn't allow the short sales
of securities. On NYSE, a stock exchange, a stock's price can be driven
down by two forces: selling and shorting. It can be driven up (or held
up)
by two forces: buying and dividends. Short selling and dividends help to
correct imbalances, usually short term, that aren't percieved or are
ignored
by certain investors, usually long term. Unfortunately, a problem arises
when a NASDAQ security, like MSFT, begins paying a dividend. When the
buyers and sellers are roughly in balance, the dividend attracts more
buyers
which upholds a certain price, but there is no counterbalancing force to
drive the price of the stock down if others recognize that it is actually
underperforming (i.e., no short selling). This creates an upward price
distortion on NASDAQ for dividend paying securities. Of course, the usual
method on NYSE to wrest corporate control from incompetent management is
to
drive the stock price down by selling and shorting until it is delisted.
Without short selling, it is harder to delist a dividend paying NASDAQ
security. This insulates underperforming management from change. Due to
this, if MSFT was a NYSE security, it's value would be lower.

You could also study how Kerk Kerkorian, KKR, Leon Black, or Ronald
Perelman, etc. get control with small percentages of ownership.
How boring.
To think that some people read this sort of stuff for a living.
--
www.personal.leeds.ac.uk/~bgy1mm
freeware games to download.
Oct 8 '06 #45
"Malcolm" <re*******@btinternet.comwrites:
"Frederick Gotham" <fg*******@SPAM.comwrote in message
>I don't think it would hurt for Microsoft to send their programmers
on a one- day course about portable programming. It would only take
a matter of hours to get them using things like the following:

struct MyStruct obj = {0};
Which doesn't make it entirely obvious that the programmer's intent is to
initialise all elements to zero. Particularly if the reader isn't very
familiar with C.

I'm not saying you are wrong to say that your way is better. However the
matter isn't entirely clear cut.
To a reader who isn't familiar with C, *nothing* in a C program is
goig to be entirely obvious.

It's obvious to me that "= {0}" initializes all elements to zero, and
it should now be obvious to everyone who reads this thread. I don't
know how widespread this idiom is, but IMHO it's a good one.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Oct 8 '06 #46

"Keith Thompson" <ks***@mib.orgwrote in message
news:ln************@nuthaus.mib.org...
"Malcolm" <re*******@btinternet.comwrites:
>"Frederick Gotham" <fg*******@SPAM.comwrote in message
>>I don't think it would hurt for Microsoft to send their programmers
on a one- day course about portable programming. It would only take
a matter of hours to get them using things like the following:

struct MyStruct obj = {0};
Which doesn't make it entirely obvious that the programmer's intent is to
initialise all elements to zero. Particularly if the reader isn't very
familiar with C.

I'm not saying you are wrong to say that your way is better. However the
matter isn't entirely clear cut.

To a reader who isn't familiar with C, *nothing* in a C program is
goig to be entirely obvious.

It's obvious to me that "= {0}" initializes all elements to zero, and
it should now be obvious to everyone who reads this thread. I don't
know how widespread this idiom is, but IMHO it's a good one.
Thats not true.
Show a Fortran programmer

x = x + y;

and he'll have no problem.

i++;

is pretty intutive to anyone bit a bit of common sense.

*ptr++ = x;

on the other hand is rather tricky. Its idiomatic and something you really
have to learn when writing C.

for(i=0; i < y, z; )

is perfectly good C, but the sort of construct that you hardly ever
encounter, and extremely likely to confuse. So there is a good case for
avoiding code like this.

str = {0};

you can argue either way. You could say that it is common and useful enough
to say that every reader must know it, or you could say that it is
confusing.
--
www.personal.leeds.ac.uk/~bgy1mm
freeware games to download.
Oct 8 '06 #47
"Malcolm" <re*******@btinternet.comwrites:
"Keith Thompson" <ks***@mib.orgwrote in message
news:ln************@nuthaus.mib.org...
>"Malcolm" <re*******@btinternet.comwrites:
>>"Frederick Gotham" <fg*******@SPAM.comwrote in message
I don't think it would hurt for Microsoft to send their programmers
on a one- day course about portable programming. It would only take
a matter of hours to get them using things like the following:

struct MyStruct obj = {0};

Which doesn't make it entirely obvious that the programmer's intent is to
initialise all elements to zero. Particularly if the reader isn't very
familiar with C.

I'm not saying you are wrong to say that your way is better. However the
matter isn't entirely clear cut.

To a reader who isn't familiar with C, *nothing* in a C program is
goig to be entirely obvious.

It's obvious to me that "= {0}" initializes all elements to zero, and
it should now be obvious to everyone who reads this thread. I don't
know how widespread this idiom is, but IMHO it's a good one.
Thats not true.
Show a Fortran programmer

x = x + y;

and he'll have no problem.

i++;

is pretty intutive to anyone bit a bit of common sense.

*ptr++ = x;

on the other hand is rather tricky. Its idiomatic and something you really
have to learn when writing C.

for(i=0; i < y, z; )

is perfectly good C, but the sort of construct that you hardly ever
encounter, and extremely likely to confuse.
Ok, I'm with you so far.
So there is a good case for
avoiding code like this.

str = {0};

you can argue either way. You could say that it is common and useful enough
to say that every reader must know it, or you could say that it is
confusing.
But I fail to see how you reach your conclusion about {0}.

An initializer of {0} is guaranteed to initialize all components of
the object to zero, converted to the appropriate type, recursively for
aggregates within aggregates. It's difficult to understand if you
don't happen to know this, but very easy to understand if you do
(e.g., for anyone who has read this thread).

And there is, as far as I know, no good alternative. You can declare
a static object with no initializer, and it achieves much the same
effect, but it's much less explicit.

It's simple, and it's clear once you understand it. I don't
understand why you think it should be avoided.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Oct 8 '06 #48
"Malcolm" <re*******@btinternet.comwrote:
"Frederick Gotham" <fg*******@SPAM.comwrote in message
And once again, the rule of thumb applies:

Don't do what Microsoft does.
People who know a lot about computers often like to make jokes at the
expense of Bill Gates and his software company.
Don't let that fool you into thinking that these reflect their real opinions
about Microsoft.
On the contrary, my statements about MS reflect my opinion of them fine.
Microsoft are the leading consumer software company in the
world, arguably the leading software company full stop.
Yes, but this is because of their legal and marketing departments, not
because of programming and quality control.

Richard
Oct 9 '06 #49

Malcolm <re*******@btinternet.comwrote in message
news:Zc********************@bt.com...
"Rod Pemberton" <do*********@bitfoad.cmmwrote in message
"Keith Thompson" <ks***@mib.orgwrote in message
news:ln************@nuthaus.mib.org...
Frederick Gotham <fg*******@SPAM.comwrites:
[...]
They have enough money to stop focusing on business, and start
focusing
on
what they actually would like to do. Bill Gates gives millions (if
not
billions) to charity every year.

If they're greedy enough to write non-portable code for the sake of
non-
portable code, you'd wouldn't expect them to be giving money to
charity...
>
Bill Gates is not Microsoft. Bill Gates is an individual, who can do
whatever he likes with his own money.
True.
Microsoft is a business with a
fiduciary responsibility to its shareholders.
That's the theory, but it is not true in reality for any of the Fortune
500.
The reason is mutual funds. Ballmer is CEO. Gates is on the Board of
Directors. 14% of Microsoft stock is controlled by Gates and Ballmer.
(Interesting, Paul Allen isn't anywhere to be found in the ownership of
stock.) 67% of Microsoft is owned by Mutual funds. They own voting
stock.
Three years after SEC rules to force mutual funds to reveal proxy votes,
the
largest mutual funds vote in favor of management 95% of the time with
the
industry as a whole voting in favor of management 74% of the time. (I
would
assume 100% before July 2003 based on past Forbes articles...)
http://money.cnn.com/2006/03/28/news..._votes_ceopay/

NASDAQ's stock market (electronic transactions) caters to technology
firms
which don't usually pay dividends. Also, it doesn't allow the short
sales
of securities. On NYSE, a stock exchange, a stock's price can be driven
down by two forces: selling and shorting. It can be driven up (or held
up)
by two forces: buying and dividends. Short selling and dividends help
to
correct imbalances, usually short term, that aren't percieved or are
ignored
by certain investors, usually long term. Unfortunately, a problem
arises
when a NASDAQ security, like MSFT, begins paying a dividend. When the
buyers and sellers are roughly in balance, the dividend attracts more
buyers
which upholds a certain price, but there is no counterbalancing force to
drive the price of the stock down if others recognize that it is
actually
underperforming (i.e., no short selling). This creates an upward price
distortion on NASDAQ for dividend paying securities. Of course, the
usual
method on NYSE to wrest corporate control from incompetent management is
to
drive the stock price down by selling and shorting until it is delisted.
Without short selling, it is harder to delist a dividend paying NASDAQ
security. This insulates underperforming management from change. Due
to
this, if MSFT was a NYSE security, it's value would be lower.

You could also study how Kerk Kerkorian, KKR, Leon Black, or Ronald
Perelman, etc. get control with small percentages of ownership.
How boring.
Not that it really matters here, but it wasn't just boring, it was also
insanely factually incorrect. I particularly enjoyed this ridiculous
statement:
NASDAQ's stock market (electronic transactions) caters to technology
firms
which don't usually pay dividends. Also, it doesn't allow the short
sales
of securities.
Take it from somebody who has shorted a LOT of NASDAQ stocks
over the last few years, NASDAQ definitely allows shorting.
To think that some people read this sort of stuff for a living.
That was just a typical whacko uninformed Usenet rant.
NOBODY reads that sort of stuff for a living. If I got paid
every time I read a Holocaust denial, an Illuminati conspiracy
theory, et. al., on Usenet, I'D be richer than Bill Gates...

---
William Ernest Reid

Oct 10 '06 #50

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: lawentzel | last post by:
I am new to PHP and am an avid RPG gamer. I am looking to use PhpMyChat to be able to game with friends all over the US. With that having been said, PhpMyChat seems to offer a lot of what I am...
4
by: dpp4669 | last post by:
I need help with writing a program to use randmax and the standard deviation when u roll the dice 10000 times I know you will need the standard dev. and the average where do i put the randmax and do...
17
by: Jose Durazo | last post by:
Hello, I'm doing an exercise to simulate rolling a pair of dice 36,000 times, then count and display how many times the simulation rolls each possible sum. For some reason each time I run my...
4
by: vegtard | last post by:
simple question. is it possible to write a script that rolls a six sided dice? if this is possible, is it possible to tell it to roll the six sided dice 4 times and ignore the dice that rolled...
2
by: sunnydude | last post by:
Anybody know how to write a 3 dice rolling program like this Sample output Welcome to the dice roller! First of all, please enter a seed for the random number generator. This should be a...
2
by: cowboyjeff05 | last post by:
the question is 1) build a Die class (6 sided). Then create a driver that tests your class. Start with one die in your driver then add a second die and notify the user and count when he or she rolls...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.