我需要执行一个循环
while (X) do Y
为N次,这是一个很大的数字。虽然循环体Y是相当快的,但测试X约占运行时间的70%。
我可以预先计算循环迭代次数N,因此不使用X作为条件,可以使用简单的For循环。
for (i=1 to N) do Y
但是,N可能会超过整数可以存储在计算机上的最大值,因此这不是一个选项。作为替代方案,我建议使用浮点变量F代替。由于N很大,很可能F不能完全等于N.因此,我将F计算为小于N的最大浮点数。这允许我运行
for (i=1 to F) do Y
while (X) do Y
大多数迭代不需要每次都测试X,只需要测试最后一个N-F。
问题是:我如何实现从1到F的for-Loop?简单地增加计数器或在每个步骤中将F减小1都是行不通的,因为数值误差会变得太大。我目前的解决方案是:
for (while F > MAXINT)
for (i=1 to MAXINT)
do Y
F -= MAXINT
while (X) do Y
有没有更好的方法来解决这个问题?
答案 0 :(得分:0)
数字错误是什么意思?浮点计数精确度在其精度范围内。 以下是使用以下数据类型的整数表示的最大值:
uint32max = 4294967295
uint64max = 18446744073709551615
float32intmax = 16777216
float64intmax = 9007199254740992
从0到最大值的每个整数都可以精确表示,没有数字错误。
如您所见,uint64可以使用最大的计数。接下来是float64,然后是uint32,最后是float32。
增加uint32 = 4294967295时会发生什么? 0
增加float32 = 16777216时会发生什么? 16777216
哪种行为更好?
您是否考虑过使用二维循环?如果N是1维循环的最大计数,那么N x N是2维循环的最大值,等等。如果最大计数小于MAXUINT x MAXUINT,则将N分解为:
N == M * MAXUINT + R;
,其中
M = N / MAXUINT;
R = N - M * MAXUINT;
然后
for (i = M; i--;) for (j = MAXUINT; j--;) DoStuff();
for (i = R; i--;) DoStuff();
如果MAXUINT * MAXUINT的数量不够大,可以添加3次,4次,......次循环。