economizing with functions that do the same thing

Y

Your Uncle

About a month ago, Heathfield posted the peudosource for random permuting
from TAOCP. It was all of maybe five lines. You needed to be able to do
two things: be able to get a random number in a range and swap. I
remembered that Dan Pop taught me to write the swap as a macro. With forum
improvements, this became:
#define SWAP(m, n) (tmp = (m), (m) = (n), (n) = tmp)
The random number comes, again with forum improvements:
int rand_in_range(int m, int n)
{
/*seed srand in main */
/* [m, n] is range */
int roll_again_threshold, divisor, result, tmp, offset, num_results;

if (m>n) SWAP(m, n);
offset = m;
num_results = n - m + 1;

if (num_results == 1) {
return m;
}


roll_again_threshold = RAND_MAX - RAND_MAX%num_results;
divisor = roll_again_threshold/num_results;

do {
result = rand();
} while (result >= roll_again_threshold);
result /= divisor;
return offset + result;
}
But then I starting thinking, and that is, of course, where the trouble
began. I posted elsewhere, and I don't think you need much of a language
background to get the gist of it:
Ich habe zwei Funktionen bei file scope erklaert:
void permute_string(char * m, int n);
void permute_int(int * m, int n);
Sie tun das genau Gleiche, allerdings erstere mit chars und letztere mit
ints. Wie werden diese Funktionen Eine?
Basically, how do I take 2 functions that differ only in the type they
operate on, and make them one? I was advised to use:
void permute (void *data, int n, size_t elsize);
that could be called for an array a with
permute(a, sizeof a / sizeof a[0], sizeof a[0]);
Is this going to work? If it isn't, then the idea is mine. If it will then
it's Erich Fruehstueck's. cheers, furunculus
 
D

Dann Corbit

Your Uncle said:
About a month ago, Heathfield posted the peudosource for random permuting
from TAOCP. It was all of maybe five lines. You needed to be able to do
two things: be able to get a random number in a range and swap. I
remembered that Dan Pop taught me to write the swap as a macro. With
forum improvements, this became:
#define SWAP(m, n) (tmp = (m), (m) = (n), (n) = tmp)
The random number comes, again with forum improvements:
int rand_in_range(int m, int n)
{
/*seed srand in main */
/* [m, n] is range */
int roll_again_threshold, divisor, result, tmp, offset, num_results;

if (m>n) SWAP(m, n);
offset = m;
num_results = n - m + 1;

if (num_results == 1) {
return m;
}


roll_again_threshold = RAND_MAX - RAND_MAX%num_results;
divisor = roll_again_threshold/num_results;

do {
result = rand();
} while (result >= roll_again_threshold);
result /= divisor;
return offset + result;
}
But then I starting thinking, and that is, of course, where the trouble
began. I posted elsewhere, and I don't think you need much of a language
background to get the gist of it:
Ich habe zwei Funktionen bei file scope erklaert:
void permute_string(char * m, int n);
void permute_int(int * m, int n);
Sie tun das genau Gleiche, allerdings erstere mit chars und letztere mit
ints. Wie werden diese Funktionen Eine?
Basically, how do I take 2 functions that differ only in the type they
operate on, and make them one? I was advised to use:
void permute (void *data, int n, size_t elsize);
that could be called for an array a with
permute(a, sizeof a / sizeof a[0], sizeof a[0]);
Is this going to work? If it isn't, then the idea is mine. If it will
then it's Erich Fruehstueck's. cheers, furunculus

Use a template. Oh, wait. That's C++.
;-)

The problem with the void pointer thingy is that the function taking the
void pointer will not know what is being passed in. So you are stuck with a
whole bunch of callback functions.

If I understand what you want to do, that is.
 
R

Richard Heathfield

Your Uncle said:
About a month ago, Heathfield posted the peudosource for random permuting
from TAOCP.

No, I didn't. I did, however, post some shuffling pseudocode and source,
just a few days ago, which was not taken from TAOCP.
It was all of maybe five lines. You needed to be able to do
two things: be able to get a random number in a range and swap.
Yes.

I
remembered that Dan Pop taught me to write the swap as a macro.

