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); }
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); }
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); }