C语言基本概念————讨论sqrt()和pow()函数与整数的关系

本文来源:C语言基本概念——讨论sqrt()和pow()函数与整数的关系.

C语言基本概念——sqrt和pow函数与整数的关系

  • 1. 使用sqrt()是否可以得到完全平方数的精确的整数平方根
    • 1.1 完全平方数的计算结果是否精确?
    • 1.2 为什么不会出现误差(如 `1.9999999`)?
    • 1.3 可能产生误差的情况
    • 1.4 总结
  • 2. 使用pow函数计算整数的幂能否得到精确的整数值
    • 2.1 **浮点数的精度限制**
    • 2.2 **隐式类型转换的陷阱**
    • 2.3 **实现依赖性问题**
    • 2.4 建议:如何安全计算整数幂?
    • 2.5 结论
    • 3. 举例


根据C标准,float类型必须至少能够表示6位有效数字,且取值范围至少是10-37〜10+37。其中,6位有效数字的要求意味着float类型必须能够精确表示如33.333333这样的数值;而取值范围的规定则使其能够方便地表示诸如太阳质量(2.0e30千克)、质子电荷量(1.6e-19库仑)等极大或极小的数值。

在大多数C语言实现中,单精度浮点数采用IEEE 754标准的32位表示法,其中尾数部分占23位(223= 8,388,608),相当于7位十进制数。这意味着float类型在转换为十进制后,最多可以保证7位有效数字的精度,完全满足C标准对6位有效数字的要求。需要注意的是,第7位之后的数字可能不准确。类似地,double类型的尾数占52位(252),可表示约16位十进制有效数字,或63位(263)时可表示约19位十进制有效数字。因此,double类型通常可以保证15-17位有效数字的精度。

sqrt()pow() 函数是 C 标准库 <math.h> 中的两个重要数学函数,其函数原型分别为:

double sqrt(double x);
double pow(double x, double y);

sqrt()函数用于计算x的平方根,而pow()函数用于计算x的y次幂。这两个函数的参数和返回值类型均为double类型。

对于sqrt()函数,要求输入参数x必须是非负实数。如果x为负数,在大多数实现中会产生域错误(domain error),并返回NaN(Not a Number)值。

现在,我们针对这两个函数与整数之间的关系提出以下两个问题:

  • 1.当n是一个完全平方数时,使用sqrt(n)函数是否能够计算出n的精确整数平方根?
  • 2.使用pow()函数是否能够计算出x^y的精确整数值?
  • 注:本文中所讨论的"整数"一般是指在标准整数类型可表示范围内的整数值。

1. 使用sqrt()是否可以得到完全平方数的精确的整数平方根

1.1 完全平方数的计算结果是否精确?

完全平方数的平方根是整数(例如 sqrt(4)=2)。对于较小的完全平方数(如 4, 9, 16 等),双精度浮点数(double)可以精确表示它们的平方根,因此 sqrt() 函数会返回准确的整数值(如 2.0)。

1.2 为什么不会出现误差(如 1.9999999)?

  • 浮点数的特性
    双精度浮点数(double)的尾数有52位,可以精确表示所有绝对值小于 2^53(约 9e15)的整数。因此,对于较小的完全平方数(如 4, 100, 10000 等),其平方根是整数且落在 2^53 范围内,sqrt() 的结果会是精确的。

  • 数学库的优化
    现代数学库(如 glibc)会对完全平方数的计算进行优化,直接返回精确的整数值,避免浮点运算的舍入误差。

1.3 可能产生误差的情况

只有当完全平方数的平方根 超过双精度浮点数的精确表示范围 时,才会出现误差。例如:

  • 对于 n = (2^26)^2 = 2^52,其平方根 2^26 是精确的。
  • 但对于 n = (2^26 + 1)^2,平方根 2^26 + 1 可能会因超出 2^53 的精确表示范围而产生微小误差。
  • 注:在实测中,没有产生误差,都能精确表示。

1.4 总结

  • 对于较小的完全平方数(如 4, 9, 100 等):
    sqrt() 返回的结果是精确的(如 2.0, 3.0, 10.0),不会出现 1.99999992.00000000001

  • 对于极大的完全平方数(超过 2^53):
    可能因浮点数精度限制产生微小误差,需谨慎处理。


