解一元二次方程

本文介绍了如何使用Java和C/C++编程语言实现解一元二次方程的功能。核心思路是利用公式法,同时考虑了方程无解、有理数和无理数解的情况。文章提供了代码示例,并强调了处理输入输出以及保留小数位的细节处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

前言

思路讲解

代码展示

java版本

注意事项

C/C++版本

注意事项


 

前言

对于一元二次方程,相信大家都不陌生,毕竟初中的时候就熟悉了。但是,解一元二次方程确实一个苦差事,毕竟真正在高中和大学中出现的那些方程都不是考官有意设的,也就是说它们很有可能是一个无限不循环小数,这样一来解它们就需要浪费很多不必要的时间。于是,程序员们就开始寻思着让计算机来代替人们计算。现在,解一元二次方程这个功能几乎每个计算器里头都有,我们今天就了解一下这个功能的原理,以及如何实现使用该功能一秒解出一元二次方程。我们这次演示的是java语言。

思路讲解

首先该程序的核心思想就是利用公式法解一元二次方程。公式法是:x=[-b±sqrt(b^2-4ac)]/(2a),其中sqrt()表示的是根号下。根据这个公式我们可以得到一元二次方程的解。该公式事实上揭示的是方程系数与根的关系。那我们根据这个我们就有了一个基本构思:向用户要一个一元二次方程的各项系数,然后返回解给用户。

这就完了么?理论上来说是的。但是,在用户实际使用的时候,还会有诸多不便。比如。有些一元二次方程没有解。因为sqrt()内的结果可能为负,而我们都知道,二次根号下的数是不能为负的(我们默认数都在实数范围),所以,我们还要给程序添加一个判断方程是否有解的一些语句。

除此以外,在实际使用上,我们会发现,有一些讨厌的一元二次方程的两个解都是无理数,而大多用户又不需要小数点后那么多位。你说,我们可以让用户自己约!可惜的是,没有用户有时间使用这种麻烦的代码,尤其是他今晚有100道题要写的时候。于是,我们要新添加一个功能,即,在用户输入完系数后,询问用户需要约到小数点后几位,并编写相应的方程。可是,有时候用户懒得写了,怎么办呢?我们再添加一个新功能:如果他不想写保留位,就可以选择按下换行键跳过这一步,直接显示结果。你瞧,这不就就舒服多了。

不过事实上,这个程序还有很多地方需要修改,比如静态方法quadraticSolution()中好像有些地方重复了。大家也可以试着扩充该程序,比如支持拍100道一元二次方程题的照,然后一键返回所有题目的答案。

代码展示

java版本

package ELEM;//一个语法,说明该程序所在的包叫ELEM
//以下四行导入库
import java.io.BufferedReader;//我们会用该库读取缓冲器中数据
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;//实现输入功能的必备库

public class Quadratic {
	public static double[] quadraticSolution(double a, double b, double c) {
		double[] arr = new double[2];//初始化double类型的数组
		if((b*b-4*a*c)>=0) {//判断方程有解的条件:delta大于0。我们会说明原因的
			arr[0]=(-b+Math.sqrt(b*b-4*a*c))/(2*a);//第一个解
			arr[1]=(-b-Math.sqrt(b*b-4*a*c))/(2*a);//第二个解
			return arr;
		}
		else {
			return arr;//方程无解的返回值
		}
	}
	public static double correctTo(double data,int dec) {
		int num=(int)Math.pow(10.0,dec);//实现的效果是10.0^dec
		return Math.ceil(data*num)/num;//四舍五入
	}
	public static void main(String[] args) throws IOException {
		Scanner input=new Scanner(System.in);
		BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
		System.out.println("enter all the coefficients of this formula: a, b, c:");
        //以下几行为一元二次方程各个项的系数:a, b, c
		double a=input.nextDouble();
		double b=input.nextDouble();
		double c=input.nextDouble();
		double[] result=Quadratic.quadraticSolution(a, b, c);
	
		if(result[0]==result[1]==0.0 &&(b!=0 || c!=0)) {//方程无解的情况
			System.out.println("it has no solution");
		}
		else {
			System.out.println("correct to which decimal(press enter to skip this part):");
			String str = "";//初始化并给读取器赋值
			str = bf.readLine();
			if (str.length() != 0) {
				int dec=Integer.parseInt(str);//类型转换String->int
				for(int j=0;j<result.length;j++) {
					result[j]=Quadratic.correctTo(result[j], dec);//保留小数位
				}
			}
			if(result[0]==result[1]) {//当方程有一个根
				System.out.println("x="+result[0]);
			}else {//当方程有两个根
				for(int i=0;i<result.length;i++) {
					System.out.println("x"+(i+1)+"="+result[i]);
				}
			}
		}	
	}
}

注意事项

这里有需要注意的点。1.在main函数中if判断方程无解的情况。当一个方程两个根都是0的时候,好像方程就无解了?错!方程x^2=0有解。虽然我们很确信,没有一个人会这样输入,但是为了确保程序结果的严谨性,我们还是要加两个条件来判断方程真的无解,即:系数b为0或c不为0。我们可以看到,这其实是一种比较鸡肋的判断方法,使用了纯数学方法判断。

第二点,大家可以看到BufferReader登场了。我们从他的名字就很容易判断出,他是专门用来读取缓存区中的数据的。但是在我们按下回车键“\r"解除阻塞状态后,他就无法获取到信息,在程序中体现为str.length()==0。当str长度不为0时,我们可以确信,用户一定输入了想要保留的小数位,而这信息储存在str中,为String类型。因此我们在把该数据赋值给dec之前,还需要通过Integer类中的parseInt()静态方法给该信息做一个类型转换——从String类型转为int类型。

