Cosine algo, was Re: sqrt algo

P

pete

it seems this cosr() is better :)
long double Kpi
=3.14159265358979323846264338327950288419716939937510L;

c_os is an academic exercise.

I will now state that the point was to get all or most
of the bits of precission available on the abstract machine,
including the one known as the DS9K.

Magic numbers like Kpi would be inapropriate.
 
P

pete

Jordan said:
Hold on... pi is inappropriate? What's he supposed to do, write the
whole thing out?

OK, I'll post it again.

#include <float.h>
#include <errno.h>
#include <math.h>

#include "ma_th.h"

static double p_i(void); /* pi == 4 * (atan(1/3.0) + atan(1/2.0)) */

double f_mod(double x, double y);
double c_os(double x);
double sq_rt(double x);

static double p_i(void)
{
unsigned n;
double p, a, b;

p = 0;
a = 3;
n = 1;
do {
a /= 9;
b = a / n;
a /= 9;
n += 2;
b -= a / n;
n += 2;
p += b;
} while (b > DBL_EPSILON / 4);
a = 2;
n = 1;
do {
a /= 4;
b = a / n;
a /= 4;
n += 2;
b -= a / n;
n += 2;
p += b;
} while (b > DBL_EPSILON / 2);
return 4 * p;
}

double c_os(double x)
{
unsigned n, negative, sine;
double a, b, c;
static double pi, two_pi, four_pi, half_pi, third_pi;

if (0 > x) {
x = -x;
}
if (DBL_MAX >= x) {
if (1 > pi) {
pi = p_i();
two_pi = 2 * pi;
four_pi = 4 * pi;
half_pi = pi / 2;
third_pi = pi / 3;
}
if (x > two_pi) {
x = f_mod(x, two_pi);
}
if (x > pi) {
x = two_pi - x;
}
if (x > half_pi) {
x = pi - x;
negative = 1;
} else {
negative = 0;
}
if (x > third_pi) {
x = half_pi - x;
sine = 1;
} else {
sine = 0;
}
c = x * x;
x = n = 0;
a = 1;
do {
b = a;
a *= c / ++n;
a /= ++n;
b -= a;
a *= c / ++n;
a /= ++n;
x += b;
} while (b > DBL_EPSILON / 2);
if (sine) {
x = sq_rt((1 - x) * (1 + x));
}
if (negative) {
x = -x;
}
} else {
errno = EDOM;
x = -HUGE_VAL;
}
return x;
}

double sq_rt(double x)
{
int n;
double a, b;

if (DBL_MAX >= x && x > 0) {
for (n = 0; x > 2; x /= 4) {
++n;
}
while (0.5 > x) {
--n;
x *= 4;
}
a = x;
b = (1 + x) / 2;
do {
x = b;
b = (a / x + x) / 2;
} while (x > b);
while (n > 0) {
x *= 2;
--n;
}
while (0 > n) {
x /= 2;
++n;
}
} else {
if (x != 0) {
errno = EDOM;
x = HUGE_VAL;
}
}
return x;
}

double f_mod(double x, double y)
{
double a, b, c;

if (0 > y) {
y = -y;
}
if ( y != 0 && DBL_MAX >= y
&& x >= -DBL_MAX && DBL_MAX >= x) {
for (a = 0 > x ? -x : x; a >= y; a -= c) {
b = a / 2;
c = y;
while (b >= c) {
c *= 2;
}
}
} else {
errno = EDOM;
a = 0;
}
if (0 > x) {
a = -a;
}
return a;
}
 
D

Dik T. Winter

