> Write a function
>
>double f( int c, double x );
>
> that will return either the sine or the logarithm of its
> second argument depending on whether it was called with a
> first argument 0 or 1, respectively (that is, 0 for sine and
> 1 for logarithm), but do not use any control statement (such
> as �if� or �while�) nor any operator with conditional
> evaluation (such as ?:, &&, ||).
>
> When the first argument is 0, the function must call
> (directly or indirectly) �sin� (math.h), but must not call
> (directly or indirectly) �log� (math.h). When the first
> argument is 1, the function must call �log�, but must not
> call �sin�.
>
> The definition of additional helper functions is allowed
> under the same restrictions as given above.
>
> (I believe that I could write such a function when the
> definition of additional helper functions is allowed, but I
> do not have an idea how to do it without additional functions.)
Create an array of pointers to functions. Initialize it so that
location 0 holds the pointer to sin, and location 1 holds the
pointer to log. Then function f returns fp[c](x). Getting the
syntax right will be a good exercise for you. Engrave this in
your mind: Using arrays of function pointers is a fundamental
concept in programming.
Richard Harter, c...@tiac.net
http://home.tiac.net/~cri, http://www.varinoma.com
It's not much to ask of the universe that it be fair;
it's not much to ask but it just doesn't happen.
> Write a function
>
> double f( int c, double x );
>
> that will return either the sine or the logarithm of its
> second argument depending on whether it was called with a
> first argument 0 or 1, respectively (that is, 0 for sine and
> 1 for logarithm), but do not use any control statement (such
> as >>if<< or >>while<<) nor any operator with conditional
> evaluation (such as ?:, &&, ||).
>
> When the first argument is 0, the function must call
> (directly or indirectly) >>sin<< (math.h), but must not call
> (directly or indirectly) >>log<< (math.h). When the first
> argument is 1, the function must call >>log<<, but must not
> call >>sin<<.
>
> The definition of additional helper functions is allowed
> under the same restrictions as given above.
>
> (I believe that I could write such a function when the
> definition of additional helper functions is allowed, but I
> do not have an idea how to do it without additional functions.)
#include <math.h>
double
f( int c, double x ){
return (double (*[])(double)){ (sin), (log) }[ c&1UL ]( x );
}
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>
double f(int c,double x) {
static double (*fns[])() = {sin,log};
return fns[c](x);
}
int main(argc,argv)
int argc;
char **argv;
{
assert(argc == 3);
int i = atoi(argv[1]);
double d = strtod(argv[2],NULL);
printf("Result of f(%d,%g) is: %g\n",i,d,f(i,d));
return 0;
}
--
(This discussion group is about C, ...)
Wrong. It is only OCCASIONALLY a discussion group
about C; mostly, like most "discussion" groups, it is
off-topic Rorsharch revelations of the childhood
traumas of the participants...
#include <math.h>
double f(int c, double x) {
typedef double (*Fptr)(double);
static const Fptr func[] = { sin, log };
return func[c](x);
}
--
Eric Sosman
eso...@ieee-dot-org.invalid
>
> #include <math.h>
>
> double
> f( int c, double x ){
> return (double (*[])(double)){ (sin), (log) }[ c&1UL ]( x );
> }
I took an
syntax error : '{'
under VC++,08
Ali
It doesn't support C99, which is the current C standard.
-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / usenet...@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
> Write a function
>
> double f( int c, double x );
>
> that will return either the sine or the logarithm of its second
> argument depending on whether it was called with a first argument 0 or
> 1, respectively (that is, 0 for sine and 1 for logarithm), but do not
> use any control statement (such as »if« or »while«) nor any operator
> with conditional evaluation (such as ?:, &&, ||).
{
return c * log(x) + (1 - c) * sin(x);
}
Sorry, I had skimmed the second paragraph of your post too quickly...
With slight loss of portability...
#include <math.h>
#include <stdio.h>
#include <stdint.h>
double f( int c, double x )
{
uintptr_t s = (uintptr_t)sin;
uintptr_t l = (uintptr_t)log;
double (*op)(double) = (double (*)(double))(s + (l-s)*c);
return op(x);
}
int main(void)
{
printf("%f\n", f(0, 3.14159/2));
printf("%f\n", f(1, 2.71828));
return 0;
}
--
Alan Curry
> r...@zedat.fu-berlin.de (Stefan Ram) writes:
>> 1 for logarithm), but do not use any control statement (such as ?if? or
>> ?while?) nor any operator with conditional evaluation (such as ?:, &&,
>> ||).
>
> The implementation using an array was also what I had in
> mind (even though I was mistakenly under the impression
> that I had to define two helper functions, due to a previous
> version of this exercise where this was necessary.)
>
> Of course, it would be very interesting if anyone could
> find a solution without using an array (I don't think that
> this can be done).
$ gcc -std=c99 -pedantic -Wall -Wextra -Wformat=2 -o sinlog sinlog.c -lm
$ ./sinlog
0.5 0
$ cat sinlog.c
#include <signal.h>
#include <math.h>
#include <assert.h>
#include <errno.h>
#include <stdio.h>
static double result,
arg;
static void
comp_sin(int sig)
{
assert(SIGTERM == sig);
result = sin(arg);
}
static void
comp_log(int sig)
{
assert(SIGINT == sig);
errno = 0;
result = log(arg);
assert(0 == errno);
}
static double
comp(int kind, double arg1)
{
assert(1 == (0 == kind) + (1 == kind));
arg = arg1;
raise((1 - kind) * SIGTERM + kind * SIGINT);
return result;
}
int
main(void)
{
{
void (*ret)(int);
ret = signal(SIGTERM, &comp_sin);
assert(SIG_ERR != ret);
ret = signal(SIGINT, &comp_log);
assert(SIG_ERR != ret);
}
(void)fprintf(stdout, "%g %g\n", comp(0, 3.141592654 / 6.0), comp(1, 1.0));
{
int ret;
ret = fflush(stdout);
assert(0 == ret);
}
return 0;
}
.
.
.
> Ali
(This is WAY off-topic, but did anyone else notice the date in the
quote? Besides being inaccurate - April 15 was 1 Iyar... - How'd you
do that, Ali?)
;-)
Marty
Here's a filthy, filthy dirty approach (I hope I've matched
the parentheses correctly(:
double f(int c, double x) {
return (double(*)(double)(void*)(((uintptr_t)
(void*)sin)^((((uintptr_t)(void*)sin)^
((uintptr_t)(void*)log))*c)))(x);
}
Unfortunately, it relies on the existence of uintptr_t (not
guaranteed) and on the non-portable operations of converting
function pointers to void* and back.
--
Eric Sosman
eso...@ieee-dot-org.invalid
Oh, drat! I mis-matched them. Here's a correction, and
I've also added a little bit of defensive coding:
double f(int c, double x) {
return ((double(*)(double))(void*)(((uintptr_t)
(void*)log)^((((uintptr_t)(void*)sin)^((uintptr_t)
(void*)log))*!c)))(x);
}
--
Eric Sosman
eso...@ieee-dot-org.invalid
i not understand well;
i find the exercise not useful, the answer too much complex;
the problem is not how to make begin the things easy, difficult;
but how difficult exercise can be easy or at last with a chance
of to be understood
The exercise is quite useful in various applications; although some of
the answers are unnecessarily complex and error-prone (such as the one
you quoted).
...
> double
> f( int c, double x ){
> return (double (*[])(double)){ (sin), (log) }[ c&1UL ]( x );
> }
Why 1UL instead of just 1U? Is there any particular reason for a long
index into an array with two elements?
--
Morris Keesan -- mke...@post.harvard.edu
> Write a function
>
> double f( int c, double x );
> .
> .
> .
#include <math.h>
f(int c, double x) {
double (*fun[])(double x) = {
sin,
log
};
return fun[c](x);
}
--
Burton Samograd
> On Thu, 15 Apr 2010 10:44:15 -0400, Tim Rentsch
> <t...@alumni.caltech.edu> wrote:
>
> ...
>> double
>> f( int c, double x ){
>> return (double (*[])(double)){ (sin), (log) }[ c&1UL ]( x );
>> }
>
> Why 1UL instead of just 1U? Is there any particular reason for a long
> index into an array with two elements?
Defensive coding reflex. If it isn't clear why just think
of it as 1U rather than 1UL.