The earlier put up identified that the next code equivalent to the next unexpectedly works.
>>> from math import log, factorial >>> log(factorial(1000)) 5912.128178488163
Should you don’t discover this sudden, word that in case you change math.log with numpy.log the code will fail [1]. Capabilities like pure logarithm function on actual numbers. Actual numbers are represented as floating level numbers in programming languages, and 1000! factorial is just too massive to symbolize as a normal floating level quantity. (Extra on that right here.)
On this put up I’d like to have a look at the way you would possibly calculate log(1000!) with much less succesful software program, and even with out software program.
One method could be to sum the logarithms of the numbers 1 via 1000. This may give basically the identical end result as above, with a little bit distinction within the final couple decimal locations on account of rounding error.
In case you have a technique to calculate 1000! however not a technique to forged it to a floating level quantity, you possibly can do that manually.
>>> s = str(factorial(1000)) >>> s[:16] '4023872600770937' >>> len(s) 2568
This tells us 1000! = 4.023872600770937 × 102567. Due to this fact
log(1000!) = log(4.023872600770937) + 2567 log(10)
which solely requires working with numbers of modest measurement.
Calculating by hand
Now suppose it’s 1964. You don’t have a pc, or perhaps a calculator, however you do have a replica of the not too long ago printed Handbook of Mathematical Capabilities by Abramowitz and Stegun (A&S). You flip to Desk 6.6 “Factorials for big arguments.” This has values of factorial for 100, 200, 300, …, 1000, so you’ll be able to merely search for your reply to twenty decimal locations.
That was too simple; I didn’t count on that to be there after I began penning this put up. Should you wished to compute log(950!), for instance, you’d need to work tougher. You may discover A&S equation 6.1.41 (Stirling’s collection) which says
So how would you employ this formulation to calculate log(1000!)? Since n! = Γ(n + 1), you set z = 1001.
You’d must determine what number of phrases you must use. Assuming the error is on the order of the primary time period you allow out, you’d motive that you possibly can most likely cease with the 1/12z time period as a result of the subsequent time period is between 10−11 and 10−12.
You discover Desk 4.2 has pure logarithms, however not for 1001. You may search for log(1.001), nonetheless, and on the backside of the identical web page is log(10) to 16 decimal locations, and you will discover log(10) to 24 decimal locations in Desk 1.1. So that you calculate
log(1001) = log(1.001 × 10³) = log(1.001) + 3 log(10).
You will discover log(2) and log(π) in Desk 1.1, and common them to seek out ½ log(2π).
Right here’s Python code to simulate the hand calculations.
log2 = 0.6931_47180_55994_53094_172321 # Desk 1.1 log10 = 2.3025_85092_99404_56840_179915 # Desk 1.1 logpi = 1.1447_29885_84940_01741_43427 # Desk 1.1 log1_001 = 0.00099_95003_330835 # Desk 4.2 z = 1001 logz = log1_001 + 3*log10 s = (z - 0.5)*logz - z + (log2 + logpi)/2 + 1/(12*z) print(s)
This end result differs from the one on the high of the put up solely within the final decimal place.
Associated posts
Doing calculations with tables just isn’t so simple as “simply look it up.” It takes a little bit of ability.
[1] The code may also fail in case you change math.log with math.cos. Each logarithm and cosine return reasonable sized actual numbers when given huge inputs like 1000!, so representing the output as a float just isn’t the issue. However logarithms of giant numbers will be computed with peculiar precision features, as above. However computing the cosine of an enormous quantity requires prolonged precision.
