如何优雅地解决这个舍入问题

How to elegantly solve this rounding issue?

本文关键字:舍入 问题 解决 何优雅      更新时间:2023-10-16

我有一个函数,它有20次尝试"猜测"1-100:范围内的数字

int guess(int number) {
    int start = 1;
    int end = 100;
    int count = 20;
    int answer = 0;
    while (count--) {
        int half = start + round((double)(end - start) / 2);
        if (number < half) end = half;
        else if (number > half) start = half;
        else {
            answer = half;
            break;
        }
    }
    if (answer > 0) return 20 - count;
    else return 0;    
}

问题是,由于它现在正在对范围减半的结果进行四舍五入,它无法猜测数字1,如果我不进行四舍四入,它也无法猜测范围的另一个极端——100。

问题的根源很明显,就像粗糙的破解解决方案一样,但我似乎没有找到一种优雅的方法来解决它。

你知道,这很容易纠正:

检查后不要将中点保持在可能的范围内,这是不可能的!

你为什么有这些麻烦?因为你使用的是封闭范围,而不是半开放范围,这是明智的。

顺便说一句,使用整数算术,如下所示:

    int half = (start + end) / 2;

(整数除法向0取整)

根据值所在的一侧使用某种天花板和地板。

因此,如果你在顶部寻找一个值,那么使用floor(5.9->5),如果你寻找的值低于一半,那么使用limit(90.2=91)。

这应该使您的流程包括1和100

这是有效的,但在某些情况下可能需要再循环一次。将end初始化为101消除了整数除法四舍五入的问题(start也可以设置为0,但不需要)。在执行循环之前,代码也可以只检查1或100,但我不确定这是否会算作另外两个循环。

int j;
int start;
int end;
int half;
    for(j = 1; j < 101; j++){
        start = 1;
        end = 101;
        while(1){
            half = (start + end)/2;
            if(half == j)
                break;
            if(half < j)
                start = half;
            else
                end = half;
        }
        printf("%3dn", half);
    }