2. 使用pow函数计算整数的幂能否得到精确的整数值

在C语言中,pow函数不能保证总是返回精确的整数值,其准确性取决于以下关键因素:

2.1 浮点数的精度限制

  • pow函数的参数和返回值均为double类型,其底层使用浮点数运算。虽然double类型可以精确表示一定范围内的整数(通常到2⁵³),但当计算结果超出此范围时,精度丢失可能导致误差
  • 示例
    printf("%.0f", pow(2, 53));   //输出 9007199254740992(精确)
    printf("%.0f", pow(2, 53)+1); //同样输出 9007199254740992(无法区分)
    

2.2 隐式类型转换的陷阱

  • 即使输入的底数和指数是整数,pow内部仍会转换为浮点数计算。对于某些看似简单的运算,舍入误差可能导致意外结果
    int a = (int)pow(5, 3);  // 期望125,实际可能得到124(如4.999999被截断)
    

2.3 实现依赖性问题

  • 不同编译器/数学库对pow的优化策略不同。例如:
    pow(10, 2);  // 可能返回100.0(精确)或99.99999999999999(误差)
    

2.4 建议:如何安全计算整数幂?

  1. 小整数幂:直接使用循环乘法

    int power(int base, int exp) {int result = 1;for (int i = 0; i < exp; i++) result *= base;return result;
    }
    
  2. 大整数或高精度需求:使用<stdint.h>中的大整数类型(如int64_t)或第三方库(如GMP)。

  3. 必须用pow:添加误差补偿

    #include <math.h>
    int safe_pow(int base, int exp) {double result = pow(base, exp);return (int)(result + 0.5);  // 四舍五入补偿
    }
    

2.5 结论

  • 可用场景:当结果远小于2⁵³且无需强制转换为整数时,pow可临时使用。
  • 风险场景:涉及大整数、类型转换或高精度需求时,必须避免依赖pow函数。

3. 举例

下列程序在Dev C++环境下运行

#include <stdio.h>
#include <math.h>
int main( void ) {printf("sqrt(): %s %d\n","error.", sqrt(pow(2, 52)));printf("sqrt(): %d %s\n", (int)sqrt(pow(2, 52)), "精确");printf("sqrt(): %d %s\n",(int)sqrt(pow(2, 54)), "精确");long long lnum = sqrt(pow(2, 80));printf("sqrt(): %lld %s\n",lnum, "精确");printf("pow(): %.0f %s\n", pow(2, 53)-1, "精确");printf("pow(): %.0f %s\n", pow(2, 53), "精确");printf("pow(): %.0f %s\n", pow(2, 53)+1, "无法区分");printf("pow(): %.0f %s\n", pow(2, 54), "精确");printf("pow(): %.0f %s\n", pow(2, 55), "精确");printf("pow(): %.0f %s\n", pow(2, 56), "精确");printf("pow(): %.0f %s\n", pow(2, 57), "不精确");printf("pow(): %.0f %s\n", pow(2, 64), "不精确");return 0;
}

运行结果截图如下:
在这里插入图片描述

下列程序在LLVM (clang-cl)环境下运行

#include <stdio.h>
#include <math.h>int main(void) { printf("sqrt(): %s %d\n", "error.", sqrt(pow(2, 52)));printf("sqrt(): %d %s\n", (int)sqrt(pow(2, 52)), "精确");printf("sqrt(): %d %s\n", (int)sqrt(pow(2, 54)), "精确");long long lnum = sqrt(pow(2, 80));printf("sqrt(): %lld %s\n", lnum, "精确");printf("pow(): %.0f %s\n", pow(2, 53) - 1, "精确");printf("pow(): %.0f %s\n", pow(2, 53), "精确");printf("pow(): %.0f %s\n", pow(2, 53) + 1, "无法区分");printf("pow(): %.0f %s\n", pow(2, 54), "精确");printf("pow(): %.0f %s\n", pow(2, 55), "精确");printf("pow(): %.0f %s\n", pow(2, 56), "精确");printf("pow(): %.0f %s\n", pow(2, 57), "精确");printf("pow(): %.0f %s\n", pow(2, 64), "精确");return 0;
}