> i have implemented in assembly Dik T. Winter sin333/cos333 routines
> (with some change).
> Do you see any error? (i'm not expert in FPU)
> In your opinion what is the better and why?

No idea. I can not use the assembly you write on the machines I normally
use for such tests. But you range reduction is still suboptimal with
respect to precision.
 
D

Dik T. Winter

>
> Hold on... pi is inappropriate? What's he supposed to do, write the
> whole thing out?

Indeed, the value of pi used is machine and precision dependent. I know
that in the DEC libraries pi was given in such precision that even for
large arguments the relative error after range reduction (assuming the
argument was exact) would have a small relativer error. So on those
machines the cosine and sine functions gave the best possible result
over the whole range of floating point numbers, under the assumption that
the argument was exact.
 
K

Keith Thompson

pete said:
OK, I'll post it again.

#include <float.h>
#include <errno.h>
#include <math.h>

#include "ma_th.h"

static double p_i(void); /* pi == 4 * (atan(1/3.0) + atan(1/2.0)) */

pete, I don't think you needed to re-post the whole thing to make
the point.

The point, as I understand it, is that any literal representation of
(an approximation of) pi might not be sufficiently precise for type
long double on some machine. If you happen to know the maximum
precision of any floating-point type on a given system, you can
declare pi as a constant and provide the required number of digits.
If you don't want to make any assumptions about precision, you can
compute the value of pi once, during program startup.

For example, assuming C99, you can declare

const long double pi = 4.0 * atanl(1.0);
 
P

pete

Keith said:
pete, I don't think you needed to re-post the whole thing to make
the point.

I like to post code a little too much.
There was a new standard library analogue there. f_mod is new.
The point, as I understand it, is that any literal representation of
(an approximation of) pi might not be sufficiently precise for type
long double on some machine.
For example, assuming C99, you can declare

const long double pi = 4.0 * atanl(1.0);

The code that I wrote, calls no standard library functions,
and is portable in both C89 and C99.

My decision not to hard code any approximations of pi
and not to call any standard library functions
was so that I could derive the cosine algorithm
entirely in terms of simple arithmetic operators
and logical decisions.
For numeric data, I only used integer constants
or floating values like 0.5,
which are likely to be exactly representable in floating point.

I wanted to see what might be involved in the logic
of calculating cosines from first principles.
 
P

pete

pete wrote:
I like to post code a little too much.
The code that I wrote, calls no standard library functions,
and is portable in both C89 and C99.
For numeric data, I only used integer constants
or floating values like 0.5,
which are likely to be exactly representable in floating point.
I wanted to see what might be involved in the logic
of calculating
from first principles.

One more time!

/* BEGIN l_og10.c output */

l_og10(10000) - 4 is 0.000000e+000
p_ow(0.01, -0.5) - 10 is 3.552714e-015
c_os(-244 * atan(1) / 3) - 0.5 is 9.992007e-016
sq_rt(2) * sq_rt(2) - 2 is -4.440892e-016

log10(10000) - 4 is 0.000000e+000
pow(0.01, -0.5) - 10 is 0.000000e+000
cos(-244 * atan(1) / 3) - 0.5 is 3.182025e-015
sqrt(2) * sqrt(2) - 2 is 4.440892e-016

l_og2(1 / 512.0) + 9 is 0.000000e+000

/* END l_og10.c output */



/* BEGIN ma_th.h */

#ifndef H_MA_TH_
#define H_MA_TH_
/*
** The IEC 60559 sqrt functions
** and other 60559 features are not implemented here
** as required by C99 when __STDC_IEC_559__ is defined.
*/
double sq_rt(double x);
double l_og(double x);
double l_og10(double x);
double e_xp(double x);
double mod_f(double value, double *iptr);
double f_mod(double x, double y);
double p_ow(double x, double y);
double c_os(double x);
/*
** C99
*/
long double sq_rtl(long double x);
double l_og2(double x);
double e_xp2(double x);

#endif

/* END ma_th.h */



/* BEGIN ma_th.c */

#include <float.h>
#include <errno.h>
#include <math.h>

#include "ma_th.h"

static double p_i(void); /* pi == 4 * (atan(1/3.0) + atan(1/2.0)) */

double sq_rt(double x)
{
int n;
double a, b;

if (DBL_MAX >= x && x > 0) {
for (n = 0; x > 2; x /= 4) {
++n;
}
while (0.5 > x) {
--n;
x *= 4;
}
a = x;
b = (1 + x) / 2;
do {
x = b;
b = (a / x + x) / 2;
} while (x > b);
while (n > 0) {
x *= 2;
--n;
}
while (0 > n) {
x /= 2;
++n;
}
} else {
if (x != 0) {
errno = EDOM;
x = HUGE_VAL;
}
}
return x;
}

double l_og(double x)
{
int n;
double a, b, c, epsilon;
static double A, B, C;

if (DBL_MAX >= x && x > 0) {
if (1 > A) {
A = sq_rt(2);
B = A / 2;
C = l_og(A);
}
for (n = 0; x > A; x /= 2) {
++n;
}
while (B > x) {
--n;
x *= 2;
}
a = (x - 1) / (x + 1);
x = C * n + a;
c = a * a;
n = 1;
epsilon = DBL_EPSILON * x;
if (0 > a) {
if (epsilon > 0) {
epsilon = -epsilon;
}
do {
n += 2;
a *= c;
b = a / n;
x += b;
} while (epsilon > b);
} else {
if (0 > epsilon) {
epsilon = -epsilon;
}
do {
n += 2;
a *= c;
b = a / n;
x += b;
} while (b > epsilon);
}
x *= 2;
} else {
errno = x != 0 ? EDOM : ERANGE;
x = -HUGE_VAL;
}
return x;
}

double l_og10(double x)
{
static double log_10;

if (1 > log_10) {
log_10 = l_og(10);
}
return x > 0 && DBL_MAX >= x ? l_og(x) / log_10 : l_og(x);
}

double e_xp(double x)
{
unsigned n, negative, square;
double b, e;
static double x_max;

if (0 > x) {
x = -x;
negative = 1;
} else {
negative = 0;
}
if (1 > x_max) {
x_max = l_og(DBL_MAX);
}
if (x_max >= x) {
for (square = 0; x > 1; x /= 2) {
++square;
}
e = b = n = 1;
do {
b /= n++;
b *= x;
e += b;
} while (b > DBL_EPSILON);
while (square-- != 0) {
e *= e;
}
if (negative) {
e = 1 / e;
}
} else {
errno = x > DBL_MAX ? EDOM : ERANGE;
e = negative ? 0 : HUGE_VAL;
}
return e;
}

double mod_f(double value, double *iptr)
{
double a, b;
const double v = value;

if (0 > v) {
value = -value;
}
if (DBL_MAX >= value) {
for (*iptr = 0; value >= 1; value -= a) {
b = value / 2;
a = 1;
while (b >= a) {
a *= 2;
}
*iptr += a;
}
} else {
errno = EDOM;
*iptr = value;
value = 0;
}
if (0 > v) {
value = -value;
*iptr = -*iptr;
}
return value;
}

double f_mod(double x, double y)
{
double a, b, c;

if (0 > y) {
y = -y;
}
if ( y != 0 && DBL_MAX >= y
&& x >= -DBL_MAX && DBL_MAX >= x) {
for (a = 0 > x ? -x : x; a >= y; a -= c) {
b = a / 2;
c = y;
while (b >= c) {
c *= 2;
}
}
} else {
errno = EDOM;
a = 0;
}
if (0 > x) {
a = -a;
}
return a;
}

double p_ow(double x, double y)
{
double p;

if (0 > x && f_mod(y, 1) == 0) {
if (f_mod(y, 2) == 0) {
p = e_xp(l_og(-x) * y);
} else {
p = -e_xp(l_og(-x) * y);
}
} else {
if (x != 0 || 0 >= y) {
p = e_xp(l_og( x) * y);
} else {
p = 0;
}
}
return p;
}

static double p_i(void)
{
unsigned n;
double p, a, b;

p = 0;
a = 3;
n = 1;
do {
a /= 9;
b = a / n;
a /= 9;
n += 2;
b -= a / n;
n += 2;
p += b;
} while (b > DBL_EPSILON / 4);
a = 2;
n = 1;
do {
a /= 4;
b = a / n;
a /= 4;
n += 2;
b -= a / n;
n += 2;
p += b;
} while (b > DBL_EPSILON / 2);
return 4 * p;
}

double c_os(double x)
{
unsigned n, negative, sine;
double a, b, c;
static double pi, two_pi, four_pi, half_pi, third_pi;

if (0 > x) {
x = -x;
}
if (DBL_MAX >= x) {
if (1 > pi) {
pi = p_i();
two_pi = 2 * pi;
four_pi = 4 * pi;
half_pi = pi / 2;
third_pi = pi / 3;
}
if (x > two_pi) {
x = f_mod(x, two_pi);
}
if (x > pi) {
x = two_pi - x;
}
if (x > half_pi) {
x = pi - x;
negative = 1;
} else {
negative = 0;
}
if (x > third_pi) {
x = half_pi - x;
sine = 1;
} else {
sine = 0;
}
c = x * x;
x = n = 0;
a = 1;
do {
b = a;
a *= c / ++n;
a /= ++n;
b -= a;
a *= c / ++n;
a /= ++n;
x += b;
} while (b > DBL_EPSILON / 2);
if (sine) {
x = sq_rt((1 - x) * (1 + x));
}
if (negative) {
x = -x;
}
} else {
errno = EDOM;
x = -HUGE_VAL;
}
return x;
}

long double sq_rtl(long double x)
{
long int n;
long double a, b;

if (LDBL_MAX >= x && x > 0) {
for (n = 0; x > 2; x /= 4) {
++n;
}
while (0.5 > x) {
--n;
x *= 4;
}
a = x;
b = (1 + x) / 2;
do {
x = b;
b = (a / x + x) / 2;
} while (x > b);
while (n > 0) {
x *= 2;
--n;
}
while (0 > n) {
x /= 2;
++n;
}
} else {
if (x != 0) {
errno = EDOM;
x = HUGE_VAL;
}
}
return x;
}

double l_og2(double x)
{
static double log_2;

if (0.5 > log_2) {
log_2 = l_og(2);
}
return x > 0 && DBL_MAX >= x ? l_og(x) / log_2 : l_og(x);
}

double e_xp2(double x)
{
static double log_2;

if (0.5 > log_2) {
log_2 = l_og(2);
}
return e_xp(x * log_2);
}

/* END ma_th.c */



/* BEGIN l_og10.c */

#include <stdio.h>
#include <math.h>

#include "ma_th.h"

int main(void)
{
puts("/* BEGIN l_og10.c output */\n");
printf("l_og10(10000) - 4 is %e\n"
, l_og10(10000) - 4);
printf("p_ow(0.01, -0.5) - 10 is %e\n"
, p_ow(0.01, -0.5) - 10);
printf("c_os(-244 * atan(1) / 3) - 0.5 is %e\n"
, c_os(-244 * atan(1) / 3) - 0.5);
printf("sq_rt(2) * sq_rt(2) - 2 is %e\n"
, sq_rt(2) * sq_rt(2) - 2);
putchar('\n');
printf("log10(10000) - 4 is %e\n"
, log10(10000) - 4);
printf("pow(0.01, -0.5) - 10 is %e\n"
, pow(0.01, -0.5) - 10);
printf("cos(-244 * atan(1) / 3) - 0.5 is %e\n"
, cos(-244 * atan(1) / 3) - 0.5);
printf("sqrt(2) * sqrt(2) - 2 is %e\n"
, sqrt(2) * sqrt(2) - 2);
putchar('\n');
printf("l_og2(1 / 512.0) + 9 is %e\n"
, l_og2(1 / 512.0) + 9);
puts("\n/* END l_og10.c output */");
return 0;
}

/* END l_og10.c */
 
J

Jordan Abel

For example, assuming C99, you can declare

const long double pi = 4.0 * atanl(1.0);

Assuming that atan provides maximum precision [and that floats are
binary]
 
K

Keith Thompson

Jordan Abel said:
For example, assuming C99, you can declare

const long double pi = 4.0 * atanl(1.0);

Assuming that atan provides maximum precision [and that floats are
binary]

I see the issue with the precisoin of atanl, but why would non-binary
floats be a problem?
 
N

Netocrat

I like to post code a little too much.

Step one is to admit that you are powerless over alcohol...

But this seems to be a first: an addiction for which there isn't a
specific twelve-step program.
 
R

Richard Bos

Netocrat said:
Step one is to admit that you are powerless over alcohol...

But this seems to be a first: an addiction for which there isn't a
specific twelve-step program.

The two addictions of programmers: caffeine and coding.

Me, I don't _want_ to kick those habits.

Richard
 
D

Dik T. Winter

> Jordan Abel said:
> > On 2005-10-28 said:
> >> For example, assuming C99, you can declare
> >>
> >> const long double pi = 4.0 * atanl(1.0);
> >
> > Assuming that atan provides maximum precision [and that floats are
> > binary]
>
> I see the issue with the precisoin of atanl, but why would non-binary
> floats be a problem?

Multiplication by 4 is not necessarily exact.
 
C

cs

No idea. I can not use the assembly you write on the machines I normally
use for such tests. But you range reduction is still suboptimal with
respect to precision.

and how can i have the result "optimal respect to precision"?
i don't know much of calculus but seems i know that for
"fixed point numbers rappresentation"
1) * is the killer of the precision
2) if i have to do thing as (a*b)/(k*t) with k,t>=1
then for precision way of see, i have to do it in this way
(a/k)*(b/t)
Is it true?
Are there others 'practical' formulas for precision subject?
 
