Just purely out of interest (and I'm sure the technique applied would come in handy in the开发者_开发百科 future)
How would one code the infinite series 1 + 1/2 +1/4 + 1/8... ad infinitum as an actual sum in c#? (I'm sure the word recursive or recursively could be used there somewhere)
Using lazy evaluation you can actually define(but not evaluate) an infinite sequence:
IEnumerable<double> Series()
{
double sum=0;
double element=1;
while(true)
{
sum+=element;
yield return sum;
element/=2;
}
}
Of course this is limited by rounding errors and thus will stop growing after about 53 iterations.
You could define it recursively, but I see no reason to do that:
double Series(int n)
{
if(n==0)
return 1;
else
return Math.Power(0.5,n)+Series(n-1);
}
var val = 0.0;
var sum = 1.0;
while(true)
{
val += sum;
sum /= 2;
}
You could use decimal datatype as it supports more decimal places than double. This can be done recursively or with a loop; I would recommend with a loop like so:
// endValue is an input integer
decimal acc = 0.0m;
int factor = 1;
for (; factor < endValue; factor *= 2)
{
try
{
acc += (1.0m/(decimal)factor);
}
catch
{
// we've exceeded bounds of the datatype; return last result
}
}
return acc;
Building on the idea presented by CodeInChaos you could create
static IEnumerable<T> Series<T>(Func<T,T> function,
T seed,
int interations = int.MaxValue)
{
T value = seed;
for (int i = 0; i < iterations; i++)
{
value = function(value);
yield return value;
}
}
and
static IEnumerable<T> Series<T>(Func<T, int, T> function,
T seed,
int interations = int.MaxValue)
{
T value = seed;
for (int i = 0; i < iterations; i++)
{
value = function(value, i);
yield return value;
}
}
allowing you to iteration over any series you like, such as:
double total = 0;
double newTotal = 0;
foreach (double v in Series(v => v * .5, 1.0, 100))
{
newTotal += v;
Console.WriteLine(total);
if (total == newTotal) break;
total = newTotal;
}
精彩评论