Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf1d85aa

Browse files
committed
Add support for hyperbolic functions, as well as log10().
The SQL:2016 standard adds support for the hyperbolic functionssinh(), cosh(), and tanh(). POSIX has long required libm toprovide those functions as well as their inverses asinh(),acosh(), atanh(). Hence, let's just expose the libm functionsto the SQL level. As with the trig functions, we only implementversions for float8, not numeric.For the moment, we'll assume that all platforms actually do havethese functions; if experience teaches otherwise, some autoconfeffort may be needed.SQL:2016 also adds support for base-10 logarithm, but with thefunction name log10(), whereas the name we've long used is log().Add aliases named log10() for the float8 and numeric versions.Lætitia AvrotDiscussion:https://postgr.es/m/CAB_COdguG22LO=rnxDQ2DW1uzv8aQoUzyDQNJjrR4k00XSgm5w@mail.gmail.com
1 parent3aa0395 commitf1d85aa

File tree

6 files changed

+333
-6
lines changed

6 files changed

+333
-6
lines changed

‎doc/src/sgml/func.sgml

Lines changed: 105 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -896,6 +896,19 @@
896896
<entry><literal>2</literal></entry>
897897
</row>
898898

899+
<row>
900+
<entry>
901+
<indexterm>
902+
<primary>log10</primary>
903+
</indexterm>
904+
<literal><function>log10(<type>dp</type> or <type>numeric</type>)</function></literal>
905+
</entry>
906+
<entry>(same as input)</entry>
907+
<entry>base 10 logarithm</entry>
908+
<entry><literal>log10(100.0)</literal></entry>
909+
<entry><literal>2</literal></entry>
910+
</row>
911+
899912
<row>
900913
<entry><literal><function>log(<parameter>b</parameter> <type>numeric</type>,
901914
<parameter>x</parameter> <type>numeric</type>)</function></literal></entry>
@@ -1147,8 +1160,8 @@
11471160
</para>
11481161

11491162
<para>
1150-
Finally,<xref linkend="functions-math-trig-table"/> shows the
1151-
available trigonometric functions. Alltrigonometric functions
1163+
<xref linkend="functions-math-trig-table"/> shows the
1164+
available trigonometric functions. Allthese functions
11521165
take arguments and return values of type <type>double
11531166
precision</type>. Each of the trigonometric functions comes in
11541167
two variants, one that measures angles in radians and one that
@@ -1311,6 +1324,96 @@
13111324
</para>
13121325
</note>
13131326