P

pete

Keith said:
pete, I don't think you needed to re-post the whole thing to make
the point.

The point, as I understand it, is that any literal representation of
(an approximation of) pi might not be sufficiently precise for type
long double on some machine. If you happen to know the maximum
precision of any floating-point type on a given system, you can
declare pi as a constant and provide the required number of digits.
If you don't want to make any assumptions about precision, you can
compute the value of pi once, during program startup.

For example, assuming C99, you can declare

const long double pi = 4.0 * atanl(1.0);

p_i is portable freestanding C89 and C99.
The rest of the functions can be converted to freestanding
just by removing all of the statements which contain errno,
and by finding some way to replace the references to HUGE_VAL.
That's not complicated.
In sq_rt, the simplest way to convert to portable free standing,
is to remove the else statement.
In l_og and c_os, HUGE_VAL can be replaced by DBL_MAX.
In e_xp, HUGE_VAL can be replaced by -1.
 
D

Dik T. Winter

>
> and how can i have the result "optimal respect to precision"?

Depends on what the purpose is. If you want to create a routine that
assumes that the input is exact and that returns the best possible
result, you need an extremely good (in number of bits) approximation
to pi and go through quite some convolution to make the range
reduction correct. If you are only wishing to create a routine that
assumes the argument is inexact, and that returns a number that is
valid for some argument in the assumed range, you have quite a bit of
freedom. For instance, in the latter case, when the argument is larger
than 2^55 you can return whatever value you wish in the range [-1, 1].
> i don't know much of calculus but seems i know that for
> "fixed point numbers rappresentation"
> 1) * is the killer of the precision
> 2) if i have to do thing as (a*b)/(k*t) with k,t>=1
> then for precision way of see, i have to do it in this way
> (a/k)*(b/t)
> Is it true?
> Are there others 'practical' formulas for precision subject?