第三点,大家注意到correctTo函数了么?他是用来保留小数位的。回忆一下,我们一般遇到这种情况是怎么做的?比如用户要保留2位小数。我们假设该方程只有一个根,是2.62782102。此时我们需要对第三位小数7进行四舍五入判断,结果得到是2.63。java中只有Math.ceil()支持四舍五入,可问题是他只支持一位小数的!那怎么办呢?很简单,我们可以给原数乘上10^2得到262.782102。现在就转换成约一位小数的问题了,交给Math.ceil()静态方法解决,得到263.0。接下来就很简单了,我们把263.0除以10^2即可的到结果,大功告成!

C/C++版本

#include<stdio.h>
#include<math.h>
#include<memory.h>
//this program output the solution to any quadraticEquation
double* solution(double a, double b, double c) {//formula
    static double arr[2];
    double delta = b * b - 4.0 * a * c;
    if (delta >= 0.0) {
        arr[0] = (-b + sqrt(delta)) / (2.0 * a);//one root of the equation
        arr[1] = (-b - sqrt(delta)) / (2.0 * a);//another root of the equation
        return arr;//get address
    }
    else {
        return arr;//the condition in which equation has no solution
    }
}
double roundToDec(double data, int dec) {//correct root to dec decimal places
    int num = (int)pow(10, dec + 1);
    int integer = (int)(data * num);
    if (integer % 10 >= 5) {//rounding
        return (double)(integer + 10) / num;
    }
    else {
        return (double)integer / num;
    }
}
int main() {
    double a, b, c;
    int dec;
    printf("enter coefficient a,b,c of this formula:");
    //get user input of coefficient
    scanf("%lf", &a);
    getchar();//cancel out blocking status
    scanf("%lf", &b);
    getchar();
    scanf("%lf", &c);
    double* roots = solution(a, b, c);//receive solution array from function

    if (roots[0] ==0.0 && roots[1] == 0.0) {//has no solution
        printf("it has no solution");
    }
    else {
        printf("correct to which decimal:");
        getchar();
        scanf("%d", &dec);
        for (int i = 0; i < 2; i++) {
            roots[i] = roundToDec(roots[i], dec);
        }
        if (roots[0] == roots[1]) {// has only one root
            printf("x=%lf", roots[0]);
        }
        else {
            for (int j = 0; j < 2; j++) {//has two roots
                printf("x%d=%lf\n", j + 1, roots[j]);
            }
        }
    }
    //system("pause");
    return 0;
}

注意事项

这里有几点需要注意的。首先,大家一定一定要注意一下这里的类型的变换,尤其是新学C语言不久的读者,类型出了问题通常是比较讨厌的,因为C语言编译器不会提醒你是类型的问题,他会伪装成一个逻辑错误,要你自己debug发现。所以类型一定是代码检查的重中之重。像这里的roundToDec()方程我就不说了,在Java中已经把思路捋的七七八八了。

这里大家看到连续scanf()那里,中间插了几个getchar()。这里涉及到了部分scanf()的工作原理,因此我简单的解释一下。打个比方,我们一般洗衣服,都会集满一桶脏衣服再去放进洗衣机,这样方便且更有效率。scanf()也是这样。在你输入时且没有按下回车键之前,你的输入会储存到缓存区,此时程序进入阻塞状态,就是直到你按下回车程序才继续运行。不过这一切有一个前提,就是输入前缓存区为空,否则下一个scanf()直接清空缓存区。而在你输入回车后,回车符"\r"会留在缓存区中,这样下次scanf()拿到的就是"\r"。所以我们要用getchar()把"\r"拿走先。

 

### C++ 实现一元二次方程一元二次方程 \( ax^2 + bx + c = 0 \) 中,通过计算判别式 Δ 的值来判断方程的根情况。具体来说: - 当 Δ > 0 时,方程有两个不同的实根; - 当 Δ = 0 时,方程有两个相同的实根; - 当 Δ < 0 时,方程有两不同虚根。 以下是使用 C++ 编写的求一元二次方程的代码示例[^2]: ```cpp #include <iostream> #include <cmath> using namespace std; int main() { double a, b, c; cout << "请输入三个浮点数 a, b, c (以空格分隔): "; cin >> a >> b >> c; // 计算判别式 double delta = b * b - 4 * a * c; if (delta > 0) { // 方程有两个不同的实根 double root1 = (-b + sqrt(delta)) / (2 * a); double root2 = (-b - sqrt(delta)) / (2 * a); cout << "方程有两个不同的实根:" << endl; cout << "root1 = " << root1 << ", root2 = " << root2 << endl; } else if (delta == 0) { // 方程有两个相同的实根 double root = -b / (2 * a); cout << "方程有两个相同的实根:" << endl; cout << "root = " << root << endl; } else { // 方程有两个共轭复根 double realPart = -b / (2 * a); double imaginaryPart = sqrt(-delta) / (2 * a); cout << "方程有两个共轭复根:" << endl; cout << "root1 = " << realPart << " + " << imaginaryPart << "i" << endl; cout << "root2 = " << realPart << " - " << imaginaryPart << "i" << endl; } return 0; } ``` 此程序会提示用户输入三个系数 `a`、`b` 和 `c`,并根据这些系数计算出相应的一元二次方程。对于每种可能的情况——两个不相等的实根、一个重根以及一对共轭复根——都提供了相应的处理逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值