home *** CD-ROM | disk | FTP | other *** search
- /* -----------------------------------------------------------------
-
- This file contains the "big number" high precision versions of the
- fractal routines.
-
- -------------------------------------------------------------------- */
-
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <float.h>
- #include <limits.h>
- #include <string.h>
- #ifdef __TURBOC__
- #include <alloc.h>
- #elif !defined(__386BSD__)
- #include <malloc.h>
- #endif
- #include "fractint.h"
- #include "helpdefs.h"
- #include "fractype.h"
- #include "prototyp.h"
- #include "biginit.h"
-
- int bf_math = 0;
-
- #if (_MSC_VER >= 700)
- #pragma code_seg ("bigsetup_text") /* place following in an overlay */
- #endif
-
- /* #define DEBUG */
- /* following are handy debugging tools */
- #ifdef DEBUG
-
- /**********************************************************************/
- void show_var_bn(char *s, bn_t n)
- {
- char msg[200];
- strcpy(msg,s);
- strcat(msg," ");
- bntostr(msg+strlen(s),40,n);
- msg[79] = 0;
- stopmsg(0,(char far *)msg);
- }
-
- void showcornersdbl(char *s)
- {
- char msg[400];
- sprintf(msg,"%s\n\
- xxmin= %.20f xxmax= %.20f\n\
- yymin= %.20f yymax= %.20f\n\
- xx3rd= %.20f yy3rd= %.20f\n\
- delxx= %.20Lf delyy= %.20Lf\n\
- delx2= %.20Lf dely2= %.20Lf",s,xxmin,xxmax,yymin,yymax,xx3rd,yy3rd,
- delxx, delyy,delxx2, delyy2);
- if(stopmsg(0,msg)==-1)
- goodbye();
- }
-
- /* show floating point and bignumber corners */
- void showcorners(char *s)
- {
- int dec=20;
- char msg[100],msg1[100],msg3[100];
- bntostr(msg,dec,bnxmin);
- sprintf(msg1,"bnxmin=%s\nxxmin= %.20f\n\n",msg,xxmin);
- strcpy(msg3,s);
- strcat(msg3,"\n");
- strcat(msg3,msg1);
- bntostr(msg,dec,bnxmax);
- sprintf(msg1,"bnxmax=%s\nxxmax= %.20f\n\n",msg,xxmax);
- strcat(msg3,msg1);
- bntostr(msg,dec,bnymin);
- sprintf(msg1,"bnymin=%s\nyymin= %.20f\n\n",msg,yymin);
- strcat(msg3,msg1);
- bntostr(msg,dec,bnymax);
- sprintf(msg1,"bnymax=%s\nyymax= %.20f\n\n",msg,yymax);
- strcat(msg3,msg1);
- bntostr(msg,dec,bnx3rd);
- sprintf(msg1,"bnx3rd=%s\nxx3rd= %.20f\n\n",msg,xx3rd);
- strcat(msg3,msg1);
- bntostr(msg,dec,bny3rd);
- sprintf(msg1,"bny3rd=%s\nyy3rd= %.20f\n\n",msg,yy3rd);
- strcat(msg3,msg1);
- if(stopmsg(0,msg3)==-1)
- goodbye();
- }
-
- /* show globals */
- void showbfglobals(char *s)
- {
- char msg[300];
- sprintf(msg, "%s\n\
- bnstep=%d bnlength=%d intlength=%d rlength=%d padding=%d\n\
- shiftfactor=%d decimals=%d bflength=%d rbflength=%d \n\
- bfshiftfactor=%d bfdecimals=%d ",
- s, bnstep, bnlength, intlength, rlength, padding,
- shiftfactor, decimals, bflength, rbflength,
- bfshiftfactor, bfdecimals);
- if(stopmsg(0,msg)==-1)
- goodbye();
- }
-
- void showcornersbf(char *s)
- {
- int dec=decimals;
- char msg[100],msg1[100],msg3[600];
- if(dec > 20) dec = 20;
- bftostr(msg,dec,bfxmin);
- sprintf(msg1,"bfxmin=%s\nxxmin= %.20f decimals %d bflength %d\n\n",
- msg,xxmin,decimals,bflength);
- strcpy(msg3,s);
- strcat(msg3,"\n");
- strcat(msg3,msg1);
- bftostr(msg,dec,bfxmax);
- sprintf(msg1,"bfxmax=%s\nxxmax= %.20f\n\n",msg,xxmax);
- strcat(msg3,msg1);
- bftostr(msg,dec,bfymin);
- sprintf(msg1,"bfymin=%s\nyymin= %.20f\n\n",msg,yymin);
- strcat(msg3,msg1);
- bftostr(msg,dec,bfymax);
- sprintf(msg1,"bfymax=%s\nyymax= %.20f\n\n",msg,yymax);
- strcat(msg3,msg1);
- bftostr(msg,dec,bfx3rd);
- sprintf(msg1,"bfx3rd=%s\nxx3rd= %.20f\n\n",msg,xx3rd);
- strcat(msg3,msg1);
- bftostr(msg,dec,bfy3rd);
- sprintf(msg1,"bfy3rd=%s\nyy3rd= %.20f\n\n",msg,yy3rd);
- strcat(msg3,msg1);
- if(stopmsg(0,msg3)==-1)
- goodbye();
- }
-
- void showcornersbfs(char *s)
- {
- int dec=20;
- char msg[100],msg1[100],msg3[500];
- bftostr(msg,dec,bfsxmin);
- sprintf(msg1,"bfsxmin=%s\nxxmin= %.20f\n\n",msg,xxmin);
- strcpy(msg3,s);
- strcat(msg3,"\n");
- strcat(msg3,msg1);
- bftostr(msg,dec,bfsxmax);
- sprintf(msg1,"bfsxmax=%s\nxxmax= %.20f\n\n",msg,xxmax);
- strcat(msg3,msg1);
- bftostr(msg,dec,bfsymin);
- sprintf(msg1,"bfsymin=%s\nyymin= %.20f\n\n",msg,yymin);
- strcat(msg3,msg1);
- bftostr(msg,dec,bfsymax);
- sprintf(msg1,"bfsymax=%s\nyymax= %.20f\n\n",msg,yymax);
- strcat(msg3,msg1);
- bftostr(msg,dec,bfsx3rd);
- sprintf(msg1,"bfsx3rd=%s\nxx3rd= %.20f\n\n",msg,xx3rd);
- strcat(msg3,msg1);
- bftostr(msg,dec,bfsy3rd);
- sprintf(msg1,"bfsy3rd=%s\nyy3rd= %.20f\n\n",msg,yy3rd);
- strcat(msg3,msg1);
- if(stopmsg(0,msg3)==-1)
- goodbye();
- }
-
- void show_two_bf(char *s1,bf_t t1,char *s2, bf_t t2, int digits)
- {
- char msg1[200],msg2[200], msg3[400];
- bftostr_e(msg1,digits,t1);
- bftostr_e(msg2,digits,t2);
- sprintf(msg3,"\n%s->%s\n%s->%s",s1,msg1,s2,msg2);
- if(stopmsg(0,msg3)==-1)
- goodbye();
- }
-
- void show_three_bf(char *s1,bf_t t1,char *s2, bf_t t2, char *s3, bf_t t3, int digits)
- {
- char msg1[200],msg2[200], msg3[200], msg4[600];
- bftostr_e(msg1,digits,t1);
- bftostr_e(msg2,digits,t2);
- bftostr_e(msg3,digits,t3);
- sprintf(msg4,"\n%s->%s\n%s->%s\n%s->%s",s1,msg1,s2,msg2,s3,msg3);
- if(stopmsg(0,msg4)==-1)
- goodbye();
- }
-
- /* for aspect ratio debugging */
- void showaspect(char *s)
- {
- bf_t bt1,bt2,aspect;
- char msg[100],str[100];
- int saved; saved = save_stack();
- bt1 = alloc_stack(rbflength+2);
- bt2 = alloc_stack(rbflength+2);
- aspect = alloc_stack(rbflength+2);
- sub_bf(bt1,bfxmax,bfxmin);
- sub_bf(bt2,bfymax,bfymin);
- div_bf(aspect,bt2,bt1);
- bftostr(str,10,aspect);
- sprintf(msg,"aspect %s\nfloat %13.10f\nbf %s\n\n",
- s,
- (yymax-yymin)/(xxmax-xxmin),
- str);
- if(stopmsg(0,msg)==-1)
- goodbye();
- restore_stack(saved);
- }
-
- /* compare a double and bignumber */
- void comparevalues(char *s, LDBL x, bn_t bnx)
- {
- int dec=40;
- char msg[100],msg1[100];
- bntostr(msg,dec,bnx);
- sprintf(msg1,"%s\nbignum=%s\ndouble=%.20Lf\n\n",s,msg,x);
- if(stopmsg(0,msg1)==-1)
- goodbye();
- }
- /* compare a double and bignumber */
- void comparevaluesbf(char *s, LDBL x, bf_t bfx)
- {
- int dec=40;
- char msg[300],msg1[300];
- bftostr_e(msg,dec,bfx);
- sprintf(msg1,"%s\nbignum=%s\ndouble=%.20Lf\n\n",s,msg,x);
- if(stopmsg(0,msg1)==-1)
- goodbye();
- }
-
- /**********************************************************************/
- void show_var_bf(char *s, bf_t n)
- {
- char msg[200];
- strcpy(msg,s);
- strcat(msg," ");
- bftostr_e(msg+strlen(s),40,n);
- msg[79] = 0;
- if(stopmsg(0,msg)==-1)
- goodbye();
- }
-
- #endif
-
- void bfcornerstofloat(void)
- {
- int i;
- if(bf_math)
- {
- xxmin = (double)bftofloat(bfxmin);
- yymin = (double)bftofloat(bfymin);
- xxmax = (double)bftofloat(bfxmax);
- yymax = (double)bftofloat(bfymax);
- xx3rd = (double)bftofloat(bfx3rd);
- yy3rd = (double)bftofloat(bfy3rd);
- }
- for(i=0;i<MAXPARAMS;i++)
- if(typehasparm(fractype,i))
- param[i] = (double)bftofloat(bfparms[i]);
- }
-
- #if (_MSC_VER >= 700)
- #pragma code_seg ( ) /* back to normal segment */
- #endif
-
- /* -------------------------------------------------------------------- */
- /* Bignumber Bailout Routines */
- /* -------------------------------------------------------------------- */
-
- /* mandel_bntoint() can only be used for intlength of 1 */
- #define mandel_bntoint(n) (*(n + bnlength - 1)) /* assumes intlength of 1 */
-
- /* Note: */
- /* No need to set magnitude */
- /* as color schemes that need it calculate it later. */
-
- int near bnMODbailout()
- {
- long longmagnitude;
-
- square_bn(bntmpsqrx, bnnew.x);
- square_bn(bntmpsqry, bnnew.y);
- add_bn(bntmp, bntmpsqrx+shiftfactor, bntmpsqry+shiftfactor);
-
- longmagnitude = bntoint(bntmp); /* works with any fractal type */
- if (longmagnitude >= (long)rqlim)
- return 1;
- copy_bn(bnold.x, bnnew.x);
- copy_bn(bnold.y, bnnew.y);
- return 0;
- }
-
- int near bnREALbailout()
- {
- long longtempsqrx;
-
- square_bn(bntmpsqrx, bnnew.x);
- square_bn(bntmpsqry, bnnew.y);
- longtempsqrx = bntoint(bntmpsqrx+shiftfactor);
- if (longtempsqrx >= (long)rqlim)
- return 1;
- copy_bn(bnold.x, bnnew.x);
- copy_bn(bnold.y, bnnew.y);
- return 0;
- }
-
-
- int near bnIMAGbailout()
- {
- long longtempsqry;
-
- square_bn(bntmpsqrx, bnnew.x);
- square_bn(bntmpsqry, bnnew.y);
- longtempsqry = bntoint(bntmpsqry+shiftfactor);
- if (longtempsqry >= (long)rqlim)
- return 1;
- copy_bn(bnold.x, bnnew.x);
- copy_bn(bnold.y, bnnew.y);
- return(0);
- }
-
- int near bnORbailout()
- {
- long longtempsqrx, longtempsqry;
-
- square_bn(bntmpsqrx, bnnew.x);
- square_bn(bntmpsqry, bnnew.y);
- longtempsqrx = bntoint(bntmpsqrx+shiftfactor);
- longtempsqry = bntoint(bntmpsqry+shiftfactor);
- if(longtempsqrx >= (long)rqlim || longtempsqry >= (long)rqlim)
- return 1;
- copy_bn(bnold.x, bnnew.x);
- copy_bn(bnold.y, bnnew.y);
- return(0);
- }
-
- int near bnANDbailout()
- {
- long longtempsqrx, longtempsqry;
-
- square_bn(bntmpsqrx, bnnew.x);
- square_bn(bntmpsqry, bnnew.y);
- longtempsqrx = bntoint(bntmpsqrx+shiftfactor);
- longtempsqry = bntoint(bntmpsqry+shiftfactor);
- if(longtempsqrx >= (long)rqlim && longtempsqry >= (long)rqlim)
- return 1;
- copy_bn(bnold.x, bnnew.x);
- copy_bn(bnold.y, bnnew.y);
- return(0);
- }
-
- int near bfMODbailout()
- {
- long longmagnitude;
-
- square_bf(bftmpsqrx, bfnew.x);
- square_bf(bftmpsqry, bfnew.y);
- add_bf(bftmp, bftmpsqrx, bftmpsqry);
-
- longmagnitude = bftoint(bftmp);
- if (longmagnitude >= (long)rqlim)
- return 1;
- copy_bf(bfold.x, bfnew.x);
- copy_bf(bfold.y, bfnew.y);
- return 0;
- }
-
- int near bfREALbailout()
- {
- long longtempsqrx;
-
- square_bf(bftmpsqrx, bfnew.x);
- square_bf(bftmpsqry, bfnew.y);
- longtempsqrx = bftoint(bftmpsqrx);
- if (longtempsqrx >= (long)rqlim)
- return 1;
- copy_bf(bfold.x, bfnew.x);
- copy_bf(bfold.y, bfnew.y);
- return 0;
- }
-
-
- int near bfIMAGbailout()
- {
- long longtempsqry;
-
- square_bf(bftmpsqrx, bfnew.x);
- square_bf(bftmpsqry, bfnew.y);
- longtempsqry = bftoint(bftmpsqry);
- if (longtempsqry >= (long)rqlim)
- return 1;
- copy_bf(bfold.x, bfnew.x);
- copy_bf(bfold.y, bfnew.y);
- return(0);
- }
-
- int near bfORbailout()
- {
- long longtempsqrx, longtempsqry;
-
- square_bf(bftmpsqrx, bfnew.x);
- square_bf(bftmpsqry, bfnew.y);
- longtempsqrx = bftoint(bftmpsqrx);
- longtempsqry = bftoint(bftmpsqry);
- if(longtempsqrx >= (long)rqlim || longtempsqry >= (long)rqlim)
- return 1;
- copy_bf(bfold.x, bfnew.x);
- copy_bf(bfold.y, bfnew.y);
- return(0);
- }
-
- int near bfANDbailout()
- {
- long longtempsqrx, longtempsqry;
-
- square_bf(bftmpsqrx, bfnew.x);
- square_bf(bftmpsqry, bfnew.y);
- longtempsqrx = bftoint(bftmpsqrx);
- longtempsqry = bftoint(bftmpsqry);
- if(longtempsqrx >= (long)rqlim && longtempsqry >= (long)rqlim)
- return 1;
- copy_bf(bfold.x, bfnew.x);
- copy_bf(bfold.y, bfnew.y);
- return(0);
- }
-
- #if (_MSC_VER >= 700)
- #pragma code_seg ("bigsetup_text") /* place following in an overlay */
- #endif
-
- int MandelbnSetup()
- {
- /* this should be set up dynamically based on corners */
- bn_t bntemp1, bntemp2;
- int saved; saved = save_stack();
- bntemp1 = alloc_stack(bnlength);
- bntemp2 = alloc_stack(bnlength);
-
- bftobn(bnxmin,bfxmin);
- bftobn(bnxmax,bfxmax);
- bftobn(bnymin,bfymin);
- bftobn(bnymax,bfymax);
- bftobn(bnx3rd,bfx3rd);
- bftobn(bny3rd,bfy3rd);
-
- bf_math = BIGNUM;
-
- /* bnxdel = (bnxmax - bnx3rd)/(xdots-1) */
- sub_bn(bnxdel, bnxmax, bnx3rd);
- div_a_bn_int(bnxdel, (U16)(xdots - 1));
-
- /* bnydel = (bnymax - bny3rd)/(ydots-1) */
- sub_bn(bnydel, bnymax, bny3rd);
- div_a_bn_int(bnydel, (U16)(ydots - 1));
-
- /* bnxdel2 = (bnx3rd - bnxmin)/(ydots-1) */
- sub_bn(bnxdel2, bnx3rd, bnxmin);
- div_a_bn_int(bnxdel2, (U16)(ydots - 1));
-
- /* bnydel2 = (bny3rd - bnymin)/(xdots-1) */
- sub_bn(bnydel2, bny3rd, bnymin);
- div_a_bn_int(bnydel2, (U16)(xdots - 1));
-
- abs_bn(bnclosenuff,bnxdel);
- if(cmp_bn(abs_bn(bntemp1,bnxdel2),bnclosenuff) > 0)
- copy_bn(bnclosenuff,bntemp1);
- if(cmp_bn(abs_bn(bntemp1,bnydel),abs_bn(bntemp2,bnydel2)) > 0)
- {
- if(cmp_bn(bntemp1,bnclosenuff) > 0)
- copy_bn(bnclosenuff,bntemp1);
- }
- else if(cmp_bn(bntemp2,bnclosenuff) > 0)
- copy_bn(bnclosenuff,bntemp2);
- {
- int t;
- t = abs(periodicitycheck);
- while(t--)
- half_a_bn(bnclosenuff);
- }
-
- c_exp = (int)param[2];
- switch (fractype)
- {
- case JULIAFP:
- bftobn(bnparm.x, bfparms[0]);
- bftobn(bnparm.y, bfparms[1]);
- break;
- case FPMANDELZPOWER:
- init_big_pi();
- if((double)c_exp == param[2] && (c_exp & 1)) /* odd exponents */
- symmetry = XYAXIS_NOPARM;
- if(param[3] != 0)
- symmetry = NOSYM;
- break;
- case FPJULIAZPOWER:
- init_big_pi();
- bftobn(bnparm.x, bfparms[0]);
- bftobn(bnparm.y, bfparms[1]);
- if((c_exp & 1) || param[3] != 0.0 || (double)c_exp != param[2] )
- symmetry = NOSYM;
- break;
- }
-
- /* at the present time, parameters are kept in float, but want to keep
- the arbitrary precision logic intact. The next two lines, if used,
- would disguise and breaking of the arbitrary precision logic */
- /*
- floattobn(bnparm.x,param[0]);
- floattobn(bnparm.y,param[1]);
- */
- restore_stack(saved);
- return (1);
- }
-
- int MandelbfSetup()
- {
- /* this should be set up dynamically based on corners */
- bf_t bftemp1, bftemp2;
- int saved; saved = save_stack();
- bftemp1 = alloc_stack(bflength+2);
- bftemp2 = alloc_stack(bflength+2);
-
- bf_math = BIGFLT;
-
- /* bfxdel = (bfxmax - bfx3rd)/(xdots-1) */
- sub_bf(bfxdel, bfxmax, bfx3rd);
- div_a_bf_int(bfxdel, (U16)(xdots - 1));
-
- /* bfydel = (bfymax - bfy3rd)/(ydots-1) */
- sub_bf(bfydel, bfymax, bfy3rd);
- div_a_bf_int(bfydel, (U16)(ydots - 1));
-
- /* bfxdel2 = (bfx3rd - bfxmin)/(ydots-1) */
- sub_bf(bfxdel2, bfx3rd, bfxmin);
- div_a_bf_int(bfxdel2, (U16)(ydots - 1));
-
- /* bfydel2 = (bfy3rd - bfymin)/(xdots-1) */
- sub_bf(bfydel2, bfy3rd, bfymin);
- div_a_bf_int(bfydel2, (U16)(xdots - 1));
-
- abs_bf(bfclosenuff,bfxdel);
- if(cmp_bf(abs_bf(bftemp1,bfxdel2),bfclosenuff) > 0)
- copy_bf(bfclosenuff,bftemp1);
- if(cmp_bf(abs_bf(bftemp1,bfydel),abs_bf(bftemp2,bfydel2)) > 0)
- {
- if(cmp_bf(bftemp1,bfclosenuff) > 0)
- copy_bf(bfclosenuff,bftemp1);
- }
- else if(cmp_bf(bftemp2,bfclosenuff) > 0)
- copy_bf(bfclosenuff,bftemp2);
- {
- int t;
- t = abs(periodicitycheck);
- while(t--)
- half_a_bf(bfclosenuff);
- }
-
- c_exp = (int)param[2];
- switch (fractype)
- {
- case JULIAFP:
- copy_bf(bfparm.x, bfparms[0]);
- copy_bf(bfparm.y, bfparms[1]);
- break;
- case FPMANDELZPOWER:
- init_big_pi();
- if((double)c_exp == param[2] && (c_exp & 1)) /* odd exponents */
- symmetry = XYAXIS_NOPARM;
- if(param[3] != 0)
- symmetry = NOSYM;
- break;
- case FPJULIAZPOWER:
- init_big_pi();
- copy_bf(bfparm.x, bfparms[0]);
- copy_bf(bfparm.y, bfparms[1]);
- if((c_exp & 1) || param[3] != 0.0 || (double)c_exp != param[2] )
- symmetry = NOSYM;
- break;
- }
-
- restore_stack(saved);
- return (1);
- }
-
- #if (_MSC_VER >= 700)
- #pragma code_seg ( ) /* back to normal segment */
- #endif
-
- int mandelbn_per_pixel()
- {
- /* parm.x = xxmin + col*delx + row*delx2 */
- mult_bn_int(bnparm.x, bnxdel, (U16)col);
- mult_bn_int(bntmp, bnxdel2, (U16)row);
-
- add_a_bn(bnparm.x, bntmp);
- add_a_bn(bnparm.x, bnxmin);
-
- /* parm.y = yymax - row*dely - col*dely2; */
- /* note: in next four lines, bnold is just used as a temporary variable */
- mult_bn_int(bnold.x, bnydel, (U16)row);
- mult_bn_int(bnold.y, bnydel2, (U16)col);
- add_a_bn(bnold.x, bnold.y);
- sub_bn(bnparm.y, bnymax, bnold.x);
-
- copy_bn(bnold.x, bnparm.x);
- copy_bn(bnold.y, bnparm.y);
-
- if(inside == -60 || inside == -61)
- {
- /* kludge to match "Beauty of Fractals" picture since we start
- Mandelbrot iteration with init rather than 0 */
- floattobn(bnold.x,param[0]); /* initial pertubation of parameters set */
- floattobn(bnold.y,param[1]);
- coloriter = -1;
- }
- else
- {
- floattobn(bnnew.x,param[0]);
- floattobn(bnnew.y,param[1]);
- add_a_bn(bnold.x,bnnew.x);
- add_a_bn(bnold.y,bnnew.y);
- }
-
- /* square has side effect - must copy first */
- copy_bn(bnnew.x, bnold.x);
- copy_bn(bnnew.y, bnold.y);
-
- /* Square these to rlength bytes of precision */
- square_bn(bntmpsqrx, bnnew.x);
- square_bn(bntmpsqry, bnnew.y);
-
- return (1); /* 1st iteration has been done */
- }
-
- int mandelbf_per_pixel()
- {
- /* parm.x = xxmin + col*delx + row*delx2 */
- mult_bf_int(bfparm.x, bfxdel, (U16)col);
- mult_bf_int(bftmp, bfxdel2, (U16)row);
-
- add_a_bf(bfparm.x, bftmp);
- add_a_bf(bfparm.x, bfxmin);
-
- /* parm.y = yymax - row*dely - col*dely2; */
- /* note: in next four lines, bfold is just used as a temporary variable */
- mult_bf_int(bfold.x, bfydel, (U16)row);
- mult_bf_int(bfold.y, bfydel2, (U16)col);
- add_a_bf(bfold.x, bfold.y);
- sub_bf(bfparm.y, bfymax, bfold.x);
-
- copy_bf(bfold.x, bfparm.x);
- copy_bf(bfold.y, bfparm.y);
-
- if(inside == -60 || inside == -61)
- {
- /* kludge to match "Beauty of Fractals" picture since we start
- Mandelbrot iteration with init rather than 0 */
- floattobf(bfold.x,param[0]); /* initial pertubation of parameters set */
- floattobf(bfold.y,param[1]);
- coloriter = -1;
- }
- else
- {
- floattobf(bfnew.x,param[0]);
- floattobf(bfnew.y,param[1]);
- add_a_bf(bfold.x,bfnew.x);
- add_a_bf(bfold.y,bfnew.y);
- }
-
- /* square has side effect - must copy first */
- copy_bf(bfnew.x, bfold.x);
- copy_bf(bfnew.y, bfold.y);
-
- /* Square these to rbflength bytes of precision */
- square_bf(bftmpsqrx, bfnew.x);
- square_bf(bftmpsqry, bfnew.y);
-
- return (1); /* 1st iteration has been done */
- }
-
- juliabn_per_pixel()
- {
- /* old.x = xxmin + col*delx + row*delx2 */
- mult_bn_int(bnold.x, bnxdel, (U16)col);
- mult_bn_int(bntmp, bnxdel2, (U16)row);
-
- add_a_bn(bnold.x, bntmp);
- add_a_bn(bnold.x, bnxmin);
-
- /* old.y = yymax - row*dely - col*dely2; */
- /* note: in next four lines, bnnew is just used as a temporary variable */
- mult_bn_int(bnnew.x, bnydel, (U16)row);
- mult_bn_int(bnnew.y, bnydel2, (U16)col);
- add_a_bn(bnnew.x, bnnew.y);
- sub_bn(bnold.y, bnymax, bnnew.x);
-
- /* square has side effect - must copy first */
- copy_bn(bnnew.x, bnold.x);
- copy_bn(bnnew.y, bnold.y);
-
- /* Square these to rlength bytes of precision */
- square_bn(bntmpsqrx, bnnew.x);
- square_bn(bntmpsqry, bnnew.y);
-
- return (1); /* 1st iteration has been done */
- }
-
- juliabf_per_pixel()
- {
- /* old.x = xxmin + col*delx + row*delx2 */
- mult_bf_int(bfold.x, bfxdel, (U16)col);
- mult_bf_int(bftmp, bfxdel2, (U16)row);
-
- add_a_bf(bfold.x, bftmp);
- add_a_bf(bfold.x, bfxmin);
-
- /* old.y = yymax - row*dely - col*dely2; */
- /* note: in next four lines, bfnew is just used as a temporary variable */
- mult_bf_int(bfnew.x, bfydel, (U16)row);
- mult_bf_int(bfnew.y, bfydel2, (U16)col);
- add_a_bf(bfnew.x, bfnew.y);
- sub_bf(bfold.y, bfymax, bfnew.x);
-
- /* square has side effect - must copy first */
- copy_bf(bfnew.x, bfold.x);
- copy_bf(bfnew.y, bfold.y);
-
- /* Square these to rbflength bytes of precision */
- square_bf(bftmpsqrx, bfnew.x);
- square_bf(bftmpsqry, bfnew.y);
-
- return (1); /* 1st iteration has been done */
- }
-
-
- JuliabnFractal()
- {
- /* Don't forget, with bn_t numbers, after multiplying or squaring */
- /* you must shift over by shiftfactor to get the bn number. */
-
- /* bntmpsqrx and bntmpsqry were previously squared before getting to */
- /* this function, so they must be shifted. */
-
- /* new.x = tmpsqrx - tmpsqry + parm.x; */
- sub_a_bn(bntmpsqrx+shiftfactor, bntmpsqry+shiftfactor);
- add_bn(bnnew.x, bntmpsqrx+shiftfactor, bnparm.x);
-
- /* new.y = 2 * bnold.x * bnold.y + parm.y; */
- mult_bn(bntmp, bnold.x, bnold.y); /* ok to use unsafe here */
- double_a_bn(bntmp+shiftfactor);
- add_bn(bnnew.y, bntmp+shiftfactor, bnparm.y);
-
- return bignumbailout();
- }
-
- JuliabfFractal()
- {
- /* new.x = tmpsqrx - tmpsqry + parm.x; */
- sub_a_bf(bftmpsqrx, bftmpsqry);
- add_bf(bfnew.x, bftmpsqrx, bfparm.x);
-
- /* new.y = 2 * bfold.x * bfold.y + parm.y; */
- mult_bf(bftmp, bfold.x, bfold.y); /* ok to use unsafe here */
- double_a_bf(bftmp);
- add_bf(bfnew.y, bftmp, bfparm.y);
- return bigfltbailout();
- }
-
- JuliaZpowerbnFractal()
- {
- _BNCMPLX parm2;
- int saved; saved = save_stack();
-
- parm2.x = alloc_stack(bnlength);
- parm2.y = alloc_stack(bnlength);
-
- floattobn(parm2.x,param[2]);
- floattobn(parm2.y,param[3]);
- ComplexPower_bn(&bnnew,&bnold,&parm2);
- add_bn(bnnew.x,bnparm.x,bnnew.x+shiftfactor);
- add_bn(bnnew.y,bnparm.y,bnnew.y+shiftfactor);
- restore_stack(saved);
- return bignumbailout();
- }
-
- JuliaZpowerbfFractal()
- {
- _BFCMPLX parm2;
- int saved; saved = save_stack();
-
- parm2.x = alloc_stack(bflength+2);
- parm2.y = alloc_stack(bflength+2);
-
- floattobf(parm2.x,param[2]);
- floattobf(parm2.y,param[3]);
- ComplexPower_bf(&bfnew,&bfold,&parm2);
- add_bf(bfnew.x,bfparm.x,bfnew.x);
- add_bf(bfnew.y,bfparm.y,bfnew.y);
- restore_stack(saved);
- return bigfltbailout();
- }
-
-
- #if 0
- /*
- the following is an example of how you can take advantage of the bn_t
- format to squeeze a little more precision out of the calculations.
- */
- JuliabnFractal()
- {
- int oldbnlength;
- bn_t mod;
- /* using partial precision multiplications */
-
- /* bnnew.x = bntmpsqrx - bntmpsqry + bnparm.x; */
- /*
- * Since tmpsqrx and tmpsqry where just calculated to rlength bytes of
- * precision, we might as well keep that extra precision in this next
- * subtraction. Therefore, use rlength as the length.
- */
-
- oldbnlength = bnlength;
- bnlength = rlength; sub_a_bn(bntmpsqrx, bntmpsqry); bnlength = oldbnlength;
-
- /*
- * Now that bntmpsqry has been sutracted from bntmpsqrx, we need to treat
- * tmpsqrx as a single width bignumber, so shift to bntmpsqrx+shiftfactor.
- */
- add_bn(bnnew.x, bntmpsqrx + shiftfactor, bnparm.x);
-
- /* new.y = 2 * bnold.x * bnold.y + old.y; */
- /* Multiply bnold.x*bnold.y to rlength precision. */
- mult_bn(bntmp, bnold.x, bnold.y);
-
- /*
- * Double bnold.x*bnold.y by shifting bits, including one of those bits
- * calculated in the previous mult_bn(). Therefore, use rlength.
- */
- bnlength = rlength; double_a_bn(bntmp); bnlength = oldbnlength;
-
- /* Convert back to a single width bignumber and add bnparm.y */
- add_bn(bnnew.y, bntmp + shiftfactor, bnparm.y);
-
- copy_bn(bnold.x, bnnew.x);
- copy_bn(bnold.y, bnnew.y);
-
- /* Square these to rlength bytes of precision */
- square_bn(bntmpsqrx, bnold.x);
- square_bn(bntmpsqry, bnold.y);
-
- /* And add the full rlength precision to get those extra bytes */
- bnlength = rlength;
- add_bn(bntmp, bntmpsqrx, bntmpsqry);
- bnlength = oldbnlength;
-
- mod = bntmp + (rlength) - (intlength << 1); /* where int part starts
- * after mult */
- /*
- * equivalent to, but faster than, mod = bn_int(tmp+shiftfactor);
- */
-
- if ((magnitude = *mod) >= rqlim)
- return (1);
- return (0);
- }
- #endif
-
- _CMPLX cmplxbntofloat(_BNCMPLX *s)
- {
- _CMPLX t;
- t.x = (double)bntofloat(s->x);
- t.y = (double)bntofloat(s->y);
- return(t);
- }
-
- _CMPLX cmplxbftofloat(_BFCMPLX *s)
- {
- _CMPLX t;
- t.x = (double)bftofloat(s->x);
- t.y = (double)bftofloat(s->y);
- return(t);
- }
-
- _BFCMPLX *cmplxlog_bf(_BFCMPLX *t, _BFCMPLX *s)
- {
- square_bf(t->x,s->x);
- square_bf(t->y,s->y);
- add_a_bf(t->x,t->y);
- ln_bf(t->x,t->x);
- half_a_bf(t->x);
- atan2_bf(t->y,s->y,s->x);
- return(t);
- }
-
- _BFCMPLX *cplxmul_bf( _BFCMPLX *t, _BFCMPLX *x, _BFCMPLX *y)
- {
- bf_t tmp1;
- int saved; saved = save_stack();
- tmp1 = alloc_stack(rbflength+2);
- mult_bf(t->x, x->x, y->x);
- mult_bf(t->y, x->y, y->y);
- sub_bf(t->x,t->x,t->y);
-
- mult_bf(tmp1, x->x, y->y);
- mult_bf(t->y, x->y, y->x);
- add_bf(t->y,tmp1,t->y);
- restore_stack(saved);
- return(t);
- }
-
- _BFCMPLX *ComplexPower_bf(_BFCMPLX *t, _BFCMPLX *xx, _BFCMPLX *yy)
- {
- _BFCMPLX tmp;
- bf_t e2x, siny, cosy;
- int saved; saved = save_stack();
- e2x = alloc_stack(rbflength+2);
- siny = alloc_stack(rbflength+2);
- cosy = alloc_stack(rbflength+2);
- tmp.x = alloc_stack(rbflength+2);
- tmp.y = alloc_stack(rbflength+2);
-
- /* 0 raised to anything is 0 */
- if (is_bf_zero(xx->x) && is_bf_zero(xx->y))
- {
- clear_bf(t->x);
- clear_bf(t->y);
- return(t);
- }
-
- cmplxlog_bf(t, xx);
- cplxmul_bf(&tmp, t, yy);
- exp_bf(e2x,tmp.x);
- sincos_bf(siny,cosy,tmp.y);
- mult_bf(t->x, e2x, cosy);
- mult_bf(t->y, e2x, siny);
- restore_stack(saved);
- return(t);
- }
-
- _BNCMPLX *cmplxlog_bn(_BNCMPLX *t, _BNCMPLX *s)
- {
- square_bn(t->x,s->x);
- square_bn(t->y,s->y);
- add_a_bn(t->x+shiftfactor,t->y+shiftfactor);
- ln_bn(t->x,t->x+shiftfactor);
- half_a_bn(t->x);
- atan2_bn(t->y,s->y,s->x);
- return(t);
- }
-
- _BNCMPLX *cplxmul_bn( _BNCMPLX *t, _BNCMPLX *x, _BNCMPLX *y)
- {
- bn_t tmp1;
- int saved; saved = save_stack();
- tmp1 = alloc_stack(rlength);
- mult_bn(t->x, x->x, y->x);
- mult_bn(t->y, x->y, y->y);
- sub_bn(t->x,t->x+shiftfactor,t->y+shiftfactor);
-
- mult_bn(tmp1, x->x, y->y);
- mult_bn(t->y, x->y, y->x);
- add_bn(t->y,tmp1+shiftfactor,t->y+shiftfactor);
- restore_stack(saved);
- return(t);
- }
-
- /* note: ComplexPower_bn() returns need to be +shiftfactor'ed */
- _BNCMPLX *ComplexPower_bn(_BNCMPLX *t, _BNCMPLX *xx, _BNCMPLX *yy)
- {
- _BNCMPLX tmp;
- bn_t e2x, siny, cosy;
- int saved; saved = save_stack();
- e2x = alloc_stack(bnlength);
- siny = alloc_stack(bnlength);
- cosy = alloc_stack(bnlength);
- tmp.x = alloc_stack(rlength);
- tmp.y = alloc_stack(rlength);
-
- /* 0 raised to anything is 0 */
- if (is_bn_zero(xx->x) && is_bn_zero(xx->y))
- {
- clear_bn(t->x);
- clear_bn(t->y);
- return(t);
- }
-
- cmplxlog_bn(t, xx);
- cplxmul_bn(&tmp, t, yy);
- exp_bn(e2x,tmp.x);
- sincos_bn(siny,cosy,tmp.y);
- mult_bn(t->x, e2x, cosy);
- mult_bn(t->y, e2x, siny);
- restore_stack(saved);
- return(t);
- }
-