Respuesta wiki comunitaria :
Puede estar decepcionado con los resultados en SQL Server en comparación con PostgreSQL (que es capaz de manejar números muy grandes como 30000 sin pérdida de precisión).
En SQL Server 33!
es tan alto como puede llegar con precisión exacta, mientras que 170!
es tan alto como puede llegar ( 171!
es lo1.24E309
que excede los límites de float
).
Por lo tanto, podría precalcularlos y almacenarlos en una tabla con valores 0 ... 170
. Esto encaja en una sola página de datos si se usa compresión.
CREATE TABLE dbo.Factorials
(
N TINYINT PRIMARY KEY WITH (DATA_COMPRESSION = ROW),
FactorialExact NUMERIC(38, 0) NULL,
FactorialApprox FLOAT NOT NULL
);
WITH R(N, FactorialExact, FactorialApprox)
AS (SELECT 0,
CAST(1 AS NUMERIC(38, 0)),
1E0
UNION ALL
SELECT R.N + 1,
CASE WHEN R.N < 33 THEN ( R.N + 1 ) * R.FactorialExact END,
CASE WHEN R.N < 170 THEN ( R.N + 1 ) * R.FactorialApprox END
FROM R
WHERE R.N < 170)
INSERT INTO dbo.Factorials
(N,
FactorialExact,
FactorialApprox)
SELECT N,
FactorialExact,
FactorialApprox
FROM R
OPTION (MAXRECURSION 170);
Por otra parte, lo siguiente será dar resultados exactos para @N hasta el 10 - y aproximada de 11+ (sería más exacto si las diversas funciones / constantes ( PI()
, EXP()
, POWER()
) trabajaron con DECIMAL
tipos pero trabajan con FLOAT
solamente):
DECLARE @N integer = 10;
SELECT
CONVERT
(
DECIMAL(38,0),
SQRT(2 * PI() * @N) *
POWER(@N/EXP(1), @N) *
EXP(1.0/12.0/@N + 1.0/360.0/POWER(@N, 3))
);