运行结果截图如下:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/16904.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

浏览器自动化与AI Agent结合项目browser-use初探

browser-use介绍 browser-use是将您的 AI 代理连接到浏览器的最简单方式。它通过提供一个强大且简单的接口来实现 AI 代理访问网站的自动化。 GitHub地址&#xff1a;https://github.com/browser-use/browser-use。目前已经获得了27.3k颗stars&#xff0c;2.7kforks&#xff…

阿里云 DeepSeek 模型部署与使用技术评测

引言 随着人工智能技术的不断发展&#xff0c;越来越多的企业和个人开始探索如何利用深度学习模型来提升业务效率和用户体验。阿里云推出的【零门槛、轻松部署您的专属 DeepSeek 模型】解决方案为用户提供了多种便捷的部署方式&#xff0c;包括基于百炼 API 调用满血版、基于人…

第二天:工具的使用

每天上午9点左右更新一到两篇文章到专栏《Python爬虫训练营》中&#xff0c;对于爬虫有兴趣的伙伴可以订阅专栏一起学习&#xff0c;完全免费。 键盘为桨&#xff0c;代码作帆。这趟为期30天左右的Python爬虫特训即将启航&#xff0c;每日解锁新海域&#xff1a;从Requests库的…

vue项目 Axios创建拦截器

Axios 1. Axios 和 Ajax 简介2. Axios 和 Ajax 的区别3. 从 按钮 到 Axios请求后端接口的 大致顺序 1. Axios 和 Ajax 简介 Ajax&#xff08;Asynchronous JavaScript and XML&#xff09; 不是一种技术&#xff0c;而是一个编程技术概念&#xff0c;核心是通过 XMLHttpReques…

windows + visual studio 2019 使用cmake 编译构建静、动态库并调用详解

环境 windows visual studio 2019 visual studio 2019创建cmake工程 1. 静态库.lib 1.1 静态库编译生成 以下是我创建的cmake工程文件结构&#xff0c;只关注高亮文件夹部分 libout 存放编译生成的.lib文件libsrc 存放编译用的源代码和头文件CMakeLists.txt 此次编译CMak…

通过 VBA 在 Excel 中自动提取拼音首字母

在excel里面把表格里的中文提取拼音大写缩写怎么弄 在Excel中&#xff0c;如果你想提取表格中的中文字符并转换为拼音大写缩写&#xff08;即每个汉字的拼音首字母的大写形式&#xff09;&#xff0c;可以通过以下步骤来实现。这项工作可以分为两个主要部分&#xff1a; 提取拼…

通过环境变量实现多个 python 版本的自由切换以及 Conda 虚拟环境的使用教程

目录 Python 安装包的下载和安装通过环境变量的方式来切换不同的 Python 版本Pycharm 创建项目使用虚拟环境 使用虚拟环境管理工具 condaConda 教程1. **环境管理**创建虚拟环境激活虚拟环境退出虚拟环境列出所有虚拟环境删除虚拟环境导出虚拟环境配置从文件创建虚拟环境 2. **…

排序算法详解、应用对比与C语言实现

四种经典排序算法详解&#xff08;原理动图代码&#xff09; 一、排序算法的重要性 排序算法是计算机科学领域最基础的算法之一&#xff0c;在数据库索引、搜索引擎优化、大数据分析等领域有广泛应用。根据Stack Overflow 2022开发者调查&#xff0c;超过83%的面试会考察算法…

Python基于Django的微博热搜、微博舆论可视化系统(V3.0)【附源码】

博主介绍&#xff1a;✌Java老徐、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&…

网络安全ids是什么意思

1、 简述IPS和IDS的异同点&#xff1b; 入侵检测系统&#xff08;IDS&#xff09; IDS&#xff08;Intrusion Detection Systems&#xff0c;入侵检测系统&#xff09;&#xff0c;专业上讲就是依照一定的安全策略&#xff0c;对网络、系统、运行状况进行监视&#xff0c;尽可能…

