Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Nov 24th, 2007, 1:05 PM   #1
peaceofpi
hi: for(;;) goto hi;
 
peaceofpi's Avatar
 
Join Date: Jun 2006
Posts: 91
Rep Power: 3 peaceofpi is on a distinguished road
Send a message via AIM to peaceofpi Send a message via MSN to peaceofpi
Is there a better way to do this?

I'm recreating whatever things from algebra/trigonometry that I can think of as a learning exercise. I wanted to post the whole thing for feedback but I don't know how that'd go in this board (it is for support after all).

This function turns a degree measure into degrees, minutes, and seconds. It works fine but I want to know if there's a better way to put the results in one place rather than three stringstreams and three strings. I want the function to return a string because there are three numbers as an answer.

c++ Syntax (Toggle Plain Text)
  1. string deg2dms(double deg)
  2. {
  3. double n = deg;
  4. int degrees = (int)n;
  5. n -= degrees;
  6. n *= 60.0;
  7. int minutes = (int)n;
  8. n -= minutes;
  9. n *= 60.0;
  10. int seconds = (int)n;
  11. if ( (n - seconds) >= 0.5 )
  12. seconds += 1;
  13.  
  14. stringstream degss;
  15. stringstream minss;
  16. stringstream secss;
  17. string degstr;
  18. string minstr;
  19. string secstr;
  20. degss << degrees;
  21. minss << minutes;
  22. secss << seconds;
  23. degss >> degstr;
  24. minss >> minstr;
  25. secss >> secstr;
  26. return degstr + " " + minstr + " " + secstr;
  27. }
__________________
How do you play Religious Roulette?
Stand around in a circle and blaspheme till someone gets struck by lightning.
peaceofpi is offline   Reply With Quote
Old Nov 24th, 2007, 2:18 PM   #2
DaWei
Resident Grouch
 
DaWei's Avatar
 
Join Date: Jun 2005
Posts: 6,453
Rep Power: 10 DaWei is on a distinguished road
Re: Is there a better way to do this?

The use of stringstreams, in this instance, amounts to a presentation issue. You have to deal with that, make the conversions, fiddlefart around, and convert back to presentation.

Your code doesn't look half bad, but you're expecting all your operations to work properly and magically. Get a life. Things don't always work out. Test for success and take appropriate actions if something fails.

Anything less is the action of an unemployable newbie or a schlock. Choose your category. Your potential employer is entitled to disagree.
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code.
Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers
DaWei is offline   Reply With Quote
Old Nov 24th, 2007, 2:22 PM   #3
Arla
Hobbyist Programmer
 
Join Date: Mar 2005
Posts: 208
Rep Power: 4 Arla is on a distinguished road
Re: Is there a better way to do this?

Personally I'd probably create a structure to house the three separate values and return that from the function. Stringing them together to return just means you end up with an amalgamated text string that you would then probably need to deconstruct to use elsewhere.
Arla is offline   Reply With Quote
Old Nov 24th, 2007, 3:26 PM   #4
Jessehk
The Oblivious One
 
Jessehk's Avatar
 
Join Date: May 2005
Location: Ontario, Canada
Posts: 644
Rep Power: 4 Jessehk is on a distinguished road
Re: Is there a better way to do this?

Some people might think this is overcomplicated, but if you have Boost I like the Tuple library. It's specifically designed to make returning multple values from a function easier.

c++ Syntax (Toggle Plain Text)
  1. #include <iostream>
  2.  
  3. #include <boost/tuple/tuple.hpp>
  4.  
  5. typedef boost::tuple<int, int, int> ResultType;
  6.  
  7. ResultType deg2dms( double deg ) {
  8. double n = deg;
  9.  
  10. int degrees = static_cast<int>( n );
  11. n -= degrees;
  12. n *= 60.0;
  13.  
  14. int minutes = static_cast<int>( n );
  15. n -= minutes;
  16. n *= 60.0;
  17.  
  18. int seconds = static_cast<int>( n );
  19. if ( (n - seconds) >= 0.5 )
  20. seconds += 1;
  21.  
  22. return ResultType( degrees, minutes, seconds );
  23. }
  24.  
  25. int main() {
  26. ResultType result = deg2dms( 34.5 );
  27.  
  28. //Access each element
  29. //In this case, we're accessing the degrees
  30. std::cout << result.get<0>() << std::endl;
  31.  
  32. // Or, Something like this
  33. #define DEGREES 0
  34. #define MINUTES 1
  35. #define SECONDS 2
  36. std::cout << result.get<MINUTES>() << std::endl;
  37. }

