pgadmin3/pgscript/utilities/m_apm/mapmgues.cpp
2020-07-07 22:19:12 +05:00

147 lines
3.8 KiB
C++

/*
* M_APM - mapmgues.c
*
* Copyright (C) 1999 - 2007 Michael C. Ring
*
* Permission to use, copy, and distribute this software and its
* documentation for any purpose with or without fee is hereby granted,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation.
*
* Permission to modify the software is granted. Permission to distribute
* the modified code is granted. Modifications are to be distributed by
* using the file 'license.txt' as a template to modify the file header.
* 'license.txt' is available in the official MAPM distribution.
*
* This software is provided "as is" without express or implied warranty.
*/
/*
*
* This file contains the functions that generate the initial
* 'guesses' for the sqrt, cbrt, log, arcsin, and arccos functions.
*/
#include "pgAdmin3.h"
#include "pgscript/utilities/mapm-lib/m_apm_lc.h"
/****************************************************************************/
void M_get_sqrt_guess(M_APM r, M_APM a)
{
char buf[48];
double dd;
m_apm_to_string(buf, 15, a);
dd = atof(buf); /* sqrt algorithm actually finds 1/sqrt */
m_apm_set_double(r, (1.0 / sqrt(dd)));
}
/****************************************************************************/
/*
* for cbrt, log, asin, and acos we induce an error of 10 ^ -5.
* this enables the iterative routine to be more efficient
* by knowing exactly how accurate the initial guess is.
*
* this also prevents some corner conditions where the iterative
* functions may terminate too soon.
*/
/****************************************************************************/
void M_get_cbrt_guess(M_APM r, M_APM a)
{
char buf[48];
double dd;
m_apm_to_string(buf, 15, a);
dd = atof(buf);
dd = log(dd) / 3.0; /* cbrt algorithm actually finds 1/cbrt */
m_apm_set_double(r, (1.00001 / exp(dd)));
}
/****************************************************************************/
void M_get_log_guess(M_APM r, M_APM a)
{
char buf[48];
double dd;
m_apm_to_string(buf, 15, a);
dd = atof(buf);
m_apm_set_double(r, (1.00001 * log(dd))); /* induce error of 10 ^ -5 */
}
/****************************************************************************/
/*
* the implementation of the asin & acos functions
* guarantee that 'a' is always < 0.85, so it is
* safe to multiply by a number > 1
*/
void M_get_asin_guess(M_APM r, M_APM a)
{
char buf[48];
double dd;
m_apm_to_string(buf, 15, a);
dd = atof(buf);
m_apm_set_double(r, (1.00001 * asin(dd))); /* induce error of 10 ^ -5 */
}
/****************************************************************************/
void M_get_acos_guess(M_APM r, M_APM a)
{
char buf[48];
double dd;
m_apm_to_string(buf, 15, a);
dd = atof(buf);
m_apm_set_double(r, (1.00001 * acos(dd))); /* induce error of 10 ^ -5 */
}
/****************************************************************************/
/*
convert a C 'double' into an M_APM value.
*/
void m_apm_set_double(M_APM atmp, double dd)
{
char *cp, *p, *ps, buf[64];
if (dd == 0.0) /* special case for 0 exactly */
M_set_to_zero(atmp);
else
{
sprintf(buf, "%.14E", dd);
if ((cp = strstr(buf, "E")) == NULL)
{
M_apm_log_error_msg(M_APM_RETURN,
"\'m_apm_set_double\', Invalid double input (likely a NAN or +/- INF)");
M_set_to_zero(atmp);
return;
}
if (atoi(cp + sizeof(char)) == 0)
*cp = '\0';
p = cp;
while (TRUE)
{
p--;
if (*p == '0' || *p == '.')
*p = ' ';
else
break;
}
ps = buf;
p = buf;
while (TRUE)
{
if ((*p = *ps) == '\0')
break;
if (*ps++ != ' ')
p++;
}
m_apm_set_string(atmp, buf);
}
}
/****************************************************************************/