I find that surprising. I'd have thought Dan Pop would have more sense.
With
forum improvements, this became:
#define SWAP(m, n) (tmp = (m), (m) = (n), (n) = tmp)

That's fine as far as it goes, provided tmp exists and is of the appropriate
type.
The random number comes, again with forum improvements:
int rand_in_range(int m, int n)
{
/*seed srand in main */
/* [m, n] is range */
int roll_again_threshold, divisor, result, tmp, offset, num_results;

if (m>n) SWAP(m, n);
offset = m;
num_results = n - m + 1;

if (num_results == 1) {
return m;
}


roll_again_threshold = RAND_MAX - RAND_MAX%num_results;
divisor = roll_again_threshold/num_results;

do {
result = rand();
} while (result >= roll_again_threshold);
result /= divisor;
return offset + result;
}

That's ghastly, but I can see what you're doing. Presumably this bit works
fine, so let's move on.
But then I starting thinking, and that is, of course, where the trouble
began. I posted elsewhere, and I don't think you need much of a language
background to get the gist of it:
Ich habe zwei Funktionen bei file scope erklaert:

"I explained two functions with file scope", according to Babelfish.
void permute_string(char * m, int n);
void permute_int(int * m, int n);
Sie tun das genau Gleiche, allerdings erstere mit chars und letztere mit
ints. Wie werden diese Funktionen Eine?

"They do that exactly resemble, however first with chars and the latters
with ints. How do these functions become one?"
Basically, how do I take 2 functions that differ only in the type they
operate on, and make them one? I was advised to use:
void permute (void *data, int n, size_t elsize);
that could be called for an array a with
permute(a, sizeof a / sizeof a[0], sizeof a[0]);
Is this going to work?

It can be made to work.
If it isn't, then the idea is mine. If it will
then it's Erich Fruehstueck's.

I doubt whether it's either your idea or Erich Fruehstueck's.

Incidentally, this isn't really permuting. It's shuffling.

Here is a generic swapping function:

void swap(void *s, void *t, size_t len)
{
unsigned char *u = s;
unsigned char *v = t;
unsigned char tmp;
while(len--)
{
tmp = *u;
*u++ = *v;
*v++ = tmp;
}
}

Here is a generic shuffling function:

void shuffle(void *s, size_t size, size_t len)
{
unsigned char *t = s;
unsigned char *u = s;
size_t i = 0;
size_t r = 0;
for(i = 0; i < len; i++)
{
r = (len - i) * rand() / (RAND_MAX + 1.0);
swap(t + size * i, u + size * r, size);
}
}
 
Y

Your Uncle

Dann Corbit said:
Your Uncle said:
About a month ago, Heathfield posted the peudosource for random permuting
from TAOCP. It was all of maybe five lines. You needed to be able to do
two things: be able to get a random number in a range and swap. I
remembered that Dan Pop taught me to write the swap as a macro. With
forum improvements, this became:
#define SWAP(m, n) (tmp = (m), (m) = (n), (n) = tmp)
The random number comes, again with forum improvements:
int rand_in_range(int m, int n)
{
/*seed srand in main */
/* [m, n] is range */
int roll_again_threshold, divisor, result, tmp, offset, num_results;

if (m>n) SWAP(m, n);
offset = m;
num_results = n - m + 1;

if (num_results == 1) {
return m;
}


roll_again_threshold = RAND_MAX - RAND_MAX%num_results;
divisor = roll_again_threshold/num_results;

do {
result = rand();
} while (result >= roll_again_threshold);
result /= divisor;
return offset + result;
}
But then I starting thinking, and that is, of course, where the trouble
began. I posted elsewhere, and I don't think you need much of a language
background to get the gist of it:
Ich habe zwei Funktionen bei file scope erklaert:
void permute_string(char * m, int n);
void permute_int(int * m, int n);
Sie tun das genau Gleiche, allerdings erstere mit chars und letztere mit
ints. Wie werden diese Funktionen Eine?
Basically, how do I take 2 functions that differ only in the type they
operate on, and make them one? I was advised to use:
void permute (void *data, int n, size_t elsize);
that could be called for an array a with
permute(a, sizeof a / sizeof a[0], sizeof a[0]);
Is this going to work? If it isn't, then the idea is mine. If it will
then it's Erich Fruehstueck's. cheers, furunculus

