Math 数字问题的小数部分

Math 数字问题的小数部分,math,rounding,floor,ceil,Math,Rounding,Floor,Ceil,为了在不使用内置的天花板或地板函数的情况下,将数字四舍五入到最接近的整数,确定所需分数的好算法是什么 编辑:寻找一个数学数字技巧,找出将数字四舍五入到最接近整数所需的部分。数学运算越原始越好。请避免使用他人的程序。0.5可以采用其他方法,任何适合您的方法。这不是我的家庭作业问题,我也不打算在任何地方使用它。将数字改为1以获得小数部分,如果大于0.5,则向上取整,否则向下取整 或 将数字除以0.5,如果是奇数,则向上舍入,否则向下舍入如果您不能使用mod(因为在您的语言中它可能只为整数定义),您可

为了在不使用内置的天花板或地板函数的情况下,将数字四舍五入到最接近的整数,确定所需分数的好算法是什么


编辑:寻找一个数学数字技巧,找出将数字四舍五入到最接近整数所需的部分。数学运算越原始越好。请避免使用他人的程序。0.5可以采用其他方法,任何适合您的方法。这不是我的家庭作业问题,我也不打算在任何地方使用它。

将数字改为1以获得小数部分,如果大于0.5,则向上取整,否则向下取整

将数字除以0.5,如果是奇数,则向上舍入,否则向下舍入

如果您不能使用mod(因为在您的语言中它可能只为整数定义),您可能可以执行以下操作(在C-ish伪代码中):

//使输入为正:
布尔输入正=真;
如果(输入<0){
输入=0-输入;
输入阳性=假;
}
//减去1,直到得到小数部分:
整数部分=0;
while(输入>1){
输入=输入-1;
integerPart++;
}
int ret;
如果(输入>=0.5){//四舍五入
ret=整数部分+1;
}否则{
ret=整数部分;
}
如果(输入正){
返回ret;
}否则{
返回0-ret;
}

这个解决方案不使用mod或任何外部函数。当然,我无法想象你在现实生活中为什么会想要这个。不过,思考这个问题很有趣。

一旦你得到了数字的小数部分,问题就基本解决了。获得小数部分的一种方法是从你的数字中反复减去-2的幂(假设它被设置为正,如果它一开始是负的)

下面的函数,
getWholeMaker
,返回您想要的值(必须将“thing”添加到整数中)。它的运行时间是
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);
}
/*返回x的派系部分*/
双getFrac(双x){
如果(x<0)x=-x;
如果(x<1)返回x;
如果(x<2),则返回x-1;
/*x>=0*/
双t=2;
而(t+t=1){
如果(t=0?+1:-1;

返回符号*(frac您是否能够使用标准api中的其他函数?或者您是否真的想要实现自己的算法,即使这意味着重新实现控制盘?您是否可以强制转换为int?或者这算是内置的floor函数?这是否也排除了最接近的整数函数nint()?你能解释一下你为什么想要/需要这样一个算法吗?你如何处理0.5,它与0和1等距。算术舍入总是向上舍入,但银行家舍入取最近的偶数。请注意,有些语言只在整数上定义mod/%。如果x%1>=0.5打印((x-x%1)+1),这个算法很聪明-x else打印x%1 end你能想出另一个没有%的解决方案吗?为什么?没有任何其他信息不可能回答这个问题你还需要什么信息?我也在想同样的问题。必须有一个简洁的数学过程来解决这个问题。没有任何其他约束。只需找出需要的部分将数字四舍五入到最接近的整数。数学运算越原始越好。为什么乘以2不起作用?如果你想进行更原始的运算,请将数字添加到它本身。根据我的说法,这是一个很好的答案,它符合所有要求!:-)+1.你可以通过减去更小的二次方来改进这一点,这样对于大的输入,这个过程也会在合理的时间内终止。这很有趣。我喜欢你检查数字是否为正的部分。我没有想到这一点。我曾希望有人会带来数学技巧,即使减去一非常乏味,我认为这个解决方案有效。谢谢。很好。但这看起来像是pkaeding的算法优化了。我对吗?是的,它和pkaeding的一样,但在对数时间内有效(pkaeding的是线性时间)。
/* 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);
}