Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/446.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 浮点数的二进制搜索/二分法_Algorithm_Floating Point_Binary Search_Numerics - Fatal编程技术网

Algorithm 浮点数的二进制搜索/二分法

Algorithm 浮点数的二进制搜索/二分法,algorithm,floating-point,binary-search,numerics,Algorithm,Floating Point,Binary Search,Numerics,使用二进制搜索很容易找到整数:首先猜测数量级,然后继续划分区间。 描述如何查找任意有理数 设置好场景后,我的问题类似:我们如何猜测IEEE 754浮点数?假设不是NaN,但其他一切都是公平的。对于每一次猜测,您的程序都会被告知所讨论的数字是更高、相等还是更低。尽量减少最坏情况下所需的猜测次数 (这不是一个家庭作业。不过,如果这个问题有一个有趣的答案,我可能会做一个。这个答案不仅仅是“用大量的特殊情况处理将浮点数字困难打得死去活来。”) 编辑:如果我在搜索方面做得更好的话,我本来可以找到的---但

使用二进制搜索很容易找到整数:首先猜测数量级,然后继续划分区间。 描述如何查找任意有理数

设置好场景后,我的问题类似:我们如何猜测IEEE 754浮点数?假设不是NaN,但其他一切都是公平的。对于每一次猜测,您的程序都会被告知所讨论的数字是更高、相等还是更低。尽量减少最坏情况下所需的猜测次数

(这不是一个家庭作业。不过,如果这个问题有一个有趣的答案,我可能会做一个。这个答案不仅仅是“用大量的特殊情况处理将浮点数字困难打得死去活来。”)


编辑:如果我在搜索方面做得更好的话,我本来可以找到的---但只有在你已经知道重新解释为
int
有效的情况下,这才有效(需要注意)。所以就不谈这个了。感谢哈罗德给了我一个很好的回答

同样的方法也适用于浮点数。更糟糕的情况是运行时间为O(logn)


同样的方法也适用于浮点数。更糟糕的情况是运行时间为O(logn)


IEEE-754 64位浮点数实际上是64位表示。此外,除了NaN值之外,浮点比较和正值整数比较之间没有区别。(也就是说,符号位未设置的两个位模式将产生相同的比较结果,无论您是将它们作为
int64\t
还是
double
进行比较,除非其中一个位模式是浮点NaN-)

这意味着您可以通过一次猜测一位,在64次猜测中找到一个数字,即使该数字为±∞. 首先将数字与0进行比较;如果目标是“更少”,则按照如下相同的方式进行猜测,但在猜测之前先否定它们。(由于IEEE-754浮点数是符号/量级,您可以通过将符号位设置为1来对数字求反。或者您可以重新解释正位模式,然后用浮点对结果求反。)

然后,从最高阶值位开始,一次猜一位。如果数字大于或等于猜测值,则将该位设置为1;如果数字较小,则将该位设置为0;然后继续下一位,直到没有了。要构造猜测,请将位模式重新解释为
double

有两个警告:

  • 通过比较测试,您无法区分±0。这意味着,如果你的对手想让你区分他们,他们就必须给你提供一种方式来询问他们是否平等−0,在确定数字为0(这将发生在第64次猜测)之后,您必须使用该机制。这将增加一个猜测,总共65个

  • 如果您确信目标不是NaN,那么就没有其他问题。如果可能是NaN,您需要注意如何进行比较:如果您总是问“X是否小于此猜测值?”,事情会很顺利,因为NaN比较总是返回false。这意味着在连续11次回答“否”后(不计算确定符号的答案),你会发现自己在猜测∞, 假设该数字不小于∞, 它必须是相等的。但是,仅在本例中,您还需要显式地测试相等性,因为如果目标是NaN,则这也是错误的。这不会给计数增加额外的猜测,因为它总是在64次猜测用完之前很久发生


  • IEEE-754 64位浮点数实际上是64位表示。此外,除了NaN值之外,浮点比较和正值整数比较之间没有区别。(也就是说,符号位未设置的两个位模式将产生相同的比较结果,无论您是将它们作为
    int64\t
    还是
    double
    进行比较,除非其中一个位模式是浮点NaN-)

    这意味着您可以通过一次猜测一位,在64次猜测中找到一个数字,即使该数字为±∞. 首先将数字与0进行比较;如果目标是“更少”,则按照如下相同的方式进行猜测,但在猜测之前先否定它们。(由于IEEE-754浮点数是符号/量级,您可以通过将符号位设置为1来对数字求反。或者您可以重新解释正位模式,然后用浮点对结果求反。)

    然后,从最高阶值位开始,一次猜一位。如果数字大于或等于猜测值,则将该位设置为1;如果数字较小,则将该位设置为0;然后继续下一位,直到没有了。要构造猜测,请将位模式重新解释为
    double

    有两个警告:

  • 通过比较测试,您无法区分±0。这意味着,如果你的对手想让你区分他们,他们就必须给你提供一种方式来询问他们是否平等−0,在确定数字为0(这将发生在第64次猜测)之后,您必须使用该机制。这将增加一个猜测,总共65个

  • 如果您确信目标不是NaN,那么就没有其他问题。如果可能是NaN,您需要注意如何进行比较:如果您总是问“X是否小于此猜测值?”,事情会很顺利,因为NaN比较总是返回false。这意味着在连续11次回答“否”后(不计算确定符号的答案),你会发现自己在猜测∞, 假设该数字不小于∞, 它必须是相等的。但是,仅在本例中,您还需要显式地测试相等性,因为如果目标是NaN,则这也是错误的。这并不重要
    public class GuessComparer
    {
        private float random;
        public GuessComparer() // generate a random float and keep it private
        {
            Random rnd = new Random();
            var buffer = new byte[4];
            rnd.NextBytes(buffer);
            random = BitConverter.ToSingle(buffer, 0);
        }
        public int CheckGuess(float quess) // answer whether number is high, lower or the same.
        {
            return random.CompareTo(quess);
        }
    }
    public class FloatFinder
    {
    
        public static int Find(GuessComparer checker)
        {
            float guess = 0;
            int result = checker.CheckGuess(guess);
            int guesscount = 1;
            var high = float.MaxValue;
            var low = float.MinValue;
            while (result != 0)
            {
                if (result > 0) //random is higher than guess
                    low = guess;
                else// random is lower than guess
    
                    high = guess;
    
                guess = (high + low) / 2;
                guesscount++;
                result = checker.CheckGuess(guess);
            }
            Console.WriteLine("Found answer in {0}", guesscount);
            return guesscount;
        }
    
        public static void Find()
        {
            var checker = new GuessComparer();
            int guesses = Find(checker);
        }
    }