Use a template. Oh, wait. That's C++.
;-)
I'm on thin ice with topicality, so I better condemn this outrageous
suggestion.

The problem with the void pointer thingy is that the function taking the
void pointer will not know what is being passed in. So you are stuck with
a whole bunch of callback functions.
I'm not sure what that means. Maybe we could make a better trivial example:

void print_a_char(char);
void print_an_int(int);
would be definitions and then
print_a_char(char g){ printf(" %c\n", g) }
print_an_int(int g){ printf(" %d\n", g) }
Does that clarify, obfuscate, or just bore? cheers, f
 
I

Ian Collins

Your said:
I'm not sure what that means. Maybe we could make a better trivial example:

void print_a_char(char);
void print_an_int(int);
would be definitions and then
print_a_char(char g){ printf(" %c\n", g) }
print_an_int(int g){ printf(" %d\n", g) }
Does that clarify, obfuscate, or just bore? cheers, f
For a trivial example, the overhead would outweigh the benifit of a
generic function.

For a more complex example, you are stuck with the function not knowing
the type passed in and the compiler not being able to check whether the
passed types are supported.
 
Y

Your Uncle

Richard Heathfield said:
Your Uncle said:


No, I didn't. I did, however, post some shuffling pseudocode and source,
just a few days ago, which was not taken from TAOCP.
I'm experiencing a wonderful time-dilation while rehabbing an injury. Why
doesn't time drag when you're golfing?
I find that surprising. I'd have thought Dan Pop would have more sense.
He does, but you have to remember he was talking to me.
That's fine as far as it goes, provided tmp exists and is of the
appropriate
type.
I'm surprised at how often this has caused me trouble.
The random number comes, again with forum improvements:
int rand_in_range(int m, int n)
{
/*seed srand in main */
/* [m, n] is range */
int roll_again_threshold, divisor, result, tmp, offset, num_results;

if (m>n) SWAP(m, n);
offset = m;
num_results = n - m + 1;

if (num_results == 1) {
return m;
}


roll_again_threshold = RAND_MAX - RAND_MAX%num_results;
divisor = roll_again_threshold/num_results;

do {
result = rand();
} while (result >= roll_again_threshold);
result /= divisor;
return offset + result;
}

That's ghastly, but I can see what you're doing. Presumably this bit works
fine, so let's move on.
But then I starting thinking, and that is, of course, where the trouble
began. I posted elsewhere, and I don't think you need much of a language
background to get the gist of it:
Ich habe zwei Funktionen bei file scope erklaert:

"I explained two functions with file scope", according to Babelfish.
void permute_string(char * m, int n);
void permute_int(int * m, int n);
Sie tun das genau Gleiche, allerdings erstere mit chars und letztere mit
ints. Wie werden diese Funktionen Eine?

"They do that exactly resemble, however first with chars and the latters
with ints. How do these functions become one?"
Basically, how do I take 2 functions that differ only in the type they
operate on, and make them one? I was advised to use:
void permute (void *data, int n, size_t elsize);
that could be called for an array a with
permute(a, sizeof a / sizeof a[0], sizeof a[0]);
Is this going to work?

It can be made to work.
If I fail, will a possible reason for this be that it was ill-advised to do
so as opposed to just having two awfully similar functions?

I doubt whether it's either your idea or Erich Fruehstueck's.

Incidentally, this isn't really permuting. It's shuffling.

Here is a generic swapping function:

void swap(void *s, void *t, size_t len)
{
unsigned char *u = s;
unsigned char *v = t;
unsigned char tmp;
while(len--)
{
tmp = *u;
*u++ = *v;
*v++ = tmp;
}
}
I'll just snipe this wholesale, thank you.
Here is a generic shuffling function:

void shuffle(void *s, size_t size, size_t len)
{
unsigned char *t = s;
unsigned char *u = s;
size_t i = 0;
size_t r = 0;
for(i = 0; i < len; i++)
{
r = (len - i) * rand() / (RAND_MAX + 1.0);
swap(t + size * i, u + size * r, size);
}
}
I'll need to take a closer look at this. Thanks and cheers, f
 
