From 04a4821adef38155b7920ba9eb83c4c3c29156f8 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Mon, 1 Dec 2003 21:52:38 +0000 Subject: Attached is a patch implementing factorial(), returning numeric. Points to note: 1) arttype is numeric. I thought this was the best way of allowing arbitarily large factorials, even though factorial(2^63) is a large number. Happy to change to integers if this is overkill. 2) since we're accepting numeric arguments, the patch tests for floats. If a numeric is passed with non-zero decimal portion, an error is raised since (from memory) they are undefined. Gavin Sherry --- src/backend/utils/adt/numeric.c | 51 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) (limited to 'src/backend/utils/adt/numeric.c') diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c index b2ffefa9da4..7f16ee37a24 100644 --- a/src/backend/utils/adt/numeric.c +++ b/src/backend/utils/adt/numeric.c @@ -14,7 +14,7 @@ * Copyright (c) 1998-2003, PostgreSQL Global Development Group * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.68 2003/11/29 19:51:59 pgsql Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.69 2003/12/01 21:52:37 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -1288,6 +1288,55 @@ numeric_larger(PG_FUNCTION_ARGS) * ---------------------------------------------------------------------- */ +/* + * numeric_fac() + * Computer factorial + */ + +Datum +numeric_fac(PG_FUNCTION_ARGS) +{ + + int64 num = PG_GETARG_INT64(0); + NumericVar count; + NumericVar fact; + NumericVar zerovar; + NumericVar result; + Numeric res; + + if(num < 1) { + res = make_result(&const_one); + PG_RETURN_NUMERIC(res); + } + + + init_var(&fact); + init_var(&count); + init_var(&result); + init_var(&zerovar); + zero_var(&zerovar); + + int8_to_numericvar((int64)num, &result); + set_var_from_var(&const_one, &count); + + for(num = num - 1; num > 0; num--) { + set_var_from_var(&result,&count); + + int8_to_numericvar((int64)num,&fact); + + mul_var(&count, &fact, &result, count.dscale + fact.dscale); + } + + res = make_result(&count); + + free_var(&count); + free_var(&fact); + free_var(&result); + free_var(&zerovar); + + PG_RETURN_NUMERIC(res); +} + /* * numeric_sqrt() - -- cgit v1.2.3