newport_j

January 10th, 2011, 10:10 PM

I am trying to get a program to compile in both c and c++ and I am very close to success. It already compiles in c. The issue now is the function fmod. I list it below. As I said it compiles in c, but not in c++.

/*

* Copyright (c) 1989 The Regents of the University of California.

* All rights reserved.

*

* Redistribution and use in source and binary forms are permitted

* provided that: (1) source distributions retain this entire copyright

* notice and comment, and (2) distributions including binaries display

* the following acknowledgement: ``This product includes software

* developed by the University of California, Berkeley and its contributors''

* in the documentation or other materials provided with the distribution

* and in all advertising materials mentioning features or use of this

* software. Neither the name of the University nor the names of its

* contributors may be used to endorse or promote products derived

* from this software without specific prior written permission.

* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR

* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED

* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

*/

#ifndef lint

static char sccsid[] = "@(#)fmod.c 5.2 (Berkeley) 6/1/90";

#endif /* not lint */

/* fmod.c

*

* SYNOPSIS

*

* #include <math.h>

* double fmod(double x, double y)

*

* DESCRIPTION

*

* The fmod function computes the floating-point remainder of x/y.

*

* RETURNS

*

* The fmod function returns the value x-i*y, for some integer i

* such that, if y is nonzero, the result has the same sign as x and

* magnitude less than the magnitude of y.

*

* On a VAX or CCI,

*

* fmod(x,0) traps/faults on floating-point divided-by-zero.

*

* On IEEE-754 conforming machines with "isnan()" primitive,

*

* fmod(x,0), fmod(INF,y) are invalid operations and NaN is returned.

*

*/

#if !defined(vax) && !defined(tahoe)

extern int isnan(),finite();

#endif /* !defined(vax) && !defined(tahoe) */

extern double frexp(),ldexp(),fabs();

#ifdef TEST_FMOD

static double

_fmod(x,y)

#else /* TEST_FMOD */

double

fmod(x,y)

#endif /* TEST_FMOD */

double x,y;

{

int ir,iy;

double r,w;

if (y == (double)0

#if !defined(vax) && !defined(tahoe) /* per "fmod" manual entry, SunOS 4.0 */

|| isnan(y) || !finite(x)

#endif /* !defined(vax) && !defined(tahoe) */

)

return (x*y)/(x*y);

r = fabs(x);

y = fabs(y);

(void)frexp(y,&iy);

while (r >= y) {

(void)frexp(r,&ir);

w = ldexp(y,ir-iy);

r -= w <= r ? w : w*(double)0.5;

}

return x >= (double)0 ? r : -r;

}

#ifdef TEST_FMOD

extern long random();

extern double fmod();

#define NTEST 10000

#define NCASES 3

static int nfail = 0;

static void

doit(x,y)

double x,y;

{

double ro = fmod(x,y),rn = _fmod(x,y);

if (ro != rn) {

(void)printf(" x = 0x%08.8x %08.8x (%24.16e)\n",x,x);

(void)printf(" y = 0x%08.8x %08.8x (%24.16e)\n",y,y);

(void)printf(" fmod = 0x%08.8x %08.8x (%24.16e)\n",ro,ro);

(void)printf("_fmod = 0x%08.8x %08.8x (%24.16e)\n",rn,rn);

(void)printf("\n");

}

}

main()

{

register int i,cases;

double x,y;

srandom(12345);

for (i = 0; i < NTEST; i++) {

x = (double)random();

y = (double)random();

for (cases = 0; cases < NCASES; cases++) {

switch (cases) {

case 0:

break;

case 1:

y = (double)1/y; break;

case 2:

x = (double)1/x; break;

default:

abort(); break;

}

doit(x,y);

doit(x,-y);

doit(-x,y);

doit(-x,-y);

}

}

if (nfail)

(void)printf("Number of failures: %d (out of a total of %d)\n",

nfail,NTEST*NCASES*4);

else

(void)printf("No discrepancies were found\n");

exit(0);

}

#endif /* TEST_FMOD */

The output of this file is

srf_int2.c:107: error: call of overloaded ‘fmod(int&, int)’ is ambiguous

/usr/include/bits/mathcalls.h:188: note: candidates are: double fmod(double, double)

