数学函数的参数和返回值探秘

news2025/1/13 7:39:19

数学函数的参数和返回值探秘

  • 一、数学函数的参数
    • 1.1 隐式类型转换
    • 1.2 隐式类型转换的秘密
  • 二、数学函数的返回值

本文所说的数学函数单指<math.h>中的系统函数,这些函数对参数和返回值的要求与其他类函数是有一点不同的。尤其是参数部分,是有值得深挖的东西的,本文将揭示这里面隐藏的秘密。

一、数学函数的参数

在C、C++中,数学函数的参数和返回值一般都要求是浮点型的,那么如果输入一个整数或者整数表达式作参数会怎么样呢?

1.1 隐式类型转换

以计算平方根的函数为例,共有3个函数,分别是sqrt, sqrtf, sqrtl,函数原型如下:

float       sqrtf( float arg );
double      sqrt( double arg );
long double sqrtl( long double arg );

按要求参数不能是整数,返回值也不能是整数。所以按理sqrt(9)是不符合函数要求的,而应写成sqrt(9.0),但实际上,用sqrt(9)也能输出正确结果。这是因为,在调用函数时,如果传入一个非接受类型的参数,会被隐式转换为接受的类型。
隐式类型转换又叫自动类型转换,常发生在赋值操作或表达式求值时。这种转换是由编译器自动进行的,不需要程序员显式地指定转换类型(这种叫强制类型转换或显式类型转换)。
为什么能自动进行转换呢?
因为sqrt(arg)函数被定义为接受double类型的参数,这一点对于编译器来讲是已知的,当传递int类型时,编译器自然会知道应该把它转换为什么类型,即会自动隐式转换为 double类型。

1.2 隐式类型转换的秘密

这里面有一个很有意思的事情,就是sqrt(arg)函数将参数arg由int转为double类型时,它实际上是将arg作为一个整体来转换的。比如sqrt(19/2)的计算过程:
1)求值。把19/2视为一个整体,先计算出它的值。因为分子分母都是整数,所以输出结果也是整型,计算结果会舍去小数部分,即19/2=9。
2)转换。将19/2的结果由int型转换为double,即将9转换为9.0,然后再计算sqrt(9.0)的值。
也就是说,它是先求值,后转换,所以sqrt(arg)相当于sqrt((double)(arg))。

(double)就是前面说的强制类型转换,用带()的类型转换运算符来表示。

这一点其实也很好理解,函数的原型就是sqrt(arg),它的参数归根到底只有arg这位仁兄,至于arg是怎么计算来的,取决于它本身的表达式,和函数本身没有关系(即19/2的值只与19/2这个表达式本身有关,和sqrt函数无关)。sqrt(arg)只管把arg转化为浮点型,然后计算它的算术平方根。
注意sqrt((double)(arg))参数中的这两个括号都是非常有必要的,感兴趣的可以用下面的代码测试一下,就可以看出其中的玄机。

#include<stdio.h>
#include<math.h>
int main(){
    printf("%f\n", sqrt(9.0));
    printf("%f\n", sqrt(9));
    printf("%f\n", sqrt(19/2));
    printf("%f\n", sqrt((double)(19/2)));
    printf("%f\n", sqrt((double)19/2));
	printf("%f\n", sqrt(19/(double)2));
	printf("%f\n", sqrt(19.0/2));
    return 0;
}

程序输出结果:
在这里插入图片描述
看吧,前4个表达式是等价的,后3个表达式是等价的。
这里尤其注意以下两个表达式的不同:

printf("%f\n", sqrt((double)(19/2)));
printf("%f\n", sqrt((double)19/2));

前者的(double)是可有可无的,就相当于printf("%f\n", sqrt(19/2));,它们表达的都是同一个意思:先求值(19/2=9)、后转换。
后者由于19/2没有括号,命运彻底改变,(double)19/2作为一个表达式,(double)和19才是最亲密的一对,因此先将19转换为浮点数,所以(double)19/2的结果是9.5,然后再计算平方根。
一个是对9开平方,一个是对9.5开平方,结果自然不同。

注意:无论哪种写法,强制类型转换(double)中的括号是不能省略的,这是语法要求,即不能写成printf("%f\n", sqrt(double(19/2)));,否则会报语法错误。