There is a whole field of mathematics that is devoted to this subject.
Numerical mathematics. But there is again a difference when you only
wish a good absolute error or a good relative error.
 
C

cs

Depends on what the purpose is. If you want to create a routine that
assumes that the input is exact and that returns the best possible
result, you need an extremely good (in number of bits) approximation
to pi and go through quite some convolution to make the range
reduction correct.

that range reduction for sen/cos seems ok (max only 1 decimal digit of
error for call) what is not ok is this

arccos(cos(x)) where x>0 very small e.g. 0.0000000000001
(or 0.00000000000000000000000000000000000000001 :)) )
y=cos(x) and y is ok, but arccos(y) has many decimal digits != x (5-6
too)
where

fnum arccos(fnum x){return Kpi/2 - arcsin(x); }

fnum arcsin(fnum x)
{fnum x1, x2, x3;
if(x>1 || x< -1)
{printf("arcsin(): Errore argomento fuori range\n");
R (fnum) 0;
}
if(x== 1) return Kpi/2;
if(x==-1) return -Kpi/2;
if(x< 0) {x=-x; return -arcsin(x);}
x1=1-x*x; x2=sqrt_f(x1); x3=x/x2;
return arctg(x3);
}

this is the problem
If you are only wishing to create a routine that
assumes the argument is inexact,