JVM春招快速学习指南

1.说在前面 在Java相关岗位的春/秋招面试过程中&#xff0c;JVM的学习是必不可少的。本文主要是通过《深入理解Java虚拟机》第三版来介绍JVM的学习路线和方法&#xff0c;并对没有过JVM基础的给出阅读和学习建议&#xff0c;尽可能更加快速高效的进行JVM的学习与秋招面试的备战…

json格式,curl命令,及轻量化处理工具

一. JSON格式 JSON&#xff08;JavaScript Object Notation&#xff09; 是一种轻量级的数据交换格式。它基于一个子集的JavaScript编程语言&#xff0c;使用人类易于阅读的文本格式来存储和表示数据。尽管名字中有“JavaScript”&#xff0c;但JSON是语言无关的&#xff0c;几…

echarts 3d中国地图飞行线

一、3D中国地图 1. 一定要使用 echarts 5.0及以上的版本; 2. echarts 5.0没有内置中国地图了。点击下载 china.json&#xff1b; 3. 一共使用了四层地图。 &#xff08;1&#xff09;第一层是中国地图各省细边框和展示南海诸岛&#xff1b; &#xff08;2&#xff09;第二层是…

从 0 开始本地部署 DeepSeek:详细步骤 + 避坑指南 + 构建可视化(安装在D盘)

个人主页&#xff1a;chian-ocean 前言&#xff1a; 随着人工智能技术的迅速发展&#xff0c;大语言模型在各个行业中得到了广泛应用。DeepSeek 作为一个新兴的 AI 公司&#xff0c;凭借其高效的 AI 模型和开源的优势&#xff0c;吸引了越来越多的开发者和企业关注。为了更好地…

[AI]Mac本地部署Deepseek R1模型 — — 保姆级教程

[AI]Mac本地部署DeepSeek R1模型 — — 保姆级教程 DeepSeek R1是中国AI初创公司深度求索&#xff08;DeepSeek&#xff09;推出大模型DeepSeek-R1。 作为一款开源模型&#xff0c;R1在数学、代码、自然语言推理等任务上的性能能够比肩OpenAI o1模型正式版&#xff0c;并采用MI…

Linux(socket网络编程)TCP连接

Linux&#xff08;socket网络编程&#xff09;TCP连接 基础文件目录函数系统进程控制函数fork()exec系列函数void abort(void)void assert(int expression)void exit(int status)void _exit(int status)int atexit(void (*func)(void))int on_exit(void (*function)(int,void*)…

408-数据结构

数据结构在学什么&#xff1f; 1.用代码把问题信息化 2.用计算机处理信息 ch1 数据&#xff1a;数据是信息的载体&#xff0c;是描述客观事物属性的数、字符及所有能输入到计算机中并被计算机程序识别和处理的符号的集合。数据是计算机程序加工的原料。 ch2 //假设线性表…

Go语言开发桌面应用基础框架(wails v3)-开箱即用框架

前言 本文是介绍如何集成好了Wails3开发框架以及提供视频教程&#xff0c;当你需要桌面开发时&#xff0c;直接下载我们基础框架代码&#xff0c;开箱即用不用配置开发需要依赖。 为什么使用v3版本&#xff0c;主要是v3新增的功能 ​支持多个窗口&#xff1a;在单个应用程序…

Git 与 Git常用命令

Git 是一个开源的分布式版本控制系统&#xff0c;广泛用于源代码管理。与传统的集中式版本控制系统不同&#xff0c;Git 允许每个开发者在本地拥有完整的代码库副本&#xff0c;支持离线工作和高效的分支管理。每次提交时&#xff0c;Git 会对当前项目的所有文件创建一个快照&a…

尚硅谷爬虫note004

一、urllib库 1. python自带&#xff0c;无需安装 # _*_ coding : utf-8 _*_ # Time : 2025/2/11 09:39 # Author : 20250206-里奥 # File : demo14_urllib # Project : PythonProject10-14#导入urllib.request import urllib.request#使用urllib获取百度首页源码 #1.定义一…