二、数学函数的返回值

sqrt的返回值也是double类型的,所以用printf输出时也不能用%d(如用了会输出0),而要用%f。

注意:
违反以上要求编译时也不会报错,但输出结果会有问题。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

炸砖块游戏的最终图案

描述 小红正在玩一个“炸砖块”游戏,游戏的规则如下:初始有一个 n * m 的砖块矩阵。小红会炸 k 次,每次会向一个位置投炸弹,如果这个位置有一个砖块,则砖块消失,上方的砖块向下落。小红希望你画出最终砖块的图案。 输入描述 第一行输入三个正整数 n, m, k,代表矩阵的行…

代码随想录算法训练营第 4 天(链表 2)| 24. 两两交换链表中的节点19.删除链表的倒数第N个节点 -

一、24. 两两交换链表中的节点 题目&#xff1a;24. 两两交换链表中的节点 - 力扣&#xff08;LeetCode&#xff09; 视频&#xff1a;帮你把链表细节学清楚&#xff01; | LeetCode&#xff1a;24. 两两交换链表中的节点_哔哩哔哩_bilibili 讲解&#xff1a;代码随想录 dummy-…

【微服务】面试题 5、分布式系统理论:CAP 与 BASE 详解

分布式系统理论&#xff1a;CAP 与 BASE 详解 一、CAP 定理 背景与定义&#xff1a;1998 年由加州大学科学家埃里克布鲁尔提出&#xff0c;分布式系统存在一致性&#xff08;Consistency&#xff09;、可用性&#xff08;Availability&#xff09;、分区容错性&#xff08;Part…

【网络】:网络编程套接字

目录 源IP地址和目的IP地址 源MAC地址和目的MAC地址 源端口号和目的端口号 端口号 VS 进程ID TCP协议和UDP协议 网络字节序 字符串IP和整数IP相互转换 查看当前网络的状态 socket编程接口 socket常见API 创建套接字 绑定端口号 发送数据 接收数据 sockaddr结构…

UnityDemo-TheBrave-制作笔记

这是我跟着b站up主MStudio的视频学习制作的&#xff0c;大体上没有去做一些更新的东西&#xff0c;这里只是一个总的总结。在文章的最后&#xff0c;我会放上可以游玩该游戏的链接和exe可执行文件&#xff0c;不过没有对游戏内容进行什么加工&#xff0c;只有基本的功能实现罢了…

力扣经典二分题:4. 寻找两个正序数组的中位数

题目链接&#xff1a;4. 寻找两个正序数组的中位数 - 力扣&#xff08;LeetCode&#xff09; 一、题目分析 这道题目是让我们在 两个正序的数组中寻找中位数已知两个数组的大小分别是&#xff1a;int m nums1.size(),n nums2.size();中位数性质1&#xff1a;中位数左侧元素 …

C++ 文字识别OCR

一.引言 文字识别&#xff0c;也称为光学字符识别&#xff08;Optical Character Recognition, OCR&#xff09;&#xff0c;是一种将不同形式的文档&#xff08;如扫描的纸质文档、PDF文件或数字相机拍摄的图片&#xff09;中的文字转换成可编辑和可搜索的数据的技术。随着技…

SpringBoot:SaToken的options预检请求鉴权失败

问题描述 使用如下sa-token配置&#xff0c;前端通过IP端口号的方式访问后端服务&#xff0c;会存在options预检请求鉴权失败的问题。 问题分析 http-options请求 HTTP OPTIONS 方法请求给定的 URL 或服务器的允许通信选项。客户端可以用这个方法指定一个 URL&#xff0c;或者…

UE材质函数

材质函数是可在不同材质中重复使用的材质表达式的一个集合 相当于把常用的功能封装到一个集合里&#xff0c;需要用到的时候调用 输入input可以添加输入节点 如果勾上公开到库&#xff0c;就可以在材质面板直接搜索到材质函数 材质函数可以直接做成一个输出

51c~Pytorch~合集5