1327+
<para>
1328+
<xref linkend="functions-math-hyp-table"/> shows the
1329+
available hyperbolic functions. All these functions
1330+
take arguments and return values of type <type>double
1331+
precision</type>.
1332+
</para>
1333+
1334+
<table id="functions-math-hyp-table">
1335+
<title>Hyperbolic Functions</title>
1336+
1337+
<tgroup cols="4">
1338+
<thead>
1339+
<row>
1340+
<entry>Function</entry>
1341+
<entry>Description</entry>
1342+
<entry>Example</entry>
1343+
<entry>Result</entry>
1344+
</row>
1345+
</thead>
1346+
<tbody>
1347+
<row>
1348+
<entry>
1349+
<indexterm>
1350+
<primary>sinh</primary>
1351+
</indexterm>
1352+
<literal><function>sinh(<replaceable>x</replaceable>)</function></literal>
1353+
</entry>
1354+
<entry>hyperbolic sine</entry>
1355+
<entry><literal>sinh(0)</literal></entry>
1356+
<entry><literal>0</literal></entry>
1357+
</row>
1358+
<row>
1359+
<entry>
1360+
<indexterm>
1361+
<primary>cosh</primary>
1362+
</indexterm>
1363+
<literal><function>cosh(<replaceable>x</replaceable>)</function></literal>
1364+
</entry>
1365+
<entry>hyperbolic cosine</entry>
1366+
<entry><literal>cosh(0)</literal></entry>
1367+
<entry><literal>1</literal></entry>
1368+
</row>
1369+
<row>
1370+
<entry>
1371+
<indexterm>
1372+
<primary>tanh</primary>
1373+
</indexterm>
1374+
<literal><function>tanh(<replaceable>x</replaceable>)</function></literal>
1375+
</entry>
1376+
<entry>hyperbolic tangent</entry>
1377+
<entry><literal>tanh(0)</literal></entry>
1378+
<entry><literal>0</literal></entry>
1379+
</row>
1380+
<row>
1381+
<entry>
1382+
<indexterm>
1383+
<primary>asinh</primary>
1384+
</indexterm>
1385+
<literal><function>asinh(<replaceable>x</replaceable>)</function></literal>
1386+
</entry>
1387+
<entry>inverse hyperbolic sine</entry>
1388+
<entry><literal>asinh(0)</literal></entry>
1389+
<entry><literal>0</literal></entry>
1390+
</row>
1391+
<row>
1392+
<entry>
1393+
<indexterm>
1394+
<primary>acosh</primary>
1395+
</indexterm>
1396+
<literal><function>acosh(<replaceable>x</replaceable>)</function></literal>
1397+
</entry>
1398+
<entry>inverse hyperbolic cosine</entry>
1399+
<entry><literal>acosh(1)</literal></entry>
1400+
<entry><literal>0</literal></entry>
1401+
</row>
1402+
<row>
1403+
<entry>
1404+
<indexterm>
1405+
<primary>atanh</primary>
1406+
</indexterm>
1407+
<literal><function>atanh(<replaceable>x</replaceable>)</function></literal>
1408+
</entry>
1409+
<entry>inverse hyperbolic tangent</entry>
1410+
<entry><literal>atanh(0)</literal></entry>
1411+
<entry><literal>0</literal></entry>
1412+
</row>
1413+
</tbody>
1414+
</tgroup>
1415+
</table>
1416+
13141417
</sect1>
13151418

13161419

‎src/backend/utils/adt/float.c

Lines changed: 157 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,9 +230,9 @@ float4in(PG_FUNCTION_ARGS)
230230
* detect whether it's a "real" out-of-range condition by checking
231231
* to see if the result is zero or huge.
232232
*
233-
* Use isinf() rather than HUGE_VALF on VS2013 because it generates
234-
* a spurious overflow warning for -HUGE_VALF. Also use isinf() if
235-
* HUGE_VALF is missing.
233+
* Use isinf() rather than HUGE_VALF on VS2013 because it
234+
*generatesa spurious overflow warning for -HUGE_VALF.Also use
235+
*isinf() ifHUGE_VALF is missing.
236236
*/
237237
if (val==0.0||
238238
#if !defined(HUGE_VALF)|| (defined(_MSC_VER)&& (_MSC_VER<1900))
@@ -2426,6 +2426,160 @@ radians(PG_FUNCTION_ARGS)
24262426
}
24272427

24282428

