HaikuDepot: notify work status from main window
[haiku.git] / src / libs / mapm / mapmcbrt.c
blobe696762a6a1dd07908c614e1a8ceda54970123cf
2 /*
3 * M_APM - mapmcbrt.c
5 * Copyright (C) 2000 - 2007 Michael C. Ring
7 * Permission to use, copy, and distribute this software and its
8 * documentation for any purpose with or without fee is hereby granted,
9 * provided that the above copyright notice appear in all copies and
10 * that both that copyright notice and this permission notice appear
11 * in supporting documentation.
13 * Permission to modify the software is granted. Permission to distribute
14 * the modified code is granted. Modifications are to be distributed by
15 * using the file 'license.txt' as a template to modify the file header.
16 * 'license.txt' is available in the official MAPM distribution.
18 * This software is provided "as is" without express or implied warranty.
22 * $Id: mapmcbrt.c,v 1.8 2007/12/03 01:50:32 mike Exp $
24 * This file contains the CBRT (cube root) function.
26 * $Log: mapmcbrt.c,v $
27 * Revision 1.8 2007/12/03 01:50:32 mike
28 * Update license
30 * Revision 1.7 2003/05/05 18:17:38 mike
31 * simplify some logic
33 * Revision 1.6 2003/04/16 16:55:58 mike
34 * use new faster algorithm which finds 1 / cbrt(N)
36 * Revision 1.5 2002/11/03 21:34:34 mike
37 * Updated function parameters to use the modern style
39 * Revision 1.4 2000/10/30 16:42:22 mike
40 * minor speed optimization
42 * Revision 1.3 2000/07/11 18:03:39 mike
43 * make better estimate for initial precision
45 * Revision 1.2 2000/04/08 18:34:35 mike
46 * added some more comments
48 * Revision 1.1 2000/04/03 17:58:04 mike
49 * Initial revision
52 #include "m_apm_lc.h"
54 /****************************************************************************/
55 void m_apm_cbrt(M_APM rr, int places, M_APM aa)
57 M_APM last_x, guess, tmpN, tmp7, tmp8, tmp9;
58 int ii, nexp, bflag, tolerance, maxp, local_precision;
60 /* result is 0 if input is 0 */
62 if (aa->m_apm_sign == 0)
64 M_set_to_zero(rr);
65 return;
68 last_x = M_get_stack_var();
69 guess = M_get_stack_var();
70 tmpN = M_get_stack_var();
71 tmp7 = M_get_stack_var();
72 tmp8 = M_get_stack_var();
73 tmp9 = M_get_stack_var();
75 /* compute the cube root of the positive number, we'll fix the sign later */
77 m_apm_absolute_value(tmpN, aa);
79 /*
80 normalize the input number (make the exponent near 0) so
81 the 'guess' function will not over/under flow on large
82 magnitude exponents.
85 nexp = aa->m_apm_exponent / 3;
86 tmpN->m_apm_exponent -= 3 * nexp;
88 M_get_cbrt_guess(guess, tmpN);
90 tolerance = places + 4;
91 maxp = places + 16;
92 bflag = FALSE;
93 local_precision = 14;
95 m_apm_negate(last_x, MM_Ten);
97 /* Use the following iteration to calculate 1 / cbrt(N) :
100 X = [ 4 * X - N * X ] / 3
101 n+1
104 ii = 0;
106 while (TRUE)
108 m_apm_multiply(tmp8, guess, guess);
109 m_apm_multiply(tmp7, tmp8, tmp8);
110 m_apm_round(tmp8, local_precision, tmp7);
111 m_apm_multiply(tmp9, tmpN, tmp8);
113 m_apm_multiply(tmp8, MM_Four, guess);
114 m_apm_subtract(tmp7, tmp8, tmp9);
115 m_apm_divide(guess, local_precision, tmp7, MM_Three);
117 if (bflag)
118 break;
120 /* force at least 2 iterations so 'last_x' has valid data */
122 if (ii != 0)
124 m_apm_subtract(tmp8, guess, last_x);
126 if (tmp8->m_apm_sign == 0)
127 break;
129 if ((-4 * tmp8->m_apm_exponent) > tolerance)
130 bflag = TRUE;
133 local_precision *= 2;
135 if (local_precision > maxp)
136 local_precision = maxp;
138 m_apm_copy(last_x, guess);
139 ii = 1;
142 /* final cbrt = N * guess ^ 2 */
144 m_apm_multiply(tmp9, guess, guess);
145 m_apm_multiply(tmp8, tmp9, tmpN);
146 m_apm_round(rr, places, tmp8);
148 rr->m_apm_exponent += nexp;
149 rr->m_apm_sign = aa->m_apm_sign;
150 M_restore_stack(6);
152 /****************************************************************************/