473,395 Members | 1,730 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

C++ Primer ex 7.20 - finding factorial

it runs fine. any advice for the improvement:

/* C++ Primer - 4/e
*
* exercise 7.20
* STATEMENT:
* write a programme to find the factorial of an int.
* use an iteratice function.
*
*/

#include <iostream>

long double find_factorial( int num ) {
/* maximum value of 32 bit int is 32768. so we need to use
long double to store its factorial value, but still for any values
above 1754 i get "inf" as output. i dont't have any problem with that
kind of output as i have successfully created the iterative version
of the factorial function.
*/

long double facto = 1;

for(int i = num; i != 0; --i)
{
facto *= i;
}

return facto;
}
int main()
{
std::cout << "Enter the number: ";
int i;
std::cin >i;

std::cout << "Factorial of "
<< i
<< " = "
<< find_factorial( i )
<< std::endl;
return 0;
}
--
http://arnuld.blogspot.com

Aug 17 '07 #1
13 3185
On Fri, 17 Aug 2007 12:17:30 +0500, arnuld wrote:
it runs fine. any advice for the improvement:

/* C++ Primer - 4/e
*
* exercise 7.20
* STATEMENT:
* write a programme to find the factorial of an int.
* use an iteratice function.
*
*/

#include <iostream>

long double find_factorial( int num ) {
/* maximum value of 32 bit int is 32768. so we need to use
2^32 != 32768

--
Obnoxious User
Aug 17 '07 #2
On Fri, 17 Aug 2007 07:25:02 +0000, Obnoxious User wrote:
2^32 != 32768
ok, whatever the value is, the point is: "long doouble" is not going to
handle any value greater than the factorial of 1754.

--
http://arnuld.blogspot.com

Aug 17 '07 #3
arnuld wrote:
>On Fri, 17 Aug 2007 07:25:02 +0000, Obnoxious User wrote:
>2^32 != 32768

ok, whatever the value is,
Shouldn't you familiarize yourself on how numbers and numeric limits
work in computers?
Believing that 32768 is the largest value representable with a 32-bit
integer shows a great lack of understanding about integers and amounts
of bits.
the point is: "long doouble" is not going to
handle any value greater than the factorial of 1754.
A long double is not going to give you an *accurate* result from some
value forward. When the result is large enough the last digits will be
wrong, and thus the result will be wrong. It's not the factorial of the
given number.
Aug 17 '07 #4
Juha Nieminen wrote:
>the point is: "long doouble" is not going to
handle any value greater than the factorial of 1754.

A long double is not going to give you an *accurate* result from some
value forward. When the result is large enough the last digits will be
wrong, and thus the result will be wrong. It's not the factorial of the
given number.
But with factorials, the trailing digits are all zeroes (in any base),
so perhaps a floating-point number is appropriate.

The largest factorial a 32-bit long can hold is 12! or 479001600. This
number in binary has 10 trailing zeroes and so can be accurately
represented with a 19-bit mantissa (stored in 18 bits with the first bit
"hidden") and 5-bit exponent; thus including sign bit, only 18+5+1 = 24
bits are required to store this number in floating-point.

Similarly, an IEEE 754 single-precision (32-bit) number can store up to
13! or 6227020800 accurately.

(I'd still advocate using integer types for factorials unless you
*really* know what you're doing...)

--
Philip Potter pgp <atdoc.ic.ac.uk
Aug 17 '07 #5
tom
On Aug 17, 3:17 pm, arnuld <geek.arn...@gmail.comwrote:
it runs fine. any advice for the improvement:

/* C++ Primer - 4/e
*
* exercise 7.20
* STATEMENT:
* write a programme to find the factorial of an int.
* use an iteratice function.
*
*/

#include <iostream>

long double find_factorial( int num ) {
/* maximum value of 32 bit int is 32768. so we need to use
long double to store its factorial value, but still for any values
above 1754 i get "inf" as output. i dont't have any problem with that
kind of output as i have successfully created the iterative version
of the factorial function.
*/

long double facto = 1;

for(int i = num; i != 0; --i)
{
facto *= i;
}

return facto;

}

int main()
{
std::cout << "Enter the number: ";
int i;
std::cin >i;

std::cout << "Factorial of "
<< i
<< " = "
<< find_factorial( i )
<< std::endl;
return 0;

}

--http://arnuld.blogspot.com
can you have a statement:
"using namespace std;"
ahead, and write:
"cout<<...<<endl;"
without referring to "std" every time, it do increase much of the
readibility

Aug 18 '07 #6

tom <px****@gmail.comwrote in message...
>
can you have a statement:
"using namespace std;"
ahead, and write:
"cout<<...<<endl;"
without referring to "std" every time, it do increase much of the
readibility
NO, it decreases the 'readibility'!

Can be bad. Try this:

#include <iostream // #include <ostream// for std::endl
#include <sstream>
using namespace std;

int main(){
std::ostringstream cout;
cout << "hello, world" << std::endl;
std::cout<<cout.str()<<std::endl;
return 0;
} // main()

Remove the 'using namespace std;' line, and it will compile and run as
expected.

--
Bob R
POVrookie
Aug 18 '07 #7

BobR wrote:
tom <px****@gmail.comwrote in message...
NO, it decreases the 'readibility'!
I've become accustomed to typing std without thinking, but...
Can be bad. Try this:

#include <iostream // #include <ostream// for std::endl
#include <sstream>
using namespace std;

int main(){
std::ostringstream cout;
cout << "hello, world" << std::endl;
std::cout<<cout.str()<<std::endl;
return 0;
} // main()
.... in reality <using namespaceis only used in source/.c* files
and these kind of mistakes like the one mentioned here
above are local to source files (apart from the naivety of
calling something cout, which does not happen in practice
that often (IMhO).
Remove the 'using namespace std;' line, and it will compile and run as
expected.
Yes, rename it (cout) to mystream, or main_cout, or whatever and
it should also compile/run as expected ;-)

Regards,

Werner

Aug 18 '07 #8

werasm <we****@gmail.comwrote in message...
>
BobR wrote:
Can be bad. Try this:

#include <iostream // #include <ostream// for std::endl
#include <sstream>
using namespace std;

int main(){
std::ostringstream cout;
cout << "hello, world" << std::endl;
std::cout<<cout.str()<<std::endl;
return 0;
} // main()

... in reality <using namespaceis only used in source/.c* files
and these kind of mistakes like the one mentioned here
above are local to source files (apart from the naivety of
calling something cout, which does not happen in practice
that often (IMhO).
Remove the 'using namespace std;' line, and it will compile and run as
expected.

Yes, rename it (cout) to mystream, or main_cout, or whatever and
it should also compile/run as expected ;-)
My use of 'cout' was not a mistake.

The point is that if you use the 'using namespace std;' you will eventually
name something that is defined in the std namespace, and it could bite you.
Most times it will just cause a compiler diagnostic (.. and save your
behind. <G>).

I used the 'cout' example because that is what I actually use in my
TestBench program. I got tired of makeing a separate program to test
snippets posted in these NGs. So, now I just cut/paste/compile/run in many
cases.
Since TestBench is an wxWidgets (windows) program, std::cout is useless
(unless it's re-directed, which I don't have to do now). My 'cout' is sent
on to the wxTextCtrl window for output. Not perfect, but easier than before.
And I don't have to drop out of the GUI to a command-line.

--
Bob R
POVrookie
Aug 18 '07 #9

BobR wrote:
My use of 'cout' was not a mistake.
I realize this, hence my comment that I deem the deliberate use
unrealistic in practice, and deliberately named as such in this
case to prove a point. My point is that in practice these name
clashes are rare (if <using namespace stdis confined to
source files. That said, I've become so accustomed to
typing std, that I do it without thinking, making <using
namespace stduseless anyway.

All said, I have come across library implementations that
have more than one version of endl/cout etc (admittedly
more than 5 years ago, and not qualifying by std explicitly
gave me strange errors then (wrong one selected), especially
concerning endl/ends.
The point is that if you use the 'using namespace std;' you will eventually
name something that is defined in the std namespace, and it could bite you.
Most times it will just cause a compiler diagnostic (.. and save your
behind. <G>).
My point is that this <israre enough to merit "using namespace std".
Although, I disagree that adding std makes code less readable. For me
it makes no difference in the readability, on the contrary.
Since TestBench is an wxWidgets (windows) program, std::cout is useless
(unless it's re-directed, which I don't have to do now). My 'cout' is sent
on to the wxTextCtrl window for output. Not perfect, but easier than before.
And I don't have to drop out of the GUI to a command-line.
We've done similar things to output to qWidget, or whatever the
classes name was.

Kind regards,

Werner

Aug 18 '07 #10

arnuld wrote:
it runs fine. any advice for the improvement:
long double find_factorial( int num ) {
Hmmm, what if I enter a negative number?

Aug 18 '07 #11

arnuld wrote:
it runs fine. any advice for the improvement:
Not much, apart from the <intargument that allows for the
possibility of infinite iteration. I have two other versions
that fallout if infinity is reached. It has the disadvantage
that it does the extra check per iteration, but it will never
iterate more than required. Also, if pedantic, I would
criticize your main function for not ensuring correct
input. If cin failed, you would be using an uninitialized
variable (I'm actually not sure whether this is undefined
behavior). I could come up with two (other) versions. I suppose
the terseness could be criticized. I like the while version as
it causes one less iteration (not that it matters).

#include <iostream>
#include <climits>

long double factorial_1( unsigned value )
{
static long double inf( std::numeric_limits<long
double>::infinity() );
long double result( 1 );
for( unsigned i = 0; (i < value) && (result < inf); result *= ++i )
{ }
return result;
}

long double factorial_2( unsigned value )
{
static long double inf( std::numeric_limits<long
double>::infinity() );
long double result( value );
while( --value )
{
result *= value;
if( result == inf ){ break; }
}
return result;
}

int main()
{
enum{ error = -1, success = 0 };
std::cout << "Enter value" << std::endl;
unsigned value;

if( std::cin >value )
{
std::cout << "Result: " << factorial_1( value ) << std::endl;
return success;
}
else
{
std::cout << "Input error!" << std::endl;
return error;
}
}

Regards,

Werner

Aug 18 '07 #12
werasm wrote:

[SNIP]

Some corrections :-)
#include <climits>
should be...

#include <limits>

and...
static long double inf(
std::numeric_limits<longdouble>::infinity() );
should be:

const static long double inf(
std::numeric_limits<longdouble>::infinity() );

Regards,

W

Aug 18 '07 #13
On Sat, 18 Aug 2007 20:43:18 -0000, werasm wrote:
>My use of 'cout' was not a mistake.

I realize this, hence my comment that I deem the deliberate use
unrealistic in practice, and deliberately named as such in this
case to prove a point.
How unrealistic is it that you might happen to use
something like "includes", "unique", "replace" or
"reverse" in your program as a variable or a function?
All of those are names of functions in <algorithm>.

--
Joel Yliluoma - http://bisqwit.iki.fi/
: comprehension = 1 / (2 ^ precision)
Aug 19 '07 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

33
by: patrick_woflian | last post by:
hey guys, im just writing a basic calculation at the moment, before building on it for an A-Level piece of work. i can add/divide etc... two numbers together yet i am having a major problem with...
35
by: aNt17017 | last post by:
This is my code: long fact(int n) { if (n == 0) return(1); if(n > 100) { printf("\t\tERROR: %d is too large for factorial.\n", n); return 1;
8
by: salman | last post by:
this program is giving compile time error. so plse ge me the logic of factorial # include <iostream.h> # include <math.h> void main() { int f,sum=0,i,j,n; cout<<"\nEnter Number: ";
59
by: Umesh | last post by:
i wrote the following program to calculate factorial: #include<stdio.h> #include<iostream.h> void main() { int i,n; long int p=1; // or long double p=1; for exponential result which I don't...
3
by: Sugandh Jain | last post by:
Hi. How to write a function that will return me the factorial (say in a string) for the any positive integer it takes? When we find a factorial of even say 2000 or a higher number, it will be...
0
by: Killer42 | last post by:
Here's a very simple function for VB (written in VB6) to calculate the factorial (!) of a number. Note that it is limited by the magnitude of the value which can be stored in the Long data type. (In...
0
kadghar
by: kadghar | last post by:
Hi, I saw that Killer posted a simple Factorial Function that allows you to calculate up to 13!, well, you can use this for bigger numbers by changing the variable type. Why is this? You can...
2
by: arnuld | last post by:
it compiles and runs and at one place it produces strange output becaus eof a semantic-bug. i can't find it: /* C++ Primer - 4/e * * exercise 7.12 * STATEMENT: * write a programme to...
2
by: becky808 | last post by:
Hi, I'm trying to write a program to calculate n factorial but it won't compile. Can anyone tell me what I'm doing wrong? #include <iostream> #include <cmath> using namespace std; int...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.