R

Richard Heathfield

Your Uncle said:
If I fail, will a possible reason for this be that it was ill-advised to
do so as opposed to just having two awfully similar functions?

No. If you fail, it will be because you didn't manage to copy and paste the
code I gave you. :)
 
K

Keith Thompson

[snip]

I've recently seen (or thought I saw) evidence that "Your Uncle",
"Frederick Gotham", and "Joe Smith" are the same person, posting under
different aliases. I recently asked you about this in the "wit's end"
thread, and you never answered.

Are "Your Uncle", "Frederick Gotham", and "Joe Smith" (or any two of
them) in fact the same person? If so, I ask you to pick a single
handle and stick with it. I don't care whether it's your real name or
not; pseudonyms are perfectly acceptable. But if you keep changing
identities, it makes the discussion more difficult to follow, with no
benefit.
 
P

pete

Your said:
He does, but you have to remember he was talking to me.

I'm surprised at how often this has caused me trouble.

This is what I use:

#define SWAP(A, B, T) \
((void)(*(T) = *(A), *(A) = *(B), *(B) = *(T)))
 
M

Michael Mair

Richard said:
Your Uncle said:

I find that surprising. I'd have thought Dan Pop would have more sense.

It is a matter of context:
http://groups.google.de/group/comp.lang.c/browse_frm/thread/63c5271ccb9149a/
somewhere around message 70 in the tree view; starting at
<[email protected]> may suffice.
"Merrill & Michele" was the name the OP went by back then.

Dan Pop IIRC mainly argued against my suggestions of how to
"fix" the macro and pointed out how they fell short -- in
the light of that, the original swap macro was a better
solution for him.
Disclaimer: It is easily possible that I misremember -- I
just tracked down the thread but did not read it.


<snip>


Cheers
Michael
 
Y

Your Uncle

"Richard Heathfield"
Your Uncle said:
No. If you fail, it will be because you didn't manage to copy and paste
the
code I gave you. :)
It doesn't do me a lick of good to snipe source, germane to what I know,
which I do not understand. You had a generic swap posted, and I frankly
can't quite remember what else, but in response to the what else, I wrote:
/* pruefer.c */
# include "big four.h"
#define MILL (.001)
int fu(int, int);
int main(void)
{# include <stdio.h>
unsigned long g, un_long_dummy, r = s = 0;
int m = 3, n = 17000, mean_less_one, t;
printf("taunt::continue: Y/N");
if (getchar == 'N') break;
mean_less_one = (n - m) / 2;
/* you wonder why Reiner einer
mistrusts syntax here until you reaun_long_dummyze
every time I read a unix jerk my
'\''s and '/''s switch */
/* control */
for (un_long_dummy = 0; un_long_dummy < g; ++ un_long_dummy)
{
t = fu(m, n);
if (t <= mean_less_one) ++ r;
else ++ s;
}
printf("r is %ul while s is %ul\n", r, s);
return 0;
}
int fu(int m, int n)
{
return n;
}
/* end .c begin .h */
/* bigfour.h */
# include <stdio.h>
# include <stdlib.h>
# include <math.h>
# include <time.h>
/* end bigfour.h */
Does this look like C? The question is meant to proceed along two lines:
q1) If I approach my compiler with this, will cl.exe give me
errors/warnings. q2) I conjecture that "bigfour.h" is not included in the c
standard. Given that the possibly non-standard header includes ONLY
standard headers, what can a person say about it? cheers, furunculus
 
Y

Your Uncle

/* pruefer.c */
# include "big four.h"
#define MILL (.001)
int fu(int, int);
int main(void)
{
unsigned long g, un_long_dummy, r = s = 0;
int m = 3, n = 17000, mean_less_one, t;
printf("taunt::continue: Y/N");
if (getchar == 'N') break;
mean_less_one = (n - m) / 2;

/* control */
for (un_long_dummy = 0; un_long_dummy < g; ++

un_long_dummy)
{
t = fu(m, n);
if (t <= mean_less_one) ++ r;
else ++ s;
}
printf("r is %ul while s is %ul\n", r, s);
return 0;
}
int fu(int m, int n)
{
return n;
}
/* repost pruefer.c */
 