2429+
/* ========== HYPERBOLIC FUNCTIONS ========== */
2430+
2431+
2432+
/*
2433+
*dsinh- returns the hyperbolic sine of arg1
2434+
*/
2435+
Datum
2436+
dsinh(PG_FUNCTION_ARGS)
2437+
{
2438+
float8arg1=PG_GETARG_FLOAT8(0);
2439+
float8result;
2440+
2441+
errno=0;
2442+
result=sinh(arg1);
2443+
2444+
/*
2445+
* if an ERANGE error occurs, it means there is an overflow. For sinh,
2446+
* the result should be either -infinity or infinity, depending on the
2447+
* sign of arg1.
2448+
*/
2449+
if (errno==ERANGE)
2450+
{
2451+
if (arg1<0)
2452+
result=-get_float8_infinity();
2453+
else
2454+
result=get_float8_infinity();
2455+
}
2456+
2457+
check_float8_val(result, true, true);
2458+
PG_RETURN_FLOAT8(result);
2459+
}
2460+
2461+
2462+
/*
2463+
*dcosh- returns the hyperbolic cosine of arg1
2464+
*/
2465+
Datum
2466+
dcosh(PG_FUNCTION_ARGS)
2467+
{
2468+
float8arg1=PG_GETARG_FLOAT8(0);
2469+
float8result;
2470+
2471+
errno=0;
2472+
result=cosh(arg1);
2473+
2474+
/*
2475+
* if an ERANGE error occurs, it means there is an overflow. As cosh is
2476+
* always positive, it always means the result is positive infinity.
2477+
*/
2478+
if (errno==ERANGE)
2479+
result=get_float8_infinity();
2480+
2481+
check_float8_val(result, true, false);
2482+
PG_RETURN_FLOAT8(result);
2483+
}
2484+
2485+
/*
2486+
*dtanh- returns the hyperbolic tangent of arg1
2487+
*/
2488+
Datum
2489+
dtanh(PG_FUNCTION_ARGS)
2490+
{
2491+
float8arg1=PG_GETARG_FLOAT8(0);
2492+
float8result;
2493+
2494+
/*
2495+
* For tanh, we don't need an errno check because it never overflows.
2496+
*/
2497+
result=tanh(arg1);
2498+
2499+
check_float8_val(result, false, true);
2500+
PG_RETURN_FLOAT8(result);
2501+
}
2502+
2503+
/*
2504+
*dasinh- returns the inverse hyperbolic sine of arg1
2505+
*/
2506+
Datum
2507+
dasinh(PG_FUNCTION_ARGS)
2508+
{
2509+
float8arg1=PG_GETARG_FLOAT8(0);
2510+
float8result;
2511+
2512+
/*
2513+
* For asinh, we don't need an errno check because it never overflows.
2514+
*/
2515+
result=asinh(arg1);
2516+
2517+
check_float8_val(result, true, true);
2518+
PG_RETURN_FLOAT8(result);
2519+
}
2520+
2521+
/*
2522+
*dacosh- returns the inverse hyperbolic cosine of arg1
2523+
*/
2524+
Datum
2525+
dacosh(PG_FUNCTION_ARGS)
2526+
{
2527+
float8arg1=PG_GETARG_FLOAT8(0);
2528+
float8result;
2529+
2530+
/*
2531+
* acosh is only defined for inputs >= 1.0. By checking this ourselves,
2532+
* we need not worry about checking for an EDOM error, which is a good
2533+
* thing because some implementations will report that for NaN. Otherwise,
2534+
* no error is possible.
2535+
*/
2536+
if (arg1<1.0)
2537+
ereport(ERROR,
2538+
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
2539+
errmsg("input is out of range")));
2540+
2541+
result=acosh(arg1);
2542+
2543+
check_float8_val(result, true, true);
2544+
PG_RETURN_FLOAT8(result);
2545+
}
2546+
2547+
/*
2548+
*datanh- returns the inverse hyperbolic tangent of arg1
2549+
*/
2550+
Datum
2551+
datanh(PG_FUNCTION_ARGS)
2552+
{
2553+
float8arg1=PG_GETARG_FLOAT8(0);
2554+
float8result;
2555+
2556+
/*
2557+
* atanh is only defined for inputs between -1 and 1. By checking this
2558+
* ourselves, we need not worry about checking for an EDOM error, which is
2559+
* a good thing because some implementations will report that for NaN.
2560+
*/
2561+
if (arg1<-1.0||arg1>1.0)
2562+
ereport(ERROR,
2563+
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
2564+
errmsg("input is out of range")));
2565+
2566+
/*
2567+
* Also handle the infinity cases ourselves; this is helpful because old
2568+
* glibc versions may produce the wrong errno for this. All other inputs
2569+
* cannot produce an error.
2570+
*/
2571+
if (arg1==-1.0)
2572+
result=-get_float8_infinity();
2573+
elseif (arg1==1.0)
2574+
result=get_float8_infinity();
2575+
else
2576+
result=atanh(arg1);
2577+
2578+
check_float8_val(result, true, true);
2579+
PG_RETURN_FLOAT8(result);
2580+
}
2581+
2582+
24292583
/*
24302584
*drandom- returns a random number
24312585
*/

‎src/include/catalog/catversion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/*yyyymmddN */
56-
#defineCATALOG_VERSION_NO201903101
56+
#defineCATALOG_VERSION_NO201903121
5757

5858
#endif

