</pre>源程序如下:<p></p><p></p><pre name="code" class="cpp">#include <stdio.h>
#include <math.h>
int main(int argc, char *argv[])
{float a,b,c,x1,x2,p,q,dish;scanf("%f%f%f",&a,&b.&c);dish=b*b-4*a*c;if(fabs(a)<=1e-7)printf("不是一元二次方程")else if(fabs(dish)<=1e-7)printf("有两个等根:%d",(-b/2a));else if(dish>1e-7){x1=(-b+sqrt(dish))/2a;x2=(-b-sqrt(dish))/2a;printf("两个实根:x1=%f,x2=%f",x1,x2);}else {p=-b/2a;q=sqrt(-dish)/2a;printf("两个复根为:%d+%di,%d-%di",p,q,p,q);}return 0;
}

其中学习了两个知识点,abs函数和fabs函数以及对于浮点数不能直接进行相等比较,也不能与0比较相等。

一、abs函数与fabs函数:

abs函数的原型为 int abs(int x),而fabs的原型为double fabs(double x),为什么要把这两个函数的原型写出来,是因为abs函数是求整型数据的绝对值,fabs函数是求浮点数的绝对值,曾经想用abs函数求浮点数的绝对值,例如 定义float变量,输入1.2,输出:printf("%d",abs(i));实际结果是:1.

如下:

#include "stdio.h"
#include "math.h"
main()
{float i,j,k1,k3;
i=-1.02;
k1=abs(i);
j=-2.03;
k3=fabs(j);
printf("abs=%.2f\nfabs=%.2f\n",k1,k3);
}
输出结果:k1=1.00,k3=2.03。
可见abs是取绝对值后再取整,而fabs是取绝对值。vc中对fabs()定义有3种:float fabs(),double fabs(),long double fabs()

至于最新的gcc中对fabs的定义暂时不知道,请知道的朋友指点。

二、浮点数的相等比较

谭浩强的书中强调浮点数不能适用“==”来进行大小比较,因为浮点数在计算和存储时会有一些微小的误差。

常规方法都是指定一个足够小的常量,然后使用fabs(a-b)<足够小的常量,那么认为a==b;

我认为这个足够小的常量不是说随便指定的,需要参照浮点数a,b的量级来进行指定,并不是说10000.0和10001.0进行相等比较时,你指定一个1e-6的常量,那么这就失去意义了。

下面转载一篇文章,是使用相对误差和绝对误差结合对浮点数是否相等来进行判断的

相对误差:relative tolerance文章中的relerror既是。绝对误差:absolute error,文章中abserror既是。

在数学运算当中经常会涉及到判断两个数是否相等的情况 
对于整数很好处理 A==B这样的一个语句就可以解决全部的问题 
但是对于浮点数是不同的

首先,浮点数在计算机当中的二进制表达方式就决定了大多数浮点数都是无法精确的表达的 
现在的计算机大部分都是数字计算机,不是模拟机,数字机的离散化的数据表示方法自然无法精确表达大部分的数据量的。

其次计算机浮点数的精度在单精度float类型下,只有7位,在进行浮点运算的时候,这个精度往往会导致运算的结果和实际期望的结果之间有误差

因为前两个原因,我们很难用 A==B来判定两个浮点数是否相同

很自然,我们可以想到 fabs(A-B) < epsilon 这样的一种判别方法 
但是这种判别方法稳妥吗? 
它也不稳妥。

首先, epsilon是一个绝对的数据,也就是误差分析当中说说的绝对误差 
使用一个固定的数值,对于float类型可以表达的整个数域来说是不可以的 
比如epsilon取值为0.0001,而a和b的数值大小也是0.0001附近的,那么显然不合适 
另外对于a和b大小是10000这样的数据的时候,它也不合适,因为10000和10001也可以认为是相等的呢 
适合它的情况只是a或者b在1或者0附近的时候