i assume argument is always exact the problem is the result
 
D

Dik T. Winter

> On Sun, 30 Oct 2005 02:39:23 GMT, "Dik T. Winter" <[email protected]>
> wrote: ....
>
> that range reduction for sen/cos seems ok (max only 1 decimal digit of
> error for call) what is not ok is this

I suspect that is false when the argument is large. Do you mean relative
error or absolute error?
> arccos(cos(x)) where x>0 very small e.g. 0.0000000000001
> (or 0.00000000000000000000000000000000000000001 :)) )
> y=cos(x) and y is ok, but arccos(y) has many decimal digits != x (5-6
> too)

Yes. You can estimate the error of a function as follows. Start with
the function (f(x)), next take the derivative of that function (d/dx f(x)),
When the absolute error in x is some value eps, the absolute error in the
approximation will be eps * d/dx f(x). For arccos this works out to
eps * 1/sqrt(1 - x^2)). You may note that when x is close to 1,
sqrt(1 - x^2) is close to 0, and so the error blows up.
> fnum arccos(fnum x){return Kpi/2 - arcsin(x); }

As pi/2 is about 1.5, the best you can expect with this is an absolute
error of 2**(-53).
 
C

cs

that range reduction for sen/cos seems ok (max only 1 decimal digit of
error for call) what is not ok is this

