factorial numbers in java script

  • Thread starter patrick_woflian
  • Start date
P

patrick_woflian

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 the following
calculation:

z = x! / (x- y)!

The following code is my attempt and i was hoping for a point in the
right direction as too where i am going wrong.. cheers

<html>

<head>

<FORM NAME = frmOne>

Number One: <INPUT TYPE = Text NAME = txtFirstNumber SIZE = 5 value
="">

Number Two: <INPUT TYPE = Text NAME = txtSecondNumber SIZE = 5 value
="">
<P>
Total: <INPUT TYPE = Text NAME = txtThirdNumber SIZE = 5 value = "">
<P>
<Input Type = Button NAME = b1 VALUE = "Calculate" onClick =
calculate()>
</FORM>

<script language = "javascript">
function calculate() {
A = document.frmOne.txtFirstNumber.value
B = document.frmOne.txtSecondNumber.value
C = (A ! / (A - B ) ! )
document.frmOne.txtThirdNumber.value = C
}

</script>

</head>

<body> Refresh to run the script again

</body>



Patrick
 
U

unixfreak0037

Patrick,

There is no factorial operator in javascript. "A !" is not a valid java
expression. If you want to do factorials, you'll need to either write
the function yourself, or search for an example, of which I'm sure
there are thousands.

john
 
P

patrick_woflian

ahhhh sorry about that.. where would i call the function seeing as i
already have the 'function calculate'? should i scrap all that and
start with the factorial function?

patrick
 
M

Michael Winter

[...] i am having a major problem with the following calculation:

z = x! / (x- y)!

Whilst there is a unary ! operator in ECMAScript, it is not
arithmetical. It is, in fact, a logical NOT operator, as in many other
programming languages.

