C# の例(10)
Numbers クラスを変更しないようにします。
internal class Numbers { private readonly LongDecimal number; private readonly LongDecimal square_difference; private readonly int scale; public Numbers(LongDecimal number, LongDecimal square_difference, int scale) { this.number = number; this.square_difference = square_difference; this.scale = scale; } public Tuple<int, Numbers> GetNextDecimalDigitAndNumbers() { LongDecimal two = new LongDecimal(2); for (int dd = 9; dd >= 0; dd--) { LongDecimal zd = new LongDecimal(dd).Shift(scale); LongDecimal number_sq_diff = number * zd * two + zd * zd; if (number_sq_diff <= square_difference) { return new Tuple<int, Numbers>(dd, new Numbers(number + zd, square_difference - number_sq_diff, scale + 1)); } } return null; } }
NumbersGenerator クラスの GenerateDecimal メソッドは以下のようにします。
public IEnumerable<int> GenerateDecimal() { LongDecimal number = new LongDecimal(); LongDecimal square_difference = new LongDecimal(3); Numbers nums = new Numbers(number, square_difference, 0); for(; ;) { Tuple<int, Numbers> d_ns = nums.GetNextDecimalDigitAndNumbers(); nums = d_ns.Item2; yield return d_ns.Item1; } }
Calc クラスの RepeatServer メソッドと NextDigitAndNumbers は以下のようにします。
public string RepeatServer() { for (int e = 0; e < count; e++) { Numbers numbers = generator_server.Numbers; Tuple<int, Numbers> d_ns = numbers.GetNextDecimalDigitAndNumbers(); int dd = d_ns.Item1; generator_server.Numbers = d_ns.Item2; result_number = result_number + new LongDecimal(dd).Shift(e); } return result_number.Print(); }
private Tuple<int, Numbers> NextDigitAndNumbers(Numbers numbers) { return numbers.GetNextDecimalDigitAndNumbers(); }
NumbersServer クラスの Numbers プロパティの get は以下のように generator_server.MoveNext() を実行するようにします。以前これは必要ないと書きましたが、間違っていました。これがないと MoveNext が最初の1回しか実行されないことになってしまいます。
public Numbers Numbers { get { generator_server.MoveNext(); return generator_server.Current; } set { current_numbers = value; }