arccos(cos(x)) where x>0 very small e.g. 0.0000000000001
(or 0.00000000000000000000000000000000000000001 :)) )
y=cos(x) and y is ok, but arccos(y) has many decimal digits != x (5-6
too)

for see something

----------------------------------------
#include "kilo.h"

extern fnum Kpi, K2pi, Kpi2, Kpi4, Ke, Katg025;
extern int libero_m_;
extern U c_arctg;
extern U precision;
extern U c_cos;
extern U c_phi;
extern volatile sig_atomic_t segnale_;
int varia=0;


int main( void )
{U mm;
libero_m_=0;
os "inserisci la precisione >"; is mm;
set_precision(mm);
{int i, ii;
U u, uu;
double x;
fnum a="23.85", c=-23.85e50, b=-7.145e-15, e, f;
fnum x0, x1, x2, x3, x4;
snum a3;
num aa, bb, cc;
os "Inserisci un numero >"; is a;
os "Inserisci un il moltiplicatore >"; is f;

a=a+f*K2pi;
c_cos=0;
// os "pi==" << Kpi << "\n";
b= tan(a);
os "tan(a)== " << b << " ";
P("c_tan = %u\n", c_cos);

c_arctg=0;
os "atg(a)== " << arctg(b) << " ";
P("c_atng = %u\n", c_arctg );

c_phi=0;
os "atan_phi(a)==" << atan_phi(b) << " ";
P("c_atng_p= %u\n", c_phi);

c_cos=0;
b= cos(a); x4=b;
os "cos(a)== " << b << " ";
P("c_cos = %u\n", c_cos);

c_arctg=0;
os "acos(a)== " << acos(b) << " ";
P("c_acs = %u\n", c_arctg );

c_phi=0;
os "acos_phi(a)==" << acos_phi(b) << " ";
P("c_acs_p = %u\n", c_phi);

c_cos=0;
b= sin(a);
os "sin(a)== " << b << " ";
P("c_sin = %u\n", c_cos);

c_arctg=0;
os "asin(a)== " << asin(b) << " ";
P("c_acs = %u\n", c_arctg );

c_phi=0;
os "asin_phi(a)==" << asin_phi(b) << " ";
P("c_acs_p= %u\n", c_phi);
if(a>1) {os a << "> " << "1\n";}
else {os a << "<=" << "1\n";}

}
R 0;
}

