0
votes

So I have a function in an app that needs to let the user calculate a trig function (sin,cos,tan) using radians OR degrees, and also to expect a returned value from inverse trig functions (asin,acos,atan) as either radians or degrees. is there any way to do this without building in a converter directly into the way they input something? what i am trying to avoid is having to convert: sin(45) to sin(dtor(45)) thanks!

4
im reffering to the built in compiler trig functions primarilySj.
Trig functions (indeed, all of math.h) are provided by the math library, not the compiler.Stephen Canon
Why don't you want to convert to radians?Andreas Brinck

4 Answers

2
votes

This should really be handled by the display / input routines in your app. Have a switchable mode to use either degrees or radians, and your IO routines either do the conversion or not depending on the mode. I mean, 90 degrees is pi/2 radians, just displayed using a dumb convention -- since they represent the same quantity, there shouldn't be any difference in how they are handled computationally, just a quirk of representation akin to localization.

Your actual calculation code then only has to support one mode (which should be radians).

0
votes

There isn't a way to change the way the functions operate.

A "solution" would be to re-make the interface, and do the conversions:

// for example
float sin(float pX)
{
    return std::sinf(d2r(pX));
}

And use that interface instead. Put it in a math:: namespace.

0
votes

Not sure there's any real way around it if you can accept both degrees and radians. There's no way to tell just from the input which units you're using. For example, sin(2) has a valid value for 2 degrees and 2 radians.

You have to do the appropriate conversion before inputting to the functions. (Or, you have to convert the output of the inverse trig functions if they want degrees.)

0
votes

I suggest using a modification of GMan's solution, and create a class containing member functions that are trig function wrappers, and which operate in degrees of radians depending on a mode variable.

class cTrig
{
    enum eTrigMode
    {
        DEGREES,
        RADIANS
    }

    cTrig( eTrigMode mode = DEGREES ) : m_mode(mode) {}

    void setMode( eTrigMode mode ) { m_mode = mode }


    double sin( double theta )
    {
        return std::sin( m_mode == DEGREES ? deg_to_rad(theta) : theta ) ;
    }

    // ... etc for all other trig functions
} ;

That way you can create either two cTrig objects with different modes, or one object and change mode as necessary. I'd go for the former:

cTrig degrees( cTrig::DEGREES ) ;
cTrig radians( cTrig::RADIANS ) ;

double a = degrees.sin( 90 ) ;
double b = ragians.sin( M_PI ) ;

I'd also include deg_to_rad and rad_to_deg as member functions of cTrig.

You could alternatively create cRadian and cDegree types and overload the functions for those types.