示例#1
0
        public override bool RenderMultiThreaded(Float128 xmin, Float128 xmax, Float128 ymin, Float128 ymax, Float128 step, int maxIterations)
        {
            Float128 HALF = new Float128(0.5);

            //Parallel.For(0, (int)(((ymax - ymin) / step) + .5M), (yp) =>
            Parallel.For(0, ymax.SubFast(ymin).Div(step).AddFast(HALF).IntValue(), (yp) =>
            {
                if (Abort)
                {
                    return;
                }
                Float128 y = ymin.AddFast(step.Mul(yp));
                int xp     = 0;
                for (Float128 x = xmin; x.SubFast(xmax).Hi < 0; x = x.AddFast(step), xp++)
                {
                    Float128 accumx = x;
                    Float128 accumy = y;
                    int iters       = 0;
                    Float128 sqabs  = new Float128(0);
                    do
                    {
                        Float128 naccumx = accumx.Sqr().SubFast(accumy.Sqr());
                        Float128 naccumy = accumx.Mul(accumy).MulPwrOf2(2);
                        accumx           = naccumx.AddFast(x);
                        accumy           = naccumy.AddFast(y);
                        iters++;
                        sqabs = accumx.Sqr().AddFast(accumy.Sqr());
                    } while (sqabs.SubFast(limit).Hi < 0 && iters < maxIterations);

                    DrawPixel(xp, yp, iters);
                }
            });
            return(!Abort);
        }
示例#2
0
        public override bool RenderSingleThreaded(Float128 xmin, Float128 xmax, Float128 ymin, Float128 ymax, Float128 step, int maxIterations)
        {
            int yp = 0;

            for (Float128 y = ymin; y.SubFast(ymax).Hi < 0 && !Abort; y = y.AddFast(step), yp++)
            {
                if (Abort)
                {
                    return(false);
                }
                int xp = 0;
                for (Float128 x = xmin; x.SubFast(xmax).Hi < 0; x = x.AddFast(step), xp++)
                {
                    Float128 accumx = x;
                    Float128 accumy = y;
                    int      iters  = 0;
                    Float128 sqabs  = new Float128(0);
                    do
                    {
                        Float128 naccumx = accumx.Sqr().SubFast(accumy.Sqr());
                        Float128 naccumy = accumx.Mul(accumx).MulPwrOf2(2);
                        accumx = naccumx.AddFast(x);
                        accumy = naccumy.AddFast(y);
                        iters++;
                        sqabs = accumx.Sqr().AddFast(accumy.Sqr());
                    } while (sqabs.SubFast(limit).Hi < 0 && iters < maxIterations);

                    DrawPixel(xp, yp, iters);
                }
            }
            return(true);
        }
示例#3
0
        private static int to_digits(this Float128 dd, char[] s, int precision, int intBase)
        {
            int halfBase = (intBase + 1) >> 1;

            if (dd.Hi == 0.0)
            {
                // Assume dd.lo == 0.
                for (int i = 0; i < s.Length; ++i)
                {
                    s[i] = '0';
                }
                return(0);
            }

            // First determine the (approximate) exponent.
            Float128 temp = dd.Abs();
            int      exp  = (int)Math.Floor(Math.Log(temp.Hi) / Math.Log(intBase));

            Float128 p = new Float128(intBase);

            if (exp < -300)
            {
                temp.MulSelf(p.Pow(150));
                p.PowSelf(-exp - 150);
                temp.MulSelf(p);
            }
            else
            {
                p.PowSelf(-exp);
                temp.MulSelf(p);
            }

            // Fix roundoff errors. (eg. floor(log10(1e9))=floor(8.9999~)=8)
            if (temp.Hi >= intBase)
            {
                exp++;
                temp.Hi /= intBase;
                temp.Lo /= intBase;
            }
            else if (temp.Hi < 1)
            {
                exp--;
                temp.Hi *= intBase;
                temp.Lo *= intBase;
            }

            if (temp.Hi >= intBase || temp.Hi < 1)
            {
                throw new Exception("Can't compute exponent.");
            }

            // Handle one digit more. Used afterwards for rounding.
            int numDigits = precision + 1;

            // Extract the digits.
            for (int i = 0; i < numDigits; i++)
            {
                int val = (int)temp.Hi;
                temp = temp.Sub(val);
                temp = temp.Mul(intBase);

                s[i] = (char)val;
            }

            if (s[0] <= 0)
            {
                throw new Exception("Negative leading digit.");
            }

            // Fix negative digits due to roundoff error in exponent.
            for (int i = numDigits - 1; i > 0; i--)
            {
                if (s[i] >= 32768)
                {
                    s[i - 1]--;
                    s[i] += (char)intBase;
                }
            }

            // Round, handle carry.
            if (s[precision] >= halfBase)
            {
                s[precision - 1]++;

                int i = precision - 1;
                while (i > 0 && s[i] >= intBase)
                {
                    s[i] -= (char)intBase;
                    s[--i]++;
                }
            }
            s[precision] = (char)0;

            // If first digit became too high, shift right.
            if (s[0] >= intBase)
            {
                exp++;
                for (int i = precision; i >= 1;)
                {
                    s[i] = s[--i];
                }
            }

            // Convert to ASCII.
            for (int i = 0; i < precision; i++)
            {
                s[i] = Float128.BASE_36_TABLE[s[i]];
            }

            // If first digit became zero, and exp > 0, shift left.
            if (s[0] == '0' && exp < 32768)
            {
                exp--;
                for (int i = 0; i < precision;)
                {
                    s[i] = s[++i];
                }
            }

            return(exp);
        }