-------------------------------------------------------
inserisci la precisione >5
Inserisci un numero >0.111111111111111111
Inserisci un il moltiplicatore >5000000000000000000000
tan(a)== 0.1115706278338005836140105774725818603335118300689F
c_tan = 23
atg(a)== 0.1111111111111111109999999999999999999999999999996F
c_atng = 23
atan_phi(a)==0.1111111111111111110000000000000000000000000000003F
c_atng_p= 73
cos(a)== 0.9938335085388919213152595951271344427065097136775F
c_cos = 12
acos(a)== 0.1111111111111111109999999999999999999999999999955F
c_acs = 23
acos_phi(a)==0.1111111111111111110000000000000000000000000000003F
c_acs_p = 73
sin(a)== 0.1108826285099529849812660263523212555739213248246F
c_sin = 11
asin(a)== 0.1111111111111111109999999999999999999999999999996F
c_acs = 23
asin_phi(a)==0.1111111111111111109999999999999999999999999998710F
c_acs_p= 76
31415926535897932384626.5449439061399530826939937499457555285825577398963F>
1
MEMORIA DINAMICA LIBERATA
------------------------------------------------------

here seems all ok, the error is in the last decimal digit of the
numbern (note the 5000000000000000000000 moltiplicator)

---------------------------------
inserisci la precisione >5
Inserisci un numero >0.00000000000000000001
Inserisci un il moltiplicatore >0
tan(a)== 0.0000000000000000000099999999999999999999999999998F
c_tan = 1
atg(a)== 0.0000000000000000000099999999999999999999999999998F
c_atng = 0
atan_phi(a)==0.0000000000000000000099999999407085749105512617598F
c_atng_p= 9
cos(a)== 0.9999999999999999999999999999999999999999500000005F
c_cos = 1
acos(a)== 0.0000000000000000000099999999407085749105512617598F
c_acs = 0
acos_phi(a)==0.0000000000000000000099999999407085749105512617598F
c_acs_p = 9
sin(a)== 0.0000000000000000000099999999999999999999999999998F
c_sin = 0
asin(a)== 0.0000000000000000000099999999999999999999999999998F
c_acs = 0
asin_phi(a)==0.0000000000000000000099999999999999999999999998411F
c_acs_p= 76
0.0000000000000000000099999999999999999999999999998F<=1
MEMORIA DINAMICA LIBERATA
-------------------------------------------

here is not ok because acos(a)==
0.0000000000000000000099999999407085749105512617598F
!= 0.00000000000000000001
in several digits

---------------------------------------------------------
Inserisci un numero >1.2222222222222222222
Inserisci un il moltiplicatore >0
tan(a)==
2.7516868611940567318071872220530884537479613137095596914917F c_ta
n = 34
atg(a)==
1.2222222222222222222000000000000000000000000000000000000000F c_at
ng = 28
atan_phi(a)==1.2222222222222222222000000000000000000000000000000000000228F
c_at
ng_p= 92
cos(a)==
0.3415580120674962110596996650852662387419748224742741638229F c_co
s = 17
acos(a)==
1.2222222222222222222000000000000000000000000000000000000002F c_ac
s = 28
acos_phi(a)==1.2222222222222222222000000000000000000000000000000000000228F
c_ac
s_p = 92
sin(a)==
0.9398606941416904006846365840250964465081184244072584161975F c_si
n = 17
asin(a)==
1.2222222222222222221999999999999999999999999999999999999991F c_ac
s = 28
asin_phi(a)==1.2222222222222222221999999999999999999999999999999999999932F
c_ac
s_p= 90
1.2222222222222222221999999999999999999999999999999999999999F> 1
MEMORIA DINAMICA LIBERATA
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top