既然绝对误差不可以,那么自然的我们就会想到了相对误差 
bool IsEqual(float a, float b, float relError ) {   
                  return ( fabs ( (a-b)/a ) < relError ) ? true   : false; 

这样写还不完善,因为是拿固定的第一个参数做比较的,那么在调用 
IsEqual(a, b, relError ) 和 IsEqual(b, a, relError ) 的时候,可能得到不同的结果 
同时如果第一个参数是0的话,就有可能是除0溢出 
这个可以改造 
把除数选取为a和b当中绝对数值较大的即可 
bool IsEqual(float a, float b, relError ) 
{   

   if (fabs(a)<fabs(b)) return ( fabs((a-b)/a)    >     relError ) ? true     :    false;   
     return ( fabs((a-b)/b)     >     relError ) ? true     :    false; 
};

使用相对误差就很完善吗? 
也不是, 在某些特殊情况下, 相对误差也不能代表全部 
比如在判断空间三点是否共线的时候,使用判断点到另外两个点形成的线段的距离的方法的时候 
只用相对误差是不够的,应为线段距离可能很段,也可能很长,点到线段的距离,以及线段的长度做综合比较的时候,需要相对误差和绝对误差结合的方式才可以 
相对完整的比较算法应该如下: 
bool IsEqual(float a, float b, float absError, float relError ) 
{   
                                   if (a==b) return true; 
if (fabs(a-b)<absError ) return true; 
if (fabs(a>b) return (fabs((a-b)/a>relError ) ? true : false; 
return (fabs((a-b)/b>relError ) ? true : false; 

这样才相对完整  

 

参照MSDN定义:

<strong><span style="color:#3366ff;">/* Compile options needed: none. Value of c is printed with a decimal
point precision of 10 and 6 (printf rounded value by default) to
show the difference
*/
#include
// Define your own tolerance</span></strong>
<strong><span style="color:#3366ff;">const double EPSILON = 1.00e-07;</span></strong>
<strong><span style="color:#3366ff;">const float   FLT_EPSILON  = 1.192092896e-07F;</span></strong>
<pre class="code" name="code" style="white-space: pre-wrap; word-wrap: break-word;"><p><strong><span style="color:#3366ff;">const double  DBL_EPSILON  = <span style="font-size: 13px;">2.2204460492503131e-016;</span></span></strong></p><span style="color:#333333;">
</span><p style="color: rgb(51, 51, 51);"><span style="font-size: 13px;"></span></p><span style="color:#333333;">
</span><span style="color: rgb(51, 51, 51); font-size: 13px;">
</span><p style="color: rgb(51, 51, 51);"> </p><span style="color:#333333;">
#define FLOAT_EQ(x,v) (((v - EPSILON) < x) && (x <( v + EPSILON)))
int main()
{
float a, b, c;
a = 1.345f;
b = 1.123f;
c = a + b;
// if (FLOAT_EQ(c, 2.468))   // Remove comment for correct result
if (c == 2.468)              // Comment this line for correct result
printf("They are equal.\n");
else
printf("They are not equal! The value of c is %13.10f,or %f",c,c);</span>

转载于:https://www.cnblogs.com/JSD1207ZX/p/9386273.html

一个一元二次方程求解编程引申的两个知识点(abs和fabs的区别以及浮点数比较相等)...相关推荐

  1. python解一元二次方程复数_一元二次方程求解(包括复数各种情况)

    /*无聊时候写的,我想每个入门的编程都会拿着个练手把,多的不说,我们来谈谈正经的--此功能实现一元二次方程求解,复数情况,输入字符处理判断是否为数字*/ import os import math i ...

  2. c语言对分求解方程,用C语言对一元二次方程求解

    一元二次方程标准形式为 ax²+bx+c=0,且a≠0. 在用C语言求值时,需要先判断给出的a.b.c三值是否满足一元二次方程,即判断a是否为0. 当a=0时,输出(不是一元二次方程): 当a≠0时, ...

  3. 用C语言对一元二次方程求解

    一元二次方程标准形式为 ax²+bx+c=0,且a≠0. 在用C语言求值时,需要先判断给出的a.b.c三值是否满足一元二次方程,即判断a是否为0. 当a=0时,输出(不是一元二次方程): 当a≠0时, ...

  4. 算法创作 | 一元二次方程求解问题解决方法

    本文首发于微信公众号:"算法与编程之美",欢迎关注,及时了解更多此系列文章. 问题描述 键盘输入a,b,c,作为一元二次方程的系数,求解. 示例:ax^2+bx+c=0 输入:a= ...

  5. Python 每日一题(一元二次方程求解)

    Python 每日一题:锻炼Python语法的运用,思维逻辑的锻炼,算法能力的培养. 题目: 输入一个一元二次方程的系数 a, b, c,求解方程的根. 分析:  1.一元二次方程标准形式: (a ≠ ...

  6. python实现一元二次方程求解

    python实现一元二次方程求解 import random a=float(input("请输入a: "))b=float(input("请输入b: "))c ...

  7. 练习题004:一元二次方程求解

    C语言练习题目录索引 题目:二元一次方程的形式一般是 ax2+bx+c=0ax2+bx+c=0 ax^2+bx+c=0(a不能为0),输入a.b.c,求这个二元一次方程的解. 解题思路:首先我们得清楚 ...

  8. 一元二次方程求解(C语言版)

    int main(){//一元二次方程求解 double a,b,c;double x1,x2,s,p,q;printf("请输入ax^2+bx+c=0的a,b,c\n");pri ...

  9. JAVA学习-JAVA实现一元二次方程求解

    JAVA实现一元二次方程求解 求3X2+4X-1=0的根 代码: public class SolveEquation {//定义公共类public static void main(String[] ...

最新文章

  1. java web常用权限方式,java web项目的几种权限控制方法
  2. Windows: 在系统启动时运行程序、定时计划任务、定时关机
  3. Swift 网络请求数据与解析
  4. android监听器作用,android - 监听器和接收器(Android)有什么区别?
  5. OpenGL(三)——OpenGL着色器基础
  6. UI设计案例|文件管理App界面设计灵感
  7. pip/pip3 install 报错 “Could not find a version that satisfies the requriement xxx” 的解决方法
  8. 系统学习机器学习之特征工程(三)--稀疏特征之FM算法
  9. java ArrayList扩容入门
  10. SpringBean生命周期详解
  11. 软件测试界的三无简历,企业拿什么来招聘你,石沉大海的简历
  12. editorMd插件的使用总结(包括开启图片上传及拖拉粘贴上传图片)
  13. word2010分页设置页眉
  14. nginx 区分手机浏览器和pc浏览器
  15. vue提示Named Route ‘News‘ has a default child route. When navigating to this named route...问题
  16. 基于Android的校园二手交易平台App
  17. 批量将多个文件夹整理合并到一个文件夹中
  18. Blender基础:多边形建模中F命令和J命令的区别
  19. 2018年6月8日 星期五 天气晴
  20. 医疗实施-MDM主数据管理基本介绍

热门文章

  1. 在Visual C++ 中使用内联汇编
  2. 全网唯一的Microsoft?NETFramework3?5SP1简体中文完整版离线安装包安装netframewo
  3. 软件架构阅读笔记15
  4. noip模拟题 ----飞
  5. [转]删除MSSQL所有的约束及表格
  6. poj 3468 线段树
  7. 我的四年建站故事(X)
  8. 无法安装或运行应用程序。该应用程序要求首先在“全局程序集缓存(gac)”中安装程序集system.data.entity...
  9. GPS及惯性传感器在无人驾驶中的应用
  10. “无中生有”计算机视觉探奇