纯粹出于兴趣(我确信应用的技术将来会派上用场)
如何将无限系列1 + 1/2 +1 + 4 + 1/8 ...无限制地编码为c#中的实际总和? (我确定递归或递归这个词可以在某处使用)
答案 0 :(得分:2)
使用延迟评估,您实际上可以定义(但不评估)无限序列:
IEnumerable<double> Series()
{
double sum=0;
double element=1;
while(true)
{
sum+=element;
yield return sum;
element/=2;
}
}
当然,这受到舍入错误的限制,因此在大约53次迭代后将停止增长。
你可以递归地定义它,但我认为没有理由这样做:
double Series(int n)
{
if(n==0)
return 1;
else
return Math.Power(0.5,n)+Series(n-1);
}
答案 1 :(得分:0)
基于CodeInChaos提出的想法,您可以创建
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;
}
}
和
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;
}
}
允许您迭代任何您喜欢的系列,例如:
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;
}
答案 2 :(得分:0)
var val = 0.0;
var sum = 1.0;
while(true)
{
val += sum;
sum /= 2;
}
答案 3 :(得分:0)
您可以使用decimal数据类型,因为它支持比double更多的小数位数。这可以递归地或循环地完成;我建议使用这样的循环:
// 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;