/usr/include/c++/4.2/cmath:268: note: long double std::fmod(long double, long double)

/usr/include/c++/4.2/cmath:264: note: float std::fmod(float, float)

btm_int2.c: In function ‘void BTM_INT2(double, double, double, double*, double, double, double*, double, double, double, double*, double*, double*, double*, double*, double*, double*, int*, ENV_DEF*)’:

btm_int2.c:129: error: call of overloaded ‘fmod(int&, int)’ is ambiguous

/usr/include/bits/mathcalls.h:188: note: candidates are: double fmod(double, double)

/usr/include/c++/4.2/cmath:268: note: long double std::fmod(long double, long double)

/usr/include/c++/4.2/cmath:264: note: float std::fmod(float, float)

There is no equivalent fmod in c so it compiles. Now when I try to compile in c++ with the g++ command, the output is as you see it above.

The functions that call fmod are now shown, but only the lines where fmod is called and used.

if( fmod(ITER,2) != 0 && fabs(ZDEL1) > 0.0 ){

/*Use the secant method.*/

RRAYd = RRAY1 - ZDEL1*(RRAY2-RRAY1)/(ZDEL2-ZDEL1);

} else {

/*Use the bisection method.*/

RRAYd = 0.5*(RRAY1+RRAY2)

and

if( fmod(ITER,2) != 0 && fabs(ZDEL1) > 0 ){

/*Use the secant method.*/

*RRAYd = RRAY1 - ZDEL1 * (RRAY2 - RRAY1) / (ZDEL2 - ZDEL1);

}else{

/*Use the bisection method.*/

*RRAYd = (RRAY1 + RRAY2) /2;

I believe that it is complaining because fmod is not prototyped. In c you do not have to prototype, but in c++ you must.

However, there is something more at work here. In that c++, I think has an equivalent fmod, which is also named fmod.

1. Now is it a good idea to redefine fmod like this or should I choose another name for my modular operation-say fmodd?

2. It does not like that I use integer variables. It gives three choices or candidates as it calls them. None of them are integer. I know that one can do modular arithmetic using real numbers, but what is wrong with using integers - it seems a logical, reasonable way to go? Yet it does not allow them.

Any help appreciated. Thanx in advance.

Newport_j

/*

* Copyright (c) 1989 The Regents of the University of California.

* All rights reserved.

*

* Redistribution and use in source and binary forms are permitted

* provided that: (1) source distributions retain this entire copyright

* notice and comment, and (2) distributions including binaries display

* the following acknowledgement: ``This product includes software

* developed by the University of California, Berkeley and its contributors''

* in the documentation or other materials provided with the distribution

* and in all advertising materials mentioning features or use of this

* software. Neither the name of the University nor the names of its

* contributors may be used to endorse or promote products derived

* from this software without specific prior written permission.

* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR

* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED

* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

*/

#ifndef lint

static char sccsid[] = "@(#)fmod.c 5.2 (Berkeley) 6/1/90";

#endif /* not lint */

/* fmod.c

*

* SYNOPSIS

*

* #include <math.h>

* double fmod(double x, double y)

*

* DESCRIPTION

*

* The fmod function computes the floating-point remainder of x/y.

*

* RETURNS

*

* The fmod function returns the value x-i*y, for some integer i

* such that, if y is nonzero, the result has the same sign as x and

* magnitude less than the magnitude of y.

*

* On a VAX or CCI,

*

* fmod(x,0) traps/faults on floating-point divided-by-zero.

*

* On IEEE-754 conforming machines with "isnan()" primitive,

*

* fmod(x,0), fmod(INF,y) are invalid operations and NaN is returned.

*

*/

#if !defined(vax) && !defined(tahoe)

extern int isnan(),finite();

#endif /* !defined(vax) && !defined(tahoe) */

extern double frexp(),ldexp(),fabs();

#ifdef TEST_FMOD

static double

_fmod(x,y)

#else /* TEST_FMOD */

double

fmod(x,y)

#endif /* TEST_FMOD */

double x,y;

{

int ir,iy;

double r,w;

if (y == (double)0

#if !defined(vax) && !defined(tahoe) /* per "fmod" manual entry, SunOS 4.0 */

|| isnan(y) || !finite(x)

#endif /* !defined(vax) && !defined(tahoe) */

)

return (x*y)/(x*y);

r = fabs(x);

y = fabs(y);

(void)frexp(y,&iy);

while (r >= y) {

(void)frexp(r,&ir);

w = ldexp(y,ir-iy);

r -= w <= r ? w : w*(double)0.5;

}

return x >= (double)0 ? r : -r;

}

#ifdef TEST_FMOD

extern long random();

extern double fmod();

#define NTEST 10000

#define NCASES 3

static int nfail = 0;

static void

doit(x,y)

double x,y;

{

double ro = fmod(x,y),rn = _fmod(x,y);

if (ro != rn) {

(void)printf(" x = 0x%08.8x %08.8x (%24.16e)\n",x,x);

(void)printf(" y = 0x%08.8x %08.8x (%24.16e)\n",y,y);

(void)printf(" fmod = 0x%08.8x %08.8x (%24.16e)\n",ro,ro);

(void)printf("_fmod = 0x%08.8x %08.8x (%24.16e)\n",rn,rn);

(void)printf("\n");

}

}

main()

{

register int i,cases;

double x,y;

srandom(12345);

for (i = 0; i < NTEST; i++) {

x = (double)random();

y = (double)random();

for (cases = 0; cases < NCASES; cases++) {

switch (cases) {

case 0:

break;

case 1:

y = (double)1/y; break;

case 2:

x = (double)1/x; break;

default:

abort(); break;

}

doit(x,y);

doit(x,-y);

doit(-x,y);

doit(-x,-y);

}

}

if (nfail)

(void)printf("Number of failures: %d (out of a total of %d)\n",

nfail,NTEST*NCASES*4);

else

(void)printf("No discrepancies were found\n");

exit(0);

}

#endif /* TEST_FMOD */

The output of this file is

srf_int2.c:107: error: call of overloaded ‘fmod(int&, int)’ is ambiguous

/usr/include/bits/mathcalls.h:188: note: candidates are: double fmod(double, double)

/usr/include/c++/4.2/cmath:268: note: long double std::fmod(long double, long double)

/usr/include/c++/4.2/cmath:264: note: float std::fmod(float, float)

btm_int2.c: In function ‘void BTM_INT2(double, double, double, double*, double, double, double*, double, double, double, double*, double*, double*, double*, double*, double*, double*, int*, ENV_DEF*)’:

btm_int2.c:129: error: call of overloaded ‘fmod(int&, int)’ is ambiguous

/usr/include/bits/mathcalls.h:188: note: candidates are: double fmod(double, double)

/usr/include/c++/4.2/cmath:268: note: long double std::fmod(long double, long double)

/usr/include/c++/4.2/cmath:264: note: float std::fmod(float, float)

There is no equivalent fmod in c so it compiles. Now when I try to compile in c++ with the g++ command, the output is as you see it above.

The functions that call fmod are now shown, but only the lines where fmod is called and used.

if( fmod(ITER,2) != 0 && fabs(ZDEL1) > 0.0 ){

/*Use the secant method.*/

RRAYd = RRAY1 - ZDEL1*(RRAY2-RRAY1)/(ZDEL2-ZDEL1);

} else {

/*Use the bisection method.*/

RRAYd = 0.5*(RRAY1+RRAY2)

and

if( fmod(ITER,2) != 0 && fabs(ZDEL1) > 0 ){

/*Use the secant method.*/

*RRAYd = RRAY1 - ZDEL1 * (RRAY2 - RRAY1) / (ZDEL2 - ZDEL1);

}else{

/*Use the bisection method.*/

*RRAYd = (RRAY1 + RRAY2) /2;

I believe that it is complaining because fmod is not prototyped. In c you do not have to prototype, but in c++ you must.

However, there is something more at work here. In that c++, I think has an equivalent fmod, which is also named fmod.

1. Now is it a good idea to redefine fmod like this or should I choose another name for my modular operation-say fmodd?

2. It does not like that I use integer variables. It gives three choices or candidates as it calls them. None of them are integer. I know that one can do modular arithmetic using real numbers, but what is wrong with using integers - it seems a logical, reasonable way to go? Yet it does not allow them.

Any help appreciated. Thanx in advance.

Newport_j