Jump to content

Need a little help with Stroustrup's Drills from Programming Principles and Practice

- - - - -

  • Please log in to reply
13 replies to this topic

#1
crookedmouth

crookedmouth

    Newbie

  • Members
  • Pip
  • 7 posts
Hello everyone, I am attempting to learn C++ "on my own". I realize that I am going to need some pointers along the way so I may be posting here a bit.

First a little introduction.

I have only a beginner background in Java and a long time ago I dabbled in BASIC but I find C++ to be a very desirable and fun language.

I decided to start from the beginning with Stroustrup's Programming Principles and Practice Using C++, then I am going to tackle Accelerated C++ and C++ Primer 4th Edition. I am very excited to finally be on this journey.

So far I have been doing well but I am only on Chapter 4. I was surprised to find that I had completed the previous drills and exorcizes similarly to what he was looking for. I like Stroustrup's straight forward approach and there is not a lot of hand-holding.

Anyway here are the Chapter 4 drills:

Quote

1. Write a program that consists of a while-loop that (each time around the
loop) reads in two ints and then prints them. Exit the program when a
terminating '||' is entered.
2. Change the program to write out "the smaller value is:" followed by the
smaller of the numbers and the larger value is: followed by the larger value.
3. Augment the program so that it writes the line the numbers are equal
(only) if they are equal.
4. Change the program so that it uses doubles instead of ints.
5. Change the program so that it writes out the numbers are almost equal
after writing out which is the larger and the smaller if the two numbers
differ by less than 1.0/10000000.

I am having trouble with number 5 and the "almost equal" part. Does 1.0/10000000 mean 0.0000001? If so wouldn't a double not be able to handle such a small figure?

Please don't make fun of me. My code skills are as I said very basic. Here is what I have so far:

#include "std_lib_facilities.h"


int main()


{

	double val1=0;

	double val2=0;

	


	while (cin>>val1>>val2)	{		//read

		cout<<"\nInput\n----------\n"<<val1<<"  "<<val2<<"\n\n";

	if (val1<val2)

		cout<<"The smaller value is:"<<val1<<"\n\n"<<"The larger value is:"<<val2<<"\n\n";

	else if (val1==val2)

		cout<<"The numbers are equal.\n\n";

	else if (val1-val2<1.0/10000000)

		cout<<"The numbers are almost equal.\n\n";

	else

		cout<<"The smaller value is:"<<val2<<"\n"<<"The larger value is:"<<val1<<"\n\n";

	}

	

}

Obviously my attempt to check for "almost equal" is way off but everything we have covered so far in the book doesn't help. Usually he will reference a later chapter to help me find the solution.

Thank you for your attention and for any pointers that you could give me.

#2
WingedPanther

WingedPanther

    A spammer's worst nightmare

  • Moderators
  • 16,831 posts
  • Location:Upstate, South Carolina
  • Programming Language:C, C++, PL/SQL, Delphi/Object Pascal, Pascal, Transact-SQL, Others
  • Learning:Java, C#, PHP, JavaScript, Lisp, Fortran, Haskell, Others
Your almost equal condition has an issue, you are assuming that val1>val2 in that comparison. You really want to test for equality first, almost equality (in both directions) second, and then different last.
Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog

#3
Flying Dutchman

Flying Dutchman

    Programming God

  • Members
  • PipPipPipPipPipPipPip
  • 889 posts
  • Location:::1
About double data type precision:

Double precision floating-point format - Wikipedia, the free encyclopedia said:

With the 52 bits of the fraction significand appearing in the memory format, the total precision is therefore 53 bits (approximately 16 decimal digits
You can read more about double here
A conclusion is where you got tired of thinking.
#define class struct    // All is public.

#4
crookedmouth

crookedmouth

    Newbie

  • Members
  • Pip
  • 7 posts
Thanks for the quick replies.

WingedPanther said:

Your almost equal condition has an issue, you are assuming that val1>val2 in that comparison. You really want to test for equality first, almost equality (in both directions) second, and then different last.

I was going on the assumption that val1-val2 would be the same as val2-val1 in regards to whether it was less then 1.0/10000000 or not. I understand that it would be negative in one instance.

I realize this is not very pretty but this change seems to make it work.

else if (val1-val2<1.0/10000000 && val2-val1<1.0/10000000)


However as you pointed out this doesn't allow for the program to express that the two doubles are almost equal and yet one is still larger and the other smaller.

Flying Dutchman said:

About double data type precision:

You can read more about double here

Thank you, that explains a lot. I always thought that double meant two decimal places.

However the above program only prints five numbers after the decimal. It can process it but when I print to screen, 1.1111113 becomes 1.11111.

Is this normal?

#5
Flying Dutchman

Flying Dutchman

    Programming God

  • Members
  • PipPipPipPipPipPipPip
  • 889 posts
  • Location:::1
You can set number of decimal places with setprecision manipulator. To do this, you will need to include iomanip header and you can find them listed here.
A conclusion is where you got tired of thinking.
#define class struct    // All is public.

#6
Alexander

Alexander

    It's Science!

  • Moderators
  • 4,118 posts
  • Location:Vancouver, Eh! Cleverness: 200
I believe you could replace
val1-val2<1.0/10000000 && val2-val1<1.0/10000000
with
fabs(val1-val2) < 1.0/10000000
On the notion that 5-2 = 3, 2-5 = -3, fabs returns the absolute value of the double (floating point absolute)

Just know you may need to include <math.h> and possibly <stdlib.h> and also compile the program with the -lm switch to utilize the math library.
Be sure to read the updated FAQ! || Health is achieved through the same 10,000 steps.
If a suggested code/method fails, informing us is less important than telling us why or what errors occurred.

#7
crookedmouth

crookedmouth

    Newbie

  • Members
  • Pip
  • 7 posts
This forum is fantastic. Quick, helpful and unassuming pointers!

Flying Dutchman said:

You can set number of decimal places with setprecision manipulator. To do this, you will need to include iomanip header and you can find them listed here.
Thank you again, that did the trick. I set the precision to 9 and output is accurate.

Alexander said:

I believe you could replace
val1-val2<1.0/10000000 && val2-val1<1.0/10000000
with
fabs(val1-val2) < 1.0/10000000
On the notion that 5-2 = 3, 2-5 = -3, fabs returns the absolute value of the double (floating point absolute)

Just know you may need to include <math.h> and possibly <stdlib.h> and also compile the program with the -lm switch to utilize the math library.

Thank you, that is much more tidy and works perfectly. I only needed to include <math.h> but most likely <stdlib.h> is included in Stroustrup's multipurpose "std_lib_facilities.h".

Hopefully I can tackle more on my own for awhile because at this rate it's going to take me awhile! I wish I had someone around my town who was as excited about programming as I was. Thankfully there is this forum but I don't want to become a nuisance. So far I have learned much here and thank you all for your guidance. I am more hungry to learn C++ then ever.

#8
crookedmouth

crookedmouth

    Newbie

  • Members
  • Pip
  • 7 posts
Hello again. I haven't had a lot of time to program lately and I'm having a hard time with this problem.

Quote

8. Reject values without units or with "illegal" representations of units, such
as y, yard , meter, km, and gallons.

My code works but I can't seem to figure out how to implement the above criteria.

I am trying to use only what I have learned so far. I tried a nested while with a Boolean but it just kept looping.

If I input an illegal unit it actually doesn't accept it but it continues through the loop giving the output "Sorry, that is an illegal unit." and then "Is neither larger nor smaller."

This sort of works but I would like to make it ask for the input again. Also if I leave off the unit after the value it doesn't go through the loop. It hangs until I give it another input.

A few pointers would be much appreciated.

Here is my ugly code.

#include "std_lib_facilities.h"

#include <iomanip>

#include <math.h>

int main()


{

	double val1=0;

	double val2=0;

	double smallest=0;

	double largest=0;

	double temp_largest=0;

	double temp_smallest=0;


	int i=0;

	string unit;

	string smallest_unit;

	string largest_unit;

	bool valid_unit=false;


	cout<<"Input a measurement followed by a unit (cm, m, in or ft):";


	while (cin>>val1>>unit)  //read a double and unit from user

		{

			

		valid_unit=true;

		

		cout<<setprecision (9)<<"\nInput\n----------\n"<<val1<<unit<<"\n\n"; //print the users input

		if (unit=="m")				//convert meters to centimeters

			val2=val1*100;

					

		else if (unit=="in")		//convert inches to centimiters

			val2=val1*2.54;		

		

		else if (unit=="ft")		//convert feet to centimeters

			val2=val1*30.48;

					

		else if (unit=="cm") 

			val2=val1;				//no conversion nescessary			

		else 

			cout<<"Sorry, that is an illegal unit.\n\n";

			

				

		if (i==0){temp_smallest=val1;temp_largest=val1;smallest=val2;largest=val2;smallest_unit=unit;largest_unit=unit;  cout<<val1<<unit<<" is the first measurement.\n\n"; }


	else if (i>0 && val2<smallest)

		{ 

		smallest=val2;

		smallest_unit=unit;

		temp_smallest=val1;

		}

	else if (i>0 && val2>largest) 

		{

		largest=val2;

		largest_unit=unit;

		temp_largest=val1;		

		}

	else cout<<"Is neither larger nor smaller.\n\n";

		

		cout<<temp_smallest<<smallest_unit<<" is the smallest so far\n\n";

		cout<<temp_largest<<largest_unit<<" is the largest so far\n\n";

		cout<<"Input another measurement followed by a unit (cm, m, in or ft): ";

	i++;

	

		}

	}


#9
Alexander

Alexander

    It's Science!

  • Moderators
  • 4,118 posts
  • Location:Vancouver, Eh! Cleverness: 200
I am sorry for a lengthy response, sometimes it is easier to post in a new thread to get better exposure on more questions.

You cannot compare strings like that, unit is really a pointer to the memory location of the first character in the string and may look like an integer to the system (integer 0xffffba != "cm" in example).


You must use strcmp (or its varieties if you need insensitive matches, or you can make your own pointer walking comparison function). One thing that should be mentioned, is that strcmp returns zero on success (as nothing is different), so you cannot use if(strcmp()) or if(!strcmp()) without creating confusion, it should be if (strcmp(...) == 0)
Be sure to read the updated FAQ! || Health is achieved through the same 10,000 steps.
If a suggested code/method fails, informing us is less important than telling us why or what errors occurred.

#10
crookedmouth

crookedmouth

    Newbie

  • Members
  • Pip
  • 7 posts
Thanks for replying Alexander. In the future I will start a new topic, I just didn't want to clutter up the place with my newb questions. :)

I actually found a "cheap" way to get this program to work. I admit that I am trying to only use what has been covered so far in the book to write my programs but this really makes for some challenge! He hasn't covered any functions yet except sqrt(). I understand that if I come here asking for help, you are going to point me to the actual way to do it, which would most likely be more advantageous for me anyway. I will keep this in mind for future questions, as well as starting a new topic.

I'm really trying to stay positive. At first I really felt that I had a natural knack for programming in C++ but it's taking me forever to get through these exercises.

I think I get how to use strcmp in this case. Something like this?

if (strcmp(unit,"ft") ==0))  

    { // code here}

else if (strcmp(unit,"in") ==0))

    {// code here}

// and so on

else

     // since the value returned is less then zero do something else

This is the cheap way that I got this to work. I reverted to a BASIC-like use of a goto.
REDO:

	cout<<"Input a measurement followed by a unit (cm, m, in or ft):";

	while (cin>>val1>>unit)  //read a double and unit from user

		{

		

		cout<<setprecision (9)<<"\nInput\n----------\n"<<val1<<unit<<"\n\n"; //print the users input

		if (unit=="m")				

			{

				val2=val1*100;     //convert meters to centimeters

				sum=sum+val1;    

				v.push_back(val1);

			}		

		else if (unit=="in")		//convert inches to centimeters

			{

				val2=val1*2.54;

				sum=sum+val1*.0254;

				v.push_back(val1*.0254);

			}

		else if (unit=="ft")		//convert feet to centimeters

			{

				val2=val1*30.48;

				sum=sum+val1*.3048;

				v.push_back(val1*.3048);

			}			

		else if (unit=="cm") 

			{

			val2=val1;				//no conversion necessary		

			sum=sum+val1/100;

			v.push_back(val1/100);

			}

		else {

			cout<<"Sorry, that is an illegal unit.\n\n";

			goto REDO;

The program actually works and does everything that is asked, though perhaps it shouldn't.

Thanks again.

#11
Alexander

Alexander

    It's Science!

  • Moderators
  • 4,118 posts
  • Location:Vancouver, Eh! Cleverness: 200
Ah, actually I am not sure what == would do, it is an std::string and not a char*, my mistake for using strcmp.

As for the goto at the end, if it is within a while loop you can just replace that with continue;, as it will continue and go to the top of the loop again, I think that is unneeded.
Be sure to read the updated FAQ! || Health is achieved through the same 10,000 steps.
If a suggested code/method fails, informing us is less important than telling us why or what errors occurred.

#12
bgardner

bgardner

    Newbie

  • Members
  • Pip
  • 8 posts
ok so I know this is a fairly old thread, but i stumbled across it while having the same issue as the OP (which btw, by (briefly) reading through the replies I still didn't find a clear answer as to why the 1.0/1000000 doesn't work. As well for my version of the program I was trying to use primarily things that were talked about in this chapter (i.e. vectors, while/for loops, constants, and the like. I did "cheat" and look up another member of vectors called "resize", even though I had a different solution that worked for the simplicity of this program. The solution however just caused the vector to keep growing.

Theoretically in my mind my "else if" statement should work seeing as how I have sorted it before the for-statement began. However it doesn't work (at least with that amount of precision). i use numbers such as 6 and 5.9999999, it just rounds the 5.9999999 up to 6. Is stroustrup trying to confuse us with things such as the setprecision the someone had talked about?? or did he maybe "accidentally" put that in there without realized he hadn't talked about it? or what?

#include "std_lib_facilities.h"


int main()

{


	const double difference=1.0/1000000;


	vector <double> numbersvector;

	double numbers;

	double smallest; //unused variable at this stage of the drill

	double largest; //another unused variable at this stage of drill

	

	while(cin>>numbers){ //read numbers in. Could also be while(cin>>true) but dont know how to end the loop

		numbersvector.push_back(numbers);


		for(int i=0; i<numbersvector.size(); i++){

			cout<<numbersvector[i]<<endl;

		}


		sort(numbersvector.begin(),numbersvector.end());


		if(numbersvector[0]==numbersvector[1])

			cout<<"The numbers are equal"<<endl;

		else if(numbersvector[0]==numbersvector[1]-difference)

			cout<<"The numbers are almost equal"<<endl;

		else{

			cout<<"The smaller value is: "<<numbersvector[0]<<endl;

			cout<<"The larger value is: "<<numbersvector[1]<<endl;

		}



		numbersvector.resize(0);


	}

}






1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users