我自己的原文哦~ https://blog.51cto.com/whaosoft/13059544 一、PyTorch DDP 正在郁闷呢 jetson nx 的torchvision安装~~ 自带就剩5g 想弄到ssd 项目中的 venv中又 cuda.h没有... 明明已经装好什么都对 算了说今天主题 啊对 还是搬运啊 学习之工具人而已 勿怪 Distrib…

用vscode写latex-1

一般大伙使用 LaTeX 大体有两种方案&#xff0c; 一种是在本地配置环境或使用本地的软件&#xff0c;如 vscode LaTeX&#xff0c;texlive&#xff0c;lyx 等等&#xff1b; 另一种是线上 LaTeX 平台&#xff0c;其中用的最多的是 Overleaf&#xff0c;还有一部分高校也有自…

用户界面软件05

已知应用 几乎所有的流行的用户界面架构都使用这种模式。我在这里举三个例子&#xff1a; 1. Seeheim 用户界面架构的特点是有一个应用核心的领域层和一个用户界面层。后者 被分为两层&#xff0c;叫做表示层和对话控制层。因为这个架构和面向事务系统有渊源&#xff0c;没有…

虚拟文件系统 VFS

目录 虚拟文件系统 VFS 文件系统挂载过程 虚拟文件系统 VFS 统一标准的系统调用接口&#xff1a; VFS定义了一组标准的文件操作API&#xff0c;如open(), read(), write(), close()等&#xff0c;使得用户空间的应用程序无需关心底层文件系统的具体类型。 下层文件系统必须实现…

conda 批量安装requirements.txt文件

通常可以用下面conda命令安装requirements.txt文件 conda install --yes --file requirements.txt 但是&#xff0c;一旦遇到某个包安装失败&#xff0c;就会停止安装后续的包。 下面这条命令能解决上面出现的不执行后续包的问题&#xff0c;需要在CMD窗口执行&#xff1a; 点…

Auto-CoT:自动构建大模型的思维链提示

今天分享的是由上海交通大学发表的一篇文章&#xff1a;Auto-COT 论文题目&#xff1a;AUTOMATIC CHAIN OF THOUGHT PROMPTING IN LARGE LANGUAGE MODELS 论文链接&#xff1a;https://arxiv.org/pdf/2210.03493 代码地址&#xff1a;https://github.com/amazon-science/aut…

算法练习7——拦截导弹的系统数量求解

题目描述 某国为了防御敌国的导弹袭击&#xff0c;发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷&#xff1a;虽然它的第一发炮弹能够到达任意的高度&#xff0c;但是以后每一发炮弹都不能高于前一发的高度。 假设某天雷达捕捉到敌国的导弹来袭。由于该系统还在试用…

命令行中打印二维码

前公司中登录设备时&#xff0c;需要下发密钥&#xff0c;密钥是通过扫描终端中的二维码获得的&#xff0c;终端中的二维码类似这样&#xff1a; 当时没理解原理&#xff0c;现在研究了下如何在命令行中打印二维码。主要介绍其中一些开源工具&#xff1a; 1. qrencode 简介 …

Android车机DIY开发之软件篇(八)单独编译

Android车机DIY开发之软件篇(八)单独编译 1.CarLauncher单独编译 CarLauncher源码位于 packages/apps/Car/Launcher 用Eclipse ADT 谷歌定制版编译而成&#xff0c;.mk .bp编译 Android13目录如下: alientekalientek:~/packages/apps/Car$ ls Calendar …

3 前端: Web开发相关概念 、HTML语法、CSS语法

文章目录 前言:导学1 Web开发相关概念2 Web标准(网页标准)3 软件架构(CS/BS)(1)C/S: Client/Server 客户端 / 服务器端(2)B/S: Browser/Server 浏览器 / 服务器端VSCode配置前段开发环境一、HTML概念1 概念2 HTML快速入门(1)语法快速入门(2)VSCode一个 !(快捷键…

Redis:内存管理

1. 最大内存限制 (maxmemory) 简介 概念:maxmemory 参数用于设置 Redis 实例允许使用的最大内存量。作用:当 Redis 使用的内存达到这个限制时,它会根据配置的淘汰策略来决定如何处理新的写入请求或移除现有数据。示例 # 设置最大内存为2GB maxmemory 2gb注意事项 合理规划…