There is no built-in method for calculating factorials, so you will need
to write your own (which shouldn't be difficult).

[snip]
<head>

<FORM NAME = frmOne>

You may not place a FORM element within the HEAD element of a document.
The SCRIPT element may remain within HEAD, but the FORM must be moved to
the BODY element.

[snip]
<Input Type = Button NAME = b1 VALUE = "Calculate" onClick =
calculate()>

That onclick attribute value must be quoted. Unless you know the rules
for what can, and what cannot be quoted, do the simple thing and quote
all attribute values.

[snip]
<script language = "javascript">

The language attribute has long been deprecated. Use the type attribute
instead:

function calculate() {
A = document.frmOne.txtFirstNumber.value
B = document.frmOne.txtSecondNumber.value
C = (A ! / (A - B ) ! )

These variables will become global, which is not good practice. Declare
them with the var keyword first.

There are other improvements that could be made, but they can wait for
now. One thing that I would recommend is that you mark-up documents
uniformly. Mixed case looks a bit of a mess. All lowercase (both for
elements and attributes) is generally easier to read.

Mike
 
W

web.dev

patrick_woflian said:
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 the following
calculation:

z = x! / (x- y)!

There is no builtin factorial function in javascript, you'll have to
write one yourself.
<script language = "javascript">

The language attribute is deprecate, use the type attribute instead:

function calculate() {
A = document.frmOne.txtFirstNumber.value
B = document.frmOne.txtSecondNumber.value
C = (A ! / (A - B ) ! )
document.frmOne.txtThirdNumber.value = C
}

It's my personal preference to explicitly declare variables, so as to
not to have potential collision with global variables.

var A, B, C;

And as for your factorial function, you can make the call here:

C = factorial(A) / factorial(A - B);

Here's a simple recursive factorial function you can use:

function factorial(n)
{
if(n == 1 || n == 0) //your base case
return 1;

return n * factorial(n - 1);
}

You can add additional checks, for example to see if n is a negative
value.
 
T

Thomas 'PointedEars' Lahn

Thomas said:
function calc(o)
{
var f;
if (o && (f = o.form))
{
var es = f.elements;
if (es)
{
var
a = es['txtFirstNumber'].value,
b = es['txtSecondNumber'].value;

es['txtThirdNumber'].value = fac(a) / (a - b);

Should be

es['txtThirdNumber'].value = fac(a) / fac(a - b);

of course.

And as for your Subject header:

Java is not JavaScript ("Java != JavaScript").


PointedEars
 
U

unixfreak0037

If your factorial function was called "factorial", then you could
replace this line:

C = (A ! / (A - B ) ! )

with this line:

var C = (factorial(A) / (factorial(A - B));

The advice given to you by others regarding your HTML markup is
important.

john
 
P

patrick_woflian

i have shortened my java script code to make it easier to understand...
this is my new code yet the factorial calculation still isn't working..
help!!
<html>

function factorial(n) {
if ((n == 0) || (n == 1))
return 1
else {
var result = (n * factorial(n-1) );
return result
}
}

<script language = "javascript">

<!--

var x = 0;
var y = 0;
var z = 0;

x = window.prompt("Enter first number..");
x = parseInt(x);

y = window.prompt("Enter second number..");
y = parseInt(y);


z = (factorial x / factorial (x-y));

alert("THE ANSWER IS " + z);


//-->

</script>

<body>

</body>


any comments would be great..
 
W

web.dev

patrick_woflian said:
function factorial(n) {
if ((n == 0) || (n == 1))
return 1
else {
var result = (n * factorial(n-1) );
return result

This can be shortened even further:

return n * factorial(n - 1);

Though it is not a requirement, it is good practice to end statements
with a semi-colon.
<script language = "javascript">
<!--

There is no need for SGML comments. The language attribute is
deprecated, use the type attribute instead:
z = (factorial x / factorial (x-y));

You have a syntax error. Fix it to be like so:

z = factorial(x) / factorial(x-y);

Another note, is your factorial function outside the script or within a
script? I can not tell from what you've posted. If it's outside, move
it inside the script tags.
 
E

Evertjan.

web.dev wrote on 09 dec 2005 in comp.lang.javascript:
This can be shortened even further:

return n * factorial(n - 1);

This can be shortened even further,
[and will also catch negative inputs,
and give [not intended] results for nonintegers]

function factorial(n) {
return (n<2)?1:n*factorial(--n);
}
 
D

Dr John Stockton

JRS: In article <[email protected]>, dated Fri, 9 Dec
2005 20:16:31 local, seen in Thomas
'PointedEars' Lahn said:
There are two approaches: iterative and recursive; the former
will allow you to calculate factorials of greater integers, of course still
with increasing loss of precision.

Why do you say that? Both can calculate 170! but not 171! - giving the
same answer. Up to 18!, both will be exact; above that answers *may*
depend on whether the multiplications for N! start or finish with *N.

<URL:http://www.merlyn.demon.co.uk/js-index.htm#BF> shows how to
determine factorials of numbers larger than 170.

Perhaps someone will check that one million factorial is about
8.263929417903883e5565708 ?
 
R

RobG

Evertjan. said:
web.dev wrote on 09 dec 2005 in comp.lang.javascript:

This can be shortened even further:

return n * factorial(n - 1);


This can be shortened even further,
[and will also catch negative inputs,
and give [not intended] results for nonintegers]

function factorial(n) {
return (n<2)?1:n*factorial(--n);
}

A non-recursive loop version is possibly faster, but the integer limit
of JavaScript is exceeded well before any meaningful result is
achieved even on a slow machine (170!), so I guess the issue is moot:


function factorial(n){
if (n > 0){
var x = 1;
do { x *= n; } while (--n);
return x;
}
return (n==0)?1 : null; // [1]
}


1. What value should be returned for negative numbers? Probably null,
but maybe false or some error message? What should be done to
test/respond to non-integer values?
 
E

Evertjan.

RobG wrote on 10 dec 2005 in comp.lang.javascript:
This can be shortened even further,
[and will also catch negative inputs,
and give [not intended] results for nonintegers]

function factorial(n) {
return (n<2)?1:n*factorial(--n);
}

A non-recursive loop version is possibly faster, but the integer limit
of JavaScript is exceeded well before any meaningful result is
achieved even on a slow machine (170!), so I guess the issue is moot:


function factorial(n){
if (n > 0){
var x = 1;
do { x *= n; } while (--n);
return x;
}
return (n==0)?1 : null; // [1]
}

My point is not:
returning any value definitionwize if n<1, or not integer,
but:
preventing an endless loop with clientside timeout.

function factorial(n) {
return (n<2)?1:n*factorial(--n);
}

does this fine.

it could be agued to prevent a too high n likewize:

function factorial(n) {
1. What value should be returned for negative numbers? Probably null,
but maybe false or some error message? What should be done to
test/respond to non-integer values?

The same goes here, I am content with the result 1, since the real result
"undefined" in the mathemetical sense should be prevented on input.

The result 0 would give an error as divider in the OP's formula.

but if you wish we could output null
for "undefined [not integer or <1] or too large [>170] a factorial input"
..

function factorial(n) {
return (n<1||n>170||Math.floor(n)!=n)?null:
(n<2)?1:n*factorial(--n);
}
 
T

Thomas 'PointedEars' Lahn

Dr said:
[...] Thomas 'PointedEars' Lahn [...] posted :
There are two approaches: iterative and recursive; the former
will allow you to calculate factorials of greater integers, of
course still with increasing loss of precision.

Why do you say that? [...]

Because how many recursive calls are possible, thus which is the greatest
factorial that can be calculated through that approach, is limited by the
range for IEEE doubles and the stack size; the greatest factorial that can
be calculated through the iterative approach is only limited by the range
for IEEE doubles.


PointedEars
 
L

Lee

patrick_woflian said:
i have shortened my java script code to make it easier to understand...
this is my new code yet the factorial calculation still isn't working..
help!!

You shouldn't really be calculating both factorials in order to
calculate A! / (A-B)!
You observe that the result is simply A(A-1)(A-2)...(A-B+1)

function permutations(A,B) {
var diff=A-B;
var result=1;
while (A>diff) {
result*=A--;
}
return result;
}
 
J

John G Harris

<[email protected]>, RobG

1. What value should be returned for negative numbers? Probably null,
but maybe false or some error message? What should be done to
test/respond to non-integer values?

Recall that x! is defined for all real numbers, except that for -1, -2,
-3, ... it goes off to +/- infinity (and drops down to nearly zero in
between). I suspect this is more than you really wanted to know :)

What should be done for negative and non-integral values depends on the
customer's requirements.
alert("I don't do that");
is the simplest answer.

John
 
J

John G Harris

Perhaps someone will check that one million factorial is about
8.263929417903883e5565708 ?
8.263931686266318e5565708

is the value I get using Stirling's formula. It is probably accurate to
10 digits or so if IE's Math object is reasonably good.

The accuracy of x! depends on x being 'large'. For comparison, I get

1! = 1.0017262166905087 e 0
4! = 2.4000001753028925 e 1
10! = 3.628800000432076 e 6

John



<SCRIPT type="text/javascript">
function LnFact(x)
// Stirling's approximation
// LnFact(x) = ln(x!)
{
return Math.log(2*Math.PI)/2 +
(x + 0.5)*Math.log(x) - x +
1/12/x - 1/360/x/x/x + 1/1260/x/x/x/x/x +
1/1680/x/x/x/x/x/x/x + 1/1188/x/x/x/x/x/x/x/x/x;
}

function DispFact(x)
// Display x!
{
var lf10 = LnFact(x)*Math.LOG10E;
var fexp = Math.floor(lf10); // exponent
var fmant = Math.pow(10, lf10 - fexp); // mantissa

document.writeln
(x, "<strong>!</strong> = ",
fmant, " e ", fexp, "<br>");
}

DispFact(1);
DispFact(4);
DispFact(10);
DispFact(1e6);

</SCRIPT>
 
R

RobG

John said:
<[email protected]>, RobG




Recall that x! is defined for all real numbers, except that for -1, -2,
-3, ... it goes off to +/- infinity (and drops down to nearly zero in
between).

No, I don't - factorials are only defined for positive integers and
zero, where 0! = 1.

I suspect this is more than you really wanted to know :)

Yes (see above).

What should be done for negative and non-integral values depends on the
customer's requirements.

Exactly, and you didn't state what that was. My intention was to raise
the issue so that you thought about it, I didn't want to guess at a
solution that may not be appropriate (for you or your client).

alert("I don't do that");
is the simplest answer.

But not very elegant. Your code should ensure negative numbers are
never passed to the factorial function by checking the data input, not
by barfing at some later stage that may be several steps away from where
the actual error occurred.
 
D

Dr John Stockton

JRS: In article <439a1e2c$0$22292$5a62ac22@per-qv1-newsreader-
01.iinet.net.au>, dated Sat, 10 Dec 2005 10:15:40 local, seen in
news:comp.lang.javascript said:
A non-recursive loop version is possibly faster, but the integer limit
of JavaScript is exceeded well before any meaningful result is
achieved even on a slow machine (170!), so I guess the issue is moot:
1. What value should be returned for negative numbers? Probably null,
but maybe false or some error message? What should be done to
test/respond to non-integer values?

For arguments where the true or apparent result exceeds the numeric
capacity of an IEEE Double, it seems reasonable to return an Infinity.

Returning anything that can be coerced into a finite number seems unwise
as it may lead to undetected error; but returning something that coerces
to 0 may be safe enough. Returning NaN seems appropriate.

There is a function known to mathematicians that basically matches
factorial for the positive, or non-negative, or greater than -1,
integers, but is actually defined over (at least) the (positive?) reals;
ISTR it's the Gamma function, but ICBW.
 
D

Dr John Stockton

JRS: In article <[email protected]>, dated Sat, 10
Dec 2005 09:02:54 local, seen in Evertjan.
it could be agued to prevent a too high n likewize:

function factorial(n) {
return (n<2||n>170)?1:n*factorial(--n);
}

(a) ISTM that 1 should NOT be the result for an out-of-range argument.

(b) ISTM that the tests should be inverted, so that a NaN argument
counts as out-of-range; or that there should be a specific isNaN test.

(c) ISTM that, ideally, the 170 test should be done only once, since it
can only fail on the first attempt.

(d) Probably, for most or all practical applications of factorial, an
argument less than zero should give NaN, as should a non-integer
argument.


function Fac(m) { return m<2 ? 1 : m*Fac(--m) }

function Factorial(n) {
if (isNaN(n)) return NaN
if (n<0) return NaN
if (n>170) return Infinity
if (n%1) return NaN
return Fac(n) }

or

function Factorial(n) {
if (isNaN(n) || n<0 || n%1) return NaN
if (n>170) return Infinity
return Fac(n) }


Then one can use Factorial in test code, and Fac in debugged code!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,062
Latest member
OrderKetozenseACV

Latest Threads

Top