你提到,你必須測試近可分與。下面的理論研究應針對的兩個大國近可分測試成立:
#define THRESHOLD 0.11
int nearly_divisible(float f) {
// printf(" %f\n", (a - (float)((long) a)));
register long l1, l2;
l1 = (long) (f + THRESHOLD);
l2 = (long) f;
return !(l1 & 31) && (l2 & 31 ? 1 : f - (float) l2 <= THRESHOLD);
}
我們正在做的是強迫浮動,和float +閾值長。
f (long) f (long) (f + THRESHOLD)
63.9 63 64
64 64 64
64.1 64 64
現在我們測試,如果(長)f是整除與32只要勾選低五位,如果它們都設置爲零,數量是32整除這導致了一系列的誤報:64.2到64.8,當轉換成long時,也是64,並且會通過第一次測試。因此,我們檢查它們的截斷形式和f之間的差異是否小於或等於THRESHOLD。
這也有一個問題:f - (float)l < = THRESHOLD對於64和64.1將適用,但不適用於63.9。因此,我們爲小於64的數字添加了一個例外(當THRESHOLD增加並隨後被強制延長時 - 請注意,正在討論的測試必須包含第一個測試 - 可以被32整除),方法是指定低5位不爲零。這將適用於63(1000000 - 1 == 1 )。
這三個測試的組合將指示數字是否可以被32整除。我希望這很清楚,請原諒我奇怪的英語。
我只是測試可擴展到三個其他大國 - 383.5和388.4之間的下列程序打印數字是整除128
#include <stdio.h>
#define THRESHOLD 0.11
int main(void) {
int nearly_divisible(float);
int i;
float f = 383.5;
for (i=0; i<50; i++) {
printf("%6.1f %s\n", f, (nearly_divisible(f) ? "true" : "false"));
f += 0.1;
}
return 0;
}
int nearly_divisible(float f) {
// printf(" %f\n", (a - (float)((long) a)));
register long l1, l2;
l1 = (long) (f + THRESHOLD);
l2 = (long) f;
return !(l1 & 127) && (l2 & 127 ? 1 : f - (float) l2 <= THRESHOLD);
}
似乎好工作至今!
+1這是一個非常合理的解決方案,如果你沒有剩餘的功能可用。 – 2010-03-22 05:27:49
或:else if(32.0f - offset
quinmars
2010-03-22 10:24:06