F

Frederick Gotham

Keith Thompson posted:

I've recently seen (or thought I saw) evidence that "Your Uncle",
"Frederick Gotham", and "Joe Smith" are the same person, posting under
different aliases. I recently asked you about this in the "wit's end"
thread, and you never answered.

Are "Your Uncle", "Frederick Gotham", and "Joe Smith" (or any two of
them) in fact the same person? If so, I ask you to pick a single
handle and stick with it. I don't care whether it's your real name or
not; pseudonyms are perfectly acceptable. But if you keep changing
identities, it makes the discussion more difficult to follow, with no
benefit.


I only post to this newsgroup as "Frederick Gotham".

If you like my posts, then that's brilliant -- I enjoy posting here, and
it's a great hobby for me. If you don't like my posts, or if you suspect I
am posting under other aliases, I don't care to discuss the topic.
 
Y

Your Uncle

"Keith Thompson"
"Your Uncle"
I've recently seen (or thought I saw) evidence that "Your Uncle",
"Frederick Gotham", and "Joe Smith" are the same person, posting under
different aliases. I recently asked you about this in the "wit's end"
thread, and you never answered.

Are "Your Uncle", "Frederick Gotham", and "Joe Smith" (or any two of
them) in fact the same person? If so, I ask you to pick a single
handle and stick with it. I don't care whether it's your real name or
not; pseudonyms are perfectly acceptable. But if you keep changing
identities, it makes the discussion more difficult to follow, with no
benefit.
I think this topic could be reasonably addressed in the full-contact
arena: comp.std.c . I believe it addresses the normative underpinnings of
the C programming language. I know it affects the way this island is
perceived. Perception is important.
I am not a sufficiently strong voice to do much right now. It interrupts
my perception that I'm a guy on my back. I am not one lick sarcastic here.
Think of how much clc says "dont toppost" as opposed to "your source is
compost" .
Keith, my newsreaders have a lot more to say about my identity than do I.
gruss, furunculus
 
K

Keith Thompson

Your Uncle said:
"Keith Thompson"
I think this topic could be reasonably addressed in the full-contact
arena: comp.std.c . I believe it addresses the normative underpinnings of
the C programming language. I know it affects the way this island is
perceived. Perception is important.
I am not a sufficiently strong voice to do much right now. It interrupts
my perception that I'm a guy on my back. I am not one lick sarcastic here.
Think of how much clc says "dont toppost" as opposed to "your source is
compost" .
Keith, my newsreaders have a lot more to say about my identity than do I.
gruss, furunculus

All right, then.

"Your Uncle"
"Frederick Gotham"
"Joe Smith"

A recommendation for the killfiles of those who use them.
 
K

Kenny McCormack

All right, then.

"Your Uncle" "Frederick Gotham"

ITYM, Frank (Not Fred, he used to work for CBS) Silvermann
"Joe Smith"

A recommendation for the killfiles of those who use them.

You are a man on a mission from God, aren't you?

I have to ask, in all seriousness, what's the percentage/what's the
psychic benefit you get from slamming people you don't understand?
 
P

pete

Kenny McCormack wrote:
I have to ask, in all seriousness, what's the percentage/what's the
psychic benefit you get from slamming people you don't understand?

Slamming people you don't understand,
is your entire purpose on this newsgroup,
isn't it?
 
F

Frederick Gotham

Keith Thompson posted:

All right, then.

"Your Uncle"
"Frederick Gotham"
"Joe Smith"

A recommendation for the killfiles of those who use them.


Hey hey hey what's all this about?!

I post under one name and one name only.

If you're THAT certain that I have an affiliation with the others you
have mentioned... then PROVE IT, rather than sabotaging the enjoyable
experience a sincere poster has on this newsgroup.

I expect an apology from you once you have confirmed my innocence --
anything less would portray you as a malicious, inhospitable person.

You make a great contribution to the group, Keith, and I regularly find
your posts interesting -- but your elevated status on this group does not
warrant the malicious behaviour you have displayed.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,149
Members
46,695
Latest member
StanleyDri

Latest Threads

Top