当前位置: 首页 > news >正文

今日分享 浮点数二分

二分查找的核心思想是"一分为二,排除一半"。对于浮点数,我们不再寻找精确的整数下标,而是要在一个连续的区间内,找到一个与目标值足够接近的数值。

 

核心奥义

 

1. 逼近而非命中:浮点数问题通常允许存在微小误差。我们的目标是让答案的精度满足题目要求。

2. 循环条件是精度:与整数二分的"left <= right"不同,浮点数二分的终止条件是区间长度小于某个极小值(如 1e-8)。当区间足够小时,区间内任意值都可作为答案。

3. 不需要 +1 或 -1:由于处理的是连续区间,不存在跳过答案的问题。直接更新  left = mid  或  right = mid  即可。

 

关键技巧

 

确定初始区间:找到一个能百分百包含答案的区间 [L, R]。例如开方问题中,区间可设为 [0, max(1, x)]。

设计判断函数:构造一个单调函数  check(mid) 。该函数能判断  mid  与目标值的大小关系,从而决定舍弃哪一半区间。

设置合理精度:精度值通常比题目要求高 2-3 个数量级。例如题目要求保留 6 位小数,精度可设为 1e-8,避免因精度不足导致答案错误。

 

 

 

实战例题:求一个数的平方根

 

问题:给定一个非负整数 x,计算并返回 x 的平方根,结果保留 6 位小数。

 

分析:

 

初始区间:当 x >= 1 时,平方根在 [1, x] 之间;当 x < 1 时,平方根在 [x, 1] 之间。统一设为 [0, max(1, x)]。

判断函数:对于 mid,计算 mid*mid。若大于 x,说明平方根小于 mid,应向左查找;否则向右查找。

 

下面是四种语言的实现:

 

C 语言实现

 

 

#include <stdio.h>

#include <math.h>

 

double mySqrt(double x) {

    double left = 0.0, right = fmax(1.0, x);

    // 精度设置为 1e-8,确保输出 6 位小数正确

    while (right - left > 1e-8) {

        double mid = left + (right - left) / 2;

        if (mid * mid > x) {

            right = mid;

        } else {

            left = mid;

        }

    }

    return left;

}

 

int main() {

    double x;

    scanf("%lf", &x);

    printf("%.6f\n", mySqrt(x));

    return 0;

}

 

 

C++ 实现

 

 

#include <iostream>

#include <algorithm> // for max

#include <<iomanip> // for setprecision

using namespace std;

 

double mySqrt(double x) {

    double left = 0.0, right = max(1.0, x);

    while (right - left > 1e-8) {

        double mid = left + (right - left) / 2;

        if (mid * mid > x) {

            right = mid;

        } else {

            left = mid;

        }

    }

    return left;

}

 

int main() {

    double x;

    cin >> x;

    cout << fixed << setprecision(6) << mySqrt(x) << endl;

    return 0;

}

 

 

Python 实现

 

 

def my_sqrt(x):

    left = 0.0

    right = max(1.0, x)

    while right - left > 1e-8:

        mid = left + (right - left) / 2

        if mid * mid > x:

            right = mid

        else:

            left = mid

    return left

 

x = float(input())

print("{0:.6f}".format(my_sqrt(x)))

 

 

Java 实现

 

 

import java.util.Scanner;

 

public class Main {

    public static double mySqrt(double x) {

        double left = 0.0;

        double right = Math.max(1.0, x);

        while (right - left > 1e-8) {

            double mid = left + (right - left) / 2;

            if (mid * mid > x) {

                right = mid;

            } else {

                left = mid;

            }

        }

        return left;

    }

 

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        double x = scanner.nextDouble();

        System.out.printf("%.6f\n", mySqrt(x));

        scanner.close();

    }

}

 

 

 

 

http://www.dtcms.com/a/430819.html

相关文章:

  • DataTool.vip官网入口 - 多平台视频与音频免费下载器工具
  • 文心雕龙:DIFY 工作流驱动的Word自动化生成与规范排版方案
  • asp sql做学生信息网站中国建设银行演示网站
  • windows10 系统添加第二块硬盘(解决硬盘盘符丢失问题)
  • java-代码随想录第48天|739. 每日温度、496.下一个更大元素 I、503.下一个更大元素II
  • 在嘉立创的泰山派上也能运行Easysearch
  • JSP 点击量统计
  • 应用网站如何做外贸网站建设哪里做得好
  • Kubernetes证书管理实战:cert-manager部署与CRD导出
  • [Java]PTA: jmu-Java-02基本语法-08-ArrayList入门
  • 网站建设背景及目的搜索优化的培训免费咨询
  • 2012 年真题配套词汇单词笔记(考研真相)
  • Ubuntu20.04 按照飞浆paddle 3.2遇到的问题
  • 网站建设推荐郑国华做网站ps图片都是多大
  • 探索 Docker/K8s 部署 MySQL 的创新实践与优化技巧
  • 线程属性的相关设置详解
  • 深圳公明网站建设桂林北站到阳朔
  • maven的概述以及在mac安装配置
  • 【复习】计网强化第一章
  • 【微信公众平台】小程序如何查找菜单?如何通过自定义的菜单路径生成小程序二维码?小程序二维码指定生成
  • 瑞萨M85内核芯片再出1GHz旗舰双核新品RA8T2,两个千兆以太网MAC,集成EtherCAT从机接口,面向高端电机控制
  • 海洋公园网站建设方案网站开发加设计要多少钱
  • KingbaseES 的 SQL Server 兼容性测试
  • 基于ps2021实现1寸相纸的打印
  • [论文阅读] AI + 软件工程 | 从“事后补救”到“实时防控”,SemGuard重塑LLM代码生成质量
  • 购物网站修改文案常见的网络推广方法有几种
  • 手腕鼓包?可能是腱鞘囊肿
  • 网站推广方法有网站制作哪家做的好
  • Servlet 国际化
  • 安卓基础组件016--Toas组件