‎src/include/catalog/pg_proc.dat

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2616,6 +2616,9 @@
26162616
{ oid => '1340', descr => 'base 10 logarithm',
26172617
proname => 'log', prorettype => 'float8', proargtypes => 'float8',
26182618
prosrc => 'dlog10' },
2619+
{ oid => '1194', descr => 'base 10 logarithm',
2620+
proname => 'log10', prorettype => 'float8', proargtypes => 'float8',
2621+
prosrc => 'dlog10' },
26192622
{ oid => '1341', descr => 'natural logarithm',
26202623
proname => 'ln', prorettype => 'float8', proargtypes => 'float8',
26212624
prosrc => 'dlog1' },
@@ -3282,6 +3285,25 @@
32823285
{ oid => '1610', descr => 'PI',
32833286
proname => 'pi', prorettype => 'float8', proargtypes => '', prosrc => 'dpi' },
32843287

3288+
{ oid => '2462', descr => 'hyperbolic sine',
3289+
proname => 'sinh', prorettype => 'float8', proargtypes => 'float8',
3290+
prosrc => 'dsinh' },
3291+
{ oid => '2463', descr => 'hyperbolic cosine',
3292+
proname => 'cosh', prorettype => 'float8', proargtypes => 'float8',
3293+
prosrc => 'dcosh' },
3294+
{ oid => '2464', descr => 'hyperbolic tangent',
3295+
proname => 'tanh', prorettype => 'float8', proargtypes => 'float8',
3296+
prosrc => 'dtanh' },
3297+
{ oid => '2465', descr => 'inverse hyperbolic sine',
3298+
proname => 'asinh', prorettype => 'float8', proargtypes => 'float8',
3299+
prosrc => 'dasinh' },
3300+
{ oid => '2466', descr => 'inverse hyperbolic cosine',
3301+
proname => 'acosh', prorettype => 'float8', proargtypes => 'float8',
3302+
prosrc => 'dacosh' },
3303+
{ oid => '2467', descr => 'inverse hyperbolic tangent',
3304+
proname => 'atanh', prorettype => 'float8', proargtypes => 'float8',
3305+
prosrc => 'datanh' },
3306+
32853307
{ oid => '1618',
32863308
proname => 'interval_mul', prorettype => 'interval',
32873309
proargtypes => 'interval float8', prosrc => 'interval_mul' },
@@ -4201,6 +4223,9 @@
42014223
{ oid => '1741', descr => 'base 10 logarithm',
42024224
proname => 'log', prolang => 'sql', prorettype => 'numeric',
42034225
proargtypes => 'numeric', prosrc => 'select pg_catalog.log(10, $1)' },
4226+
{ oid => '1481', descr => 'base 10 logarithm',
4227+
proname => 'log10', prolang => 'sql', prorettype => 'numeric',
4228+
proargtypes => 'numeric', prosrc => 'select pg_catalog.log(10, $1)' },
42044229
{ oid => '1742', descr => 'convert float4 to numeric',
42054230
proname => 'numeric', prorettype => 'numeric', proargtypes => 'float4',
42064231
prosrc => 'float4_numeric' },

‎src/test/regress/expected/float8.out

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,43 @@ SELECT '' AS five, * FROM FLOAT8_TBL;
454454
| -1.2345678901234e-200
455455
(5 rows)
456456

457+
-- hyperbolic functions
458+
SELECT sinh(float8 '0');
459+
sinh
460+
------
461+
0
462+
(1 row)
463+
464+
SELECT cosh(float8 '0');
465+
cosh
466+
------
467+
1
468+
(1 row)
469+
470+
SELECT tanh(float8 '0');
471+
tanh
472+
------
473+
0
474+
(1 row)
475+
476+
SELECT asinh(float8 '0');
477+
asinh
478+
-------
479+
0
480+
(1 row)
481+
482+
SELECT acosh(float8 '1');
483+
acosh
484+
-------
485+
0
486+
(1 row)
487+
488+
SELECT atanh(float8 '0');
489+
atanh
490+
-------
491+
0
492+
(1 row)
493+
457494
RESET extra_float_digits;
458495
-- test for over- and underflow
459496
INSERT INTO FLOAT8_TBL(f1) VALUES ('10e400');

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp