Risposta wiki della community :
Potresti essere deluso dai risultati in SQL Server rispetto a PostgreSQL (che è in grado di gestire numeri molto grandi come 30000! Senza perdita di precisione).
In SQL Server 33!è il più alto che puoi andare con la massima precisione mentre 170!è il più alto che puoi ( 171!è il1.24E309 che supera i limiti di float).
Quindi potresti semplicemente precalcolarli e archiviarli in una tabella con valori 0 ... 170. Questo si adatta a una singola pagina di dati se viene utilizzata la compressione.
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);
In alternativa, il seguente darà risultati accurati per @N fino al 10 - e approssimativa per 11+ (sarebbe più esatto se le varie funzioni / costanti ( PI(), EXP(), POWER()) ha lavorato con DECIMALi tipi, ma con cui lavorano FLOATsolo):
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))
);