什么是一个好的算法来确定添加/减去数字所需的必要分数,以便在不使用内置天花板或地板功能的情况下将其四舍五入到最接近的整数?
编辑:寻找一个数学数字技巧来找出将数字四舍五入到最接近的整数所需的部分。数学运算越原始越好。请避免使用其他程序。无论哪种方式都可以采用 0.5,无论哪种方式适合您的方法。这不是我的作业问题,我也不打算在任何地方使用它。
将数字修改为 1 得到小数部分,如果大于 0.5,则向上取整,否则向下取整
或者
将数字除以 0.5,如果是奇数,则向上取整,否则向下取整
一旦你有了数字的小数部分,问题就基本解决了。获得小数部分的一种方法是从你的数字中反复减去 2 的幂(假设它已经被设为正,如果它一开始是负的)。
下面的函数,getWholeMaker
,返回你想要的(必须添加到四舍五入的“东西”)。它的运行时间是O(log(n))
,并且仅使用基本操作。
/* Returns the factional part of x */
double getFrac(double x) {
if(x < 0) x = -x;
if(x < 1) return x;
else if(x < 2) return x-1;
/* x >= 0 */
double t = 2;
while(t+t <= x) t += t;
/* t is now the largest power of 2 less than or equal to x */
while(t >= 1) {
if(t <= x) x -= t;
t /= 2;
}
return x;
}
double getWholeMaker(double x) {
double frac = getFrac(x);
double sign = x >= 0 ? +1 : -1;
return sign * (frac <= 0.5 ? -frac : 1-frac);
}
如果你不能使用 mod (因为它可能只为你的语言中的整数定义,你可以做这样的事情(在 C-ish 伪代码中):
// make the input positive:
boolean inputPositive = true;
if (input < 0) {
input = 0 - input;
inputPositive = false;
}
// subtract 1 until you just have the decimal portion:
int integerPart = 0;
while (input > 1) {
input = input - 1;
integerPart++;
}
int ret;
if (input >= 0.5) { // round up
ret = integerPart + 1;
} else {
ret = integerPart;
}
if (inputPositive) {
return ret;
} else {
return 0 - ret;
}
此解决方案不使用 mod 或任何外部功能。当然,我无法想象你为什么会在现实生活中想要这个。不过,想想也很有趣。