pow函数以及math.h的一些坑
本文来自独孤伶俜的博客: pow函数以及math.h的一些坑 - 独孤伶俜
pow函数以及math.h的一些坑
起源
任何问题都有起源不是?这道问题其实是我刚学C语言的时候就自己遇到过。加上最近好多人问我类似于这种问题,于是决定写篇blog来解释一下。。。
问题描述
主要是C语言函数库中main.h中的pow(); 等函数有这个问题
问题的重现性和随机性还有得到的结果可能和你的编译器和cpu架构有关
下面是一个栗子:
#include<stdio.h>
#include<math.h>
int main()
{int i = 2;printf("%d\n",(int)pow(10,2));printf("%d\n",(int)pow(10,i));return 0;
}
将上面代码在 windows10,linux,Android下运行,得到结果如下:
咦 为啥windowds的结果会不一样呢
先看看pow()函数的原型定义
double pow (double base, double exponent);
可以看到这个函数定义的 参数 和 返回值 都是 double 类型
这就意味着我们用int类型参与运算是需要强制转换~
接下来让我们来分析一下下~
- 首先 我们得知道三大平台所对应的编译器是什么(win的cfree5.0用的的clang编译器,Android的C4roid 和 我的Deepin系统用的都是gcc编译器)
- 其实 gcc和clang是两种完全不同的编译器,实现方式,编译步骤甚至都不一样,他们各有各的优势和劣势~,这里就不解释了~~(其实是解释不了!!!)~~
- 最后 我们研究一下子这两编译器生成的中间代码
原来是编译器的锅!!!!!
我们看下中间代码~~(篇幅有限就不贴了)~~看到 :
Android和deepin的gcc编译器生成的代码把int变量的i值在调用pow函数前强制转换为double类型参与运算
于是
int i = 2;
printf("%d\n",(int)pow(10,i));
//就变成了
printf("%d\n",(int)pow(10,(double)i));
//最终就成了
printf("%d\n",(int)pow(10,2.0));
而反观Windows下的Clang编译器 他没有把int的i变成double值,于是……
int i = 2;
printf("%d\n",(int)pow(10,i));
//编译器不知道i是个什么玩意,就会按double的形式把i的二进制数据取出来参与运算,,,
//所以i的值就不知道是啥了,,,运气好的话值可能不会差太远
//如果运气不好,,,那完蛋了,失之毫厘谬以千里也
而常数2为啥不会出错呢
printf("%d\n",(int)pow(10,2));
//这是因为两种编译器都会自动转换常数的类型
//就相当于
printf("%d\n",(int)pow(10.0,2.0));
//所以两个常数都是以double类型参与运算的
//而在遇到 %d 时 他会把之前准备好的(int)强制转换的值给printf 所以不会出错咯~
解决办法
说了这么半天,那到底咋解决呢!!!貌似有好几种方法 哈哈哈
方法一
//涉及整数的幂运算、阶乘等等你就不要使用pow(),自己写个函数随便起个名 不要用double就行了
方法二
//全程使用double运算 最后强制转换为int类型再输出什么的
//比如刚刚上面的代码可以写成这样
double i = 2.0;
int aut1 = (int)pow(10.0,i);
int aut2 = (int)pow(10.0,2.0);
printf("%d\n",aut1);
printf("%d\n",aut2;
方法三
//早日跳坑吧
//程序员没有女友
//有很大风险秃头
//钢铁直男
//But
//I love programming
//I love programming BUG
//I love you
//咳咳,我也爱读沈从文的《边城》
总结
其实不止pow函数,让我们看看math.h中的其他的函数原型
//三角函数
double sin(double);//正弦
double cos(double);//余弦
double tan(double);//正切
//反三角函数
double asin (double); //结果介于[-PI/2,PI/2]
double acos (double); //结果介于[0,PI]
double atan (double); //反正切(主值),结果介于[-PI/2,PI/2]
double atan2 (double,double); //反正切(整圆值),结果介于[-PI,PI]
//绝对值
int abs(int i); //求整型的绝对值
double fabs (double); //求实型的绝对值
double cabs(struct complex znum); //求复数的绝对值
上面这些函数大部分是用的double作为参数和返回值的,所以都有可能出现今天我们谈论的莫名其妙的bug,哈哈哈
尽量避免发生类型强制转换的情况发生,即使无法避免,也要写清楚(类型)强制转换,后面维护也会轻松不少~~~
pow函数以及math.h的一些坑相关推荐
- C语言标准数学函数库math.h之常用函数介绍
C语言标准数学函数库math.h,一些数学计算的公式的具体实现是放在math.h里,具体有: 1 三角函数 double sin (double x); x的正弦值 double cos (doub ...
- C语言数学函数库<math.h>及常用函数
C语言数学函数库<math.h>及常用函数 一.<math.h> C语言中常用的一个数学函数库,里面涵盖了常用的数学运算,如求对数.指数.绝对值.三角函数.两数中最大数等.使用 ...
- 函数定义与调用,自己实现pow()函数对整数的运算
// MyPow.cpp : 此文件包含 "main" 函数.程序执行将在此处开始并结束. //自己实现pow()函数#include <stdio.h>double ...
- 用<math.h>遇到 Redefinition of ‘y1‘ as different kind of symbol的问题
大家好,我是程序员白菜. 前言 今天在用C语言写题目时发现了一个奇怪的问题. 费尽周折,解决问题之后.遂与大家分享,希望大家遇到之后可以快速解决. 问题如下 在vscode上面编译一下代码发现了问题. ...
- C语言math.h中的常用函数实例详解
1.绝对值 2.取整和取余 3.三角函数 4.反三角函数 5.双曲三角函数 6.指数和对数 7.标准化浮点数 8.多项式 9.数学错误计算处理 1.绝对值 函数原型: int abs(int x); ...
- c语言中math的库函数,C语言中math.h库中的常用函数
C语言中math.h库中的常用函数 int abs(int i) 返回整型参数i的绝对值 double cabs(struct complex znum) 返回复数znum的绝对值 double fa ...
- math.h数学函数
函数定义 abs -- 绝对值acos -- 反余弦acosh -- 反双曲余弦asin -- 反正弦asinh -- 反双曲正弦atan2 -- 两个参数的反正切atan -- 反正切atanh - ...
- 常用math.h数学函数以及其他函数(吉林大学 孙立鑫)
目录 1.math.h 头文件的常用函数 a.signbit(求浮点数是否含有符号) b.三角函数汇总 c.双曲函数 d.指数函数对数函数 e.分解浮点数(详解如下)frexp f.取浮点数的指数部分 ...
- 0020 C语言<math.h>函数库
C语言的数学库函数之<math.h>函数库 1. 三角函数 double sin(double); 正弦 double cos(double); 余弦 double tan(double) ...
最新文章
- Sping面试题 Top 50
- 扩展KMP --- HDU 3613 Best Reward
- bolt在java,java neo4j bolt
- SLB vs CLB
- SpringBoot中怎样基于slf4j封装日志类输出日志
- C++中父类的虚函数必需要实现吗?
- Vue系列vue-router的动态路由使用(二)
- 背包——01背包Bone Collector(hdu2602)
- windows xp中安装PadWalker
- 卫星星历和历书的区别
- Oracle 各备份恢复环境下 SCN
- 拼多多微信页面h5 html,拼多多(7pdd)微信跳转h5页面打开app跳转任意url关注技术weixin://dl/business/?ticket...
- 如何成为靠谱的DotNet/C#程序员 (sunxiunan)(zz)
- activiti启动流程的过程中BUSSINESS_KEY没有获取到key
- java8通讯_8.进程通信
- Android 悬浮窗功能实现(微信语音通话悬浮窗效果实现)
- Streamsets相关资料汇总
- 2022电大国家开放大学网上形考任务-桥梁工程技术非免费(非答案)
- 关于Linux性能调优之内存负载调优
- Objective-C基础教程读书笔记(3)
热门文章
- 腾讯云服务器基础操作
- 产品经理原型篇——八大原则教你如何出赏心悦目的原型图
- Python3.6-Flask:制作一个语音对话问答机器人系统(网页版)
- Get UWP Version(不使用额外的nuget包或SDK)
- System.out. 输出到指定文件中
- 如何提高项目交付效率
- DBLE分库分表实战
- word转换为html为什么图片显示不了,word插入html 转换为docx图片不显示问题
- 2015年国网计算机考试试题,2015全国计算机等级一级MS Office考试试题(回忆版)
- Kubuntu安装N卡驱动教程