Number greater than the largest positive floating-point number (1.7977e+308)

11 次查看(过去 30 天)
I'm trying to calculate the following expression:
(l+m)! / (l!m!)
but when l=m > 85 I get infinity, because the result is greater than the largest positive floating-point number (1.7977e+308).
Is there a way of increasing this number limit, or even a trick to avoid this problem?

采纳的回答

Roger Stafford
Roger Stafford 2014-9-1
There is a much more satisfactory way to compute that expression:
round(prod((L+1:L+m)./(1:m)))
or
round(prod((m+1:m+L)./(1:L)))
whichever you prefer. For the case m = L = 85, the answer would be 9.1448e+49, which is far below the limit for double floating point numbers. You will not encounter difficulties until you reach m = L = 515, and that is unavoidable because the result really is in excess of 'realmax'.
  4 个评论
Roger Stafford
Roger Stafford 2014-9-2
编辑:Roger Stafford 2014-9-2
@Tigo. I will repeat a comment here that I made in John's answer. You say "I figure out that (l+m)! / (l!m!) is equivalent to product_{j=1}^l (m+j)/j. Unfortunately I'm having problems to write this on Matlab." However, you appear not to recognize that matlab's equivalent form of this computation is what I already wrote for you:
prod((m+1:m+L)./(1:L))
For example, if m = 11 and L = 4 both expressions are computing the product
(11+1)/1 times (11+2)/2 times (11+3)/3 times (11+4)/4 = 1365
The two are identical computations, being translations of precisely the same algorithm expressed in two different languages. The 'round' is merely added to this to correct for round-off errors that have occurred during the computation.
Eric
Eric 2014-9-2
编辑:Eric 2014-9-2
"Why do you need numbers that big? What is the real world application of this?"
These big numbers come in the numerator of ((l+m)!)/(l!m!), but the actual result is not that big because we still have the denominator. One thing that bugs me is that this same expression runs without problems in Mathematica.

请先登录,再进行评论。

更多回答(3 个)

Roger Stafford
Roger Stafford 2014-9-2
In case it is of interest, here is an alternate method of computation based on Pascal triangle summations.
m = 25;
L = 11;
x = ones(m+1,1);
for k = 2:L+1
x = cumsum(x);
end
y = x(m+1); % <-- This is the answer
This involves more operations than the other method presented earlier here, but, as opposed to this other method, there are no round-off errors until reaching numbers beyond 2^53 where not all integers can be represented. This is because only sums of integers are being computed in this method.

John D'Errico
John D'Errico 2014-9-2
I'd suggest working in logs, which will be as insensitive as possible to problems with exponents. Only at the very end do you need to exponentiate.
If you truly need to compute a number too large to represent in a double, then you will have no choice in the end. Use either the symbolic toolbox, or a tool like my own HPF toolbox.
  2 个评论
Eric
Eric 2014-9-2
Thanks. But before I try to learn that (I'm a beginner on Matlab), do you have any ideas of how to write this on Matlab?
product_{j=1}^l (m+j)/j
Roger Stafford
Roger Stafford 2014-9-2
product_{j=1}^l (m+j)/j
I gave you the matlab version of that in the line:
round(prod((m+1:m+L)./(1:L)))
The added 'round' merely corrects for rounding errors occurring in the division process.

请先登录,再进行评论。


Steven Lord
Steven Lord 2016-5-18
(L+M)! / (L! * M!) is just nchoosek(L+M, L) or nchoosek(L+M, M). For most cases this uses the approach that others in this discussion have recommended.
But if L+M is on the order of 5000, the answer will not be exact unless one of L or M is much, much smaller than 5000 and will be infinite (too large to represent as a finite double) if the second input is greater than about 150 or 160.

类别

Help CenterFile Exchange 中查找有关 Loops and Conditional Statements 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by