I copied your algorithm, but converted it to use static_cast's instead. I can't comment on the algorithm itself.
__________________
Dr. Zoidberg: [ecstatic] I'm going to a movie... with FRIENDS!
Jessehk is offline   Reply With Quote
Old Nov 24th, 2007, 11:16 PM   #5
peaceofpi
hi: for(;;) goto hi;
 
peaceofpi's Avatar
 
Join Date: Jun 2006
Posts: 91
Rep Power: 3 peaceofpi is on a distinguished road
Send a message via AIM to peaceofpi Send a message via MSN to peaceofpi
Re: Is there a better way to do this?

Quote:
Originally Posted by DaWei
Your code doesn't look half bad
DaWei + praise = ?!

Quote:
Originally Posted by DaWei
(rest of it)
Phew, I thought I did a good job for a second!

Quote:
Originally Posted by Arla
Personally I'd probably create a structure to house the three separate values and return that from the function.
I'll see what I can do with that, but it's not making complete sense yet.

Jesse: Boost is nice (although I haven't gotten it to work yet) but I want to make something I can carry with me anywhere.
__________________
How do you play Religious Roulette?
Stand around in a circle and blaspheme till someone gets struck by lightning.
peaceofpi is offline   Reply With Quote
Old Nov 24th, 2007, 11:26 PM   #6
Arla
Hobbyist Programmer
 
Join Date: Mar 2005
Posts: 208
Rep Power: 4 Arla is on a distinguished road
Re: Is there a better way to do this?

Having done a bit of websurfing (sorry I use C# so didn't want to post code as my syntax would probably be a bit off) this site

http://www.cplusplus.com/doc/tutorial/classes.html

Seemed to have some good information on what I was meaning, create a class, with three int's in it (Degrees, Minutes and Seconds) and then have the function return your new class as it's result.
Arla is offline   Reply With Quote
Old Nov 24th, 2007, 11:45 PM   #7
peaceofpi
hi: for(;;) goto hi;
 
peaceofpi's Avatar
 
Join Date: Jun 2006
Posts: 91
Rep Power: 3 peaceofpi is on a distinguished road
Send a message via AIM to peaceofpi Send a message via MSN to peaceofpi
Re: Is there a better way to do this?

Well, I understand what you mean, but you can't return a class instance as a function result. Jesse's answer is basically what I want, but I was hoping for a solution within the standard headers.

edit: By the way, Jesse, I tried out the boost solution. It gave errors so I played around with the code (I've never used tuples or boost so it was guesswork) till it was satisfied:

c++ Syntax (Toggle Plain Text)
  1. typedef boost::tuples::tuple<int,int,int> tuple;
  2.  
  3. tuple deg2dms( double deg )
  4. {
  5. double n = deg;
  6.  
  7. int degrees = static_cast<int>( n );
  8. n -= degrees;
  9. n *= 60.0;
  10.  
  11. int minutes = static_cast<int>( n );
  12. n -= minutes;
  13. n *= 60.0;
  14.  
  15. int seconds = static_cast<int>( n );
  16. if ( (n - seconds) >= 0.5 )
  17. seconds += 1;
  18.  
  19. return tuple(degrees, minutes, seconds);
  20. }

Can't cout<<deg2dms(x); though, apparently there's no << for tuples.
__________________
How do you play Religious Roulette?
Stand around in a circle and blaspheme till someone gets struck by lightning.

Last edited by peaceofpi; Nov 25th, 2007 at 12:11 AM.
peaceofpi is offline   Reply With Quote
Old Nov 25th, 2007, 8:30 AM   #8
Jessehk
The Oblivious One
 
Jessehk's Avatar
 
Join Date: May 2005
Location: Ontario, Canada
Posts: 644
Rep Power: 4 Jessehk is on a distinguished road
Re: Is there a better way to do this?

Quote:
Originally Posted by peaceofpi View Post

Can't cout<<deg2dms(x); though, apparently there's no << for tuples.
c++ Syntax (Toggle Plain Text)
  1. #include "boost/tuple/tuple_io.hpp"

Which defines an operator<< that outputs things in the form
(x y z)

But if you really want to do it with standard headers, you should just make a custom struct and return it -- basically what Arla suggested.
__________________
Dr. Zoidberg: [ecstatic] I'm going to a movie... with FRIENDS!
Jessehk is offline   Reply With Quote
Old Nov 25th, 2007, 9:05 AM   #9
Jessehk
The Oblivious One
 
Jessehk's Avatar
 
Join Date: May 2005
Location: Ontario, Canada
Posts: 644
Rep Power: 4 Jessehk is on a distinguished road
Re: Is there a better way to do this?

Quote:
Originally Posted by peaceofpi View Post
Well, I understand what you mean, but you can't return a class instance as a function result.
Hold on a second. What do you mean?

c++ Syntax (Toggle Plain Text)
  1. #include <iostream>
  2.  
  3. class Heading {
  4. private:
  5. int degrees_;
  6. int minutes_;
  7. int seconds_;
  8. public:
  9. Heading( int degrees, int minutes, int seconds );
  10.  
  11. int degrees() const { return degrees_; }
  12. int minutes() const { return minutes_; }
  13. int seconds() const { return seconds_; }
  14. };
  15.  
  16. std::ostream &operator<<( std::ostream &os, const Heading &heading ) {
  17. os << "(" << heading.degrees() << ", " << heading.minutes() << ", " << heading.seconds() << ")";
  18. return os;
  19. }
  20.  
  21. Heading::Heading( int degrees, int minutes, int seconds ) :
  22. degrees_( degrees ),
  23. minutes_( minutes ),
  24. seconds_( seconds ) {}
  25.  
  26. Heading testFunction() {
  27. return Heading( 33, 5, 2 );
  28. }
  29.  
  30. int main() {
  31. Heading heading = testFunction();
  32.  
  33. std::cout << heading << std::endl;
  34. }

$ ./example
(33, 5, 2)

You are copying the instance on the return from the function (which does add overhead), but the same thing happens with Boost.Tuple. The only reason to use Boost.Tuple in this case in convenience.
__________________
Dr. Zoidberg: [ecstatic] I'm going to a movie... with FRIENDS!
Jessehk is offline   Reply With Quote
Old Nov 25th, 2007, 11:09 AM   #10
peaceofpi
hi: for(;;) goto hi;
 
peaceofpi's Avatar
 
Join Date: Jun 2006
Posts: 91
Rep Power: 3 peaceofpi is on a distinguished road
Send a message via AIM to peaceofpi Send a message via MSN to peaceofpi
Re: Is there a better way to do this?

Quote:
Originally Posted by Jessehk View Post
c++ Syntax (Toggle Plain Text)
  1. #include "boost/tuple/tuple_io.hpp"
That helps!

Oops, operator<< slipped my mind.

c++ Syntax (Toggle Plain Text)
  1. using namespace boost::tuples;
  2. tuple<int,string,int,string,int,string> deg2dms(double deg)
  3. {
  4. double n = deg;
  5.  
  6. int degrees = static_cast<int>(n);
  7. n -= degrees;
  8. n *= 60.0;
  9.  
  10. int minutes = static_cast<int>(n);
  11. n -= minutes;
  12. n *= 60.0;
  13.  
  14. int seconds = static_cast<int>(n);
  15. if ( (n - seconds) >= 0.5 )
  16. seconds += 1;
  17.  
  18. tuple<int,string,int,string,int,string> dms
  19. (degrees,"degrees,",minutes,"minutes,",seconds,"seconds");
  20. return dms;
  21. }
__________________
How do you play Religious Roulette?
Stand around in a circle and blaspheme till someone gets struck by lightning.

Last edited by peaceofpi; Nov 25th, 2007 at 11:23 AM.
peaceofpi is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 4:17 AM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC