이 페이지는 코딩도장 데이터의 읽기 전용 정적 보관본입니다.

2차방정식(근의 공식 미사용) 값 구하기

앞쪽 문제에 근의 공식을 이용하는 문제가 있더라구요. 근의 공식을 사용하지 않고, 값을 구하세요. (근사값이라고 하나요, 그러면 3차 이상 방정식 값을 구하는 것도 어렵지 않겠죠.)

a X^2 + b X + C = 0

에서 a, b, c의 값을 입력 받으세요. (-10 <= a, b, c <=10인 정수). 범위를 넘어가거나, 문자가 입력되면 다시 받도록 하세요.

[결과] 값이 2개이면 2개 출력, 1개이면 1개 출력, 0개이면 0에서 가장 가까운 X값을 출력하세요. 값 아래에 비교가 되도록, "근의 공식으로 구한 값은 000, 000 (2개일 경우)입니다."를 출력하세요. 값은 소수 2자리까지 표현해 주세요.

trial and error

2020/06/10 10:16

Stony Lee

10개의 풀이가 있습니다.

2차 함수는 아주 간단한 형태의 볼록함수이므로 간단한 수치해법으로 계산하게 해봤습니다.

먼저, f'(x) = 0이 되는 x값을 찾아 그 함수값과 a(2차항 계수)이 부호를 비교하여 근의 개수를 구합니다. 근의 개수가 0개이거나 1개인 경우, f'(x) = 0이 되는 x의 값이 문제에서 원하는 값이므로 곧바로 출력합니다. 근의 개수가 2개인 경우, 다음과 같은 수치해법으로 근을 계산합니다.

  1. f'(x)=0이 되는 x값으로부터 양쪽으로 적당히 떨어진 지점에 초기치를 둡니다.
  2. 해당 점에서 접선을 그어, 그 접선이 x축과 만나는 점을 다음 반복점의x값으로 둡니다.
  3. 반복점이 x축에 만족할만큼 가까워지면(이번 풀이에서는 이터레이션 종료 기준을 1.00e-6으로 뒀습니다) 반복을 종료하고, 공식 대입으로 얻어진 값과 비교합니다.
import math

def sol(a, b, c, initial) : # 수치해 계산

    the_number_of_iteration = 0
    pos = [initial, a*(initial)**2+b*(initial)+c]
    next_pos = [0, 0]

    print("INITIAL POINT : (%f, %f)\n" %(pos[0], pos[1]))

    while True :
        the_number_of_iteration += 1
        print("-"*10+"ITERATION %d" % the_number_of_iteration+"-"*10)
        next_pos[0] = ((-pos[1])/(2*a*pos[0]+b)) + pos[0]
        next_pos[1] = a*(next_pos[0])**2 + b*(next_pos[0]) + c

        pos = [next_pos[0], next_pos[1]]

        print("next_pos = (%f, %f)\n" %(next_pos[0], next_pos[1]))

        if abs(pos[1]) <= 1.00e-6 : # 종료조건
            return (pos[0], pos[1])

    return 0

def cen(a2, b2, c2) :  #f'(x) = 0이 되는 값 계산, 근 계수 확인
    j = (-b2)/(2*a2) 
    f_j = (a2*j)**2+(b2*j)+c2

    if a2*f_j > 0 : return (0, j)
    elif  f_j == 0 : return (1, j)
    else : return (2, j)


def equa_solver(a3, b3, c3) :
    r = cen(a3, b3, c3)
    if r[0] == 0 : 
        print("No solution.")
        return r[1]
    elif r[0] == 1 : 
        return print(r[1])
    else :
        D = math.sqrt((b3**2)-4*a3*c3)
        x_1_2 = sorted([(-b3-D)/(2*a3), (-b3+D)/(2*a3)])
        numerical = [sol(a3, b3, c3, r[1]-1)[0], sol(a3, b3, c3, r[1]+1)[0]]
        print("Numerical solution : ", "(", numerical[0],",", numerical[1], ")")
        print("(", x_1_2[0],", ", x_1_2[1], ")")
        return print("error : ", abs(numerical[0]-x_1_2[0]), abs(numerical[1]-x_1_2[1]))

if __name__ == "__main__" :

    in_a, in_b, in_c = 0, 0, 0
    while True :
        try :

            in_a, in_b, in_c = map(int, input("INPUT : ").split())
            if (-10<=in_a<=10) and (-10<=in_b<=10) and (-10<=in_c<=10) :
                equa_solver(in_a, in_b, in_c)
                break
            else : continue
        except :
            print("ERROR")
            break

결과

INPUT : -1 8 -9
INITIAL POINT : (3.000000, 6.000000)

----------ITERATION 1----------
next_pos = (0.000000, -9.000000)

----------ITERATION 2----------
next_pos = (1.125000, -1.265625)

----------ITERATION 3----------
next_pos = (1.345109, -0.048448)

----------ITERATION 4----------
next_pos = (1.354233, -0.000083)

----------ITERATION 5----------
next_pos = (1.354249, -0.000000)

INITIAL POINT : (5.000000, 6.000000)

----------ITERATION 1----------
next_pos = (8.000000, -9.000000)

----------ITERATION 2----------
next_pos = (6.875000, -1.265625)

----------ITERATION 3----------
next_pos = (6.654891, -0.048448)

----------ITERATION 4----------
next_pos = (6.645767, -0.000083)

----------ITERATION 5----------
next_pos = (6.645751, -0.000000)

Numerical solution :  ( 1.3542486888886305 , 6.645751311111369 )
( 1.3542486889354093 ,  6.645751311064591 ) #공식으로 구해진 값
error :  4.677880305337112e-11 4.6778581008766196e-11  # 오차

위의 예에서는 각 해당 5번의 반복, 총 10번의 계산으로 공식에서 구해진 값에 가까운 값이 구해졌습니다.

2020/06/15 17:21

GG

이차함수 f(X)에 대해 f'(X) = 0 인 변곡점 Xi를 찾은 후, f(Xi) * 계수 A의 부호에 따라 해의 개수를 판단.

해가 두 개일 경우,

Xi를 기준으로 X값을 증가시켜 가면서 f(X)의 부호가 '양>음' 또는 '음>양'으로바뀌는 구간의 X 값이 해.

Xi를 기준으로 대칭된 위치의 X값이 또하나의 해.

C#

using System;

namespace CD252
{
    class Program
    {
        static void Main()
        {

            int a = GetInput("A");
            int b = GetInput("B");
            int c = GetInput("C");
            Equation eq = new Equation(a, b, c);
            Equation.EqType numRoots = eq.SolveEquation(out double rootA, out double rootB);
            _ = eq.SolveEquationByFormula(out double rootAF, out double rootBF);
            Console.WriteLine($"근의 개수: {numRoots}");
            if (numRoots == Equation.EqType.TwoRoots)
            {
                Console.WriteLine($"근사치로 구한 근은 {rootA}, {rootB}이며,");
                Console.WriteLine($"근의 공식으로 구한 근은 {rootAF}, {rootBF}입니다.");
            }
            else if (numRoots == Equation.EqType.OneRoot)
            {
                Console.WriteLine($"근사치로 구한 근은 {rootA}이며,");
                Console.WriteLine($"근의 공식으로 구한 근은 {rootAF}입니다.");
            }
            else
            {
                Console.WriteLine($"0에 가장 가까운 X값은 {rootA}입니다.");
            }
        }

        static int GetInput(string varName)
        {
            bool foo = false;
            int parsedValue = int.MaxValue;
            while (!foo || parsedValue < -10 || parsedValue > 10)
            {
                Console.Write($"계수 {varName}의 값을 입력하세요(단, -10 <= 변수(정수) <= 10): ");
                foo = int.TryParse(Console.ReadLine(), out parsedValue);
            }
            return parsedValue;
        }
    }

    // 좌표를 나타내는 구조체
    struct Pos
    {
        public double X, Y;

        public Pos(double x, double y)
        {
            this.X = x;
            this.Y = y;
        }
    }

    // 방정식을 나타내는 클래스
    class Equation
    {
        private int _A, _B, _C;

        private Pos _Inflection; // 변곡점의 좌표

        private double GetFuncValue(double x) // x에 대한 함수의 값 계산
        {
            return _A * x * x + _B * x + _C;
        }

        public Equation(int a, int b, int c)
        {
            (_A, _B, _C) = (a, b, c);

            // 2차 함수 f(x)에 대해 변곡점을 구하면, 
            // f'(x) = 2 A x + B = 0  ==> x = -B / (2 A)
            double fooX = -_B / (2.0 * _A);
            _Inflection = new Pos(fooX, GetFuncValue(fooX));
        }

        // 주어진 방정식 인스턴스의 해를 구함 (근사)
        public EqType SolveEquation(out double rootA, out double rootB)
        {
            rootA = default;
            rootB = default;

            EqType numberOfRoots; // 근의 개수

            // 근의 개수 판단
            switch (_Inflection.Y)
            {
                case double d when d == 0:
                    numberOfRoots = EqType.OneRoot;
                    rootA = _Inflection.X; // 근이 하나인 경우 변곡점
                    break;
                case double d when d * _A < 0:
                    numberOfRoots = EqType.TwoRoots;
                    break;
                default:
                    numberOfRoots = EqType.NoRoot;
                    rootA = _Inflection.X; // 근이 없는 경우 0에 가장 가까운 값
                    break;
            }

            // 근이 두 개인 경우 trial-error로 근 구함
            if (numberOfRoots == EqType.TwoRoots)
            {
                // X좌표값을 변곡점을 기준으로 epsilon만큼 증가시켜 가면서
                // Y값이 음->양 또는 양->음 되는 점(해)을 찾음
                // 변곡점을 기준으로 대칭된 반대의 위치에 있는 점이 또 다른 해임
                double epsilon = 0.0001;
                double prevX = _Inflection.X; // 이전 X좌표
                double tryX = _Inflection.X + epsilon; // 시도할 X좌표
                while (GetFuncValue(prevX) * GetFuncValue(tryX) > 0)
                {
                    tryX += epsilon;
                }
                rootA = tryX;
                rootB = _Inflection.X - (tryX - _Inflection.X);
            }

            return numberOfRoots;
        }

        // 주어진 방정식 인스턴스의 해를 구함 (근의 공식)
        public EqType SolveEquationByFormula(out double rootA, out double rootB)
        {
            rootA = default;
            rootB = default;

            EqType numberOfRoots;
            double checkFormula = _B * _B - 4.0 * _A * _C;
            if (checkFormula > 0)
            {
                numberOfRoots = EqType.TwoRoots;
                rootA = (-_B + Math.Sqrt(checkFormula)) / (2.0 * _A);
                rootB = (-_B - Math.Sqrt(checkFormula)) / (2.0 * _A);
            }
            else if (checkFormula == 0)
            {
                numberOfRoots = EqType.OneRoot;
                rootA = -_B / (2.0 * _A);
            }
            else
            {
                numberOfRoots = EqType.NoRoot;
            }

            return numberOfRoots;
        }

        public enum EqType // 근의 개수를 나타내는 열거형
        {
            NoRoot,
            OneRoot,
            TwoRoots
        }
    }
}

2020/06/10 23:27

mohenjo

2차원 함수의 꼭지점을 미분으로 구하지 않고, 근사치 입력값의 범위를 -1000.000에서 1000.000까지 0.001 단위로 입력해서, 값이 + - 가 변경되거나, 0이 되는 값을 구했습니다. 200만번 계산하느라 컴이 잠깐 쉬네요. (a, b, c 값이 한정되서 실제로는 -20.000 에서 20.000 이내로 가능은 합니다. 코드내 t = 1000000으로 했는데, 20000으로 고쳐서 돌리면 컴이 쉬지 않고 똑같은 답을 내놓습니다.)

방정식의 해가 없을 경우, 절대값이 0에 가장 가까운 값을 잡았습니다. 이 경우 200만번을 한 번 더 돌리느라 한 번 더 잠깐 쉬네요.

이런 방법으로 하면 3차 이상의 방정식도 구할 수 있습니다.

print("a*X^2 + b*X + c = 0")
while True:
    try:
        a = int(input("input integer for a from -10 to 10 : "))
        b = int(input("input integer for b from -10 to 10 : "))
        c = int(input("input integer for c from -10 to 10 : "))
        if a>=-10 and a<=10 and b>=-10 and b<=10 and c>=-10 and c<=10:
            break
    except ValueError:
        print("That was no valid number.  Try again...")

t = 1000000
x1 = t/100
x2 = t/100
flag = 0

for i in range((0-t), t):
    n = float(i / 1000)
    y_c1 = a * n**2 + b * n + c
    y_c2 = a * (n+0.001)**2 + b * (n+0.001) + c
    if y_c1 == 0:
        x1 = n
        break
    elif (y_c1 < 0 and y_c2 > 0) or (y_c1 > 0 and y_c2 < 0):
        x1 = n
        break
if x1 != t/100:
    for j in range(int((n+0.001)*1000), t):
        n = float(j / 1000)
        y_c1 = a * n**2 + b * n + c
        y_c2 = a * (n+0.001)**2 + b * (n+0.001) + c
        if y_c1 == 0:
            x2 = n
            break
        elif (y_c1 < 0 and y_c2 > 0) or (y_c1 > 0 and y_c2 < 0):
            x2 = n
            break
elif x1 == t/100:
    y = float(a * (t/100)**2 + b * t/100 + c)
    for i in range((0-t), t):
        n = float(i/1000)
        y_c1 = a * n**2 + b * n + c
        if abs(y_c1) < abs(y):
            x1 = n
            y = y_c1
            flag = 1
        else:
            x1 = x1
print()
if x2 == t/100 and flag != 1:
    print("x = {}".format(round(x1,2)))
    print()
    if a != 0:
        print("근의 공식값 : ",round(((0-b)-(((b**2)-4*a*c)**0.5))/(2*a),2)," ,  ", round((((0-b)+(((b**2)-4*a*c)**0.5))/(2*a)),2))
    print()
elif x2 == t/100 and flag == 1:
    print("0에 가장 가까운 값 x = {}".format(round(x1,2)))
    print("{}를 x에 입력해서 계산하면 나오는 값 : {}".format(round(x1,2),round((a*(x1**2) + b*x1 + c),2)))
else:
    print("x1 = {}, x2 = {}".format(round(x1,2), round(x2,2)))
    print()
    if a != 0:
        print("근의 공식값 : ",round(((0-b)-(((b**2)-4*a*c)**0.5))/(2*a),2)," ,  ", round((((0-b)+(((b**2)-4*a*c)**0.5))/(2*a)),2))
print()

2020/06/12 16:41

Stony Lee

무식하게 풀었습니다.

파라미터 조정을 더 해야하는 거 같은데 더 손대기가 귀찮아서...

from math import sqrt


# 근의 공식 사용
def calc(a, b, c):
    dsc = b * b - 4 * a * c
    return set() if dsc < 0 else {
        round((-b + sqrt(dsc)) / (2 * a), 2),
        round((-b - sqrt(dsc)) / (2 * a), 2)
    }


# (1) 변곡점에서 시작해서 x값을 delta 만큼 증가시킴
# (2) x축을 넘어가면 delta 크기를 줄여서 반대방향으로 진행, y값이 threshold 보다 작아지면 리턴
def estim(a, b, c):
    def y_of(x):
        return a * x * x + b * x + c

    delta = 1 / a      # 곡선이 가파를수록 좁게 진행
    th = min(a, 0.1)  # delta와 반대

    cx = b / (-2 * a)
    x, y = cx, y_of(cx)
    py = y

    while abs(y) >= th: # ......(2)
        while not(py < 0 <= y or y <= 0 < py):   # ......(1)
            x += delta
            py, y = y, y_of(x)
            # print(x, y, delta); input()

        py = y + delta # 무한루프 방지
        delta = -(delta / 10)

    return {round(x, 2), round(cx - (x - cx), 2)}


a, b, c = map(int, input().split())
print("근의 공식 => ", *calc(a, b, c))
print("추정 => ", *estim(a, b, c))

2020/07/11 18:06

Noname

import numpy as np

class QuadraticEquationSolver:
    """Approximate only a quadratic equation by Newton's method.
    Return the number of solution and the solution(s).

    a: The coefficient of the 2th degree term. Can not be zero.
    b: The coefficient of the 1th degree term.
    c: The coefficient of the constant term.

    Example

    a = 1
    b = 2
    c = 1

    qes = QuadraticEquationSolver(a, b, c)
    solutions = qes.result()
    print('Solution(s): {}'.format(solutions))
    print('근의 공식으로 구한 값은 {}입니다.'.format(qes.numpy_solver()))"""

    def __init__(self, a, b, c):
        for n in [a, b, c]:
            assert type(n) is int and -10 <= n <= 10, '-10, 10 사이의 정수를 입력해주세요.'
        self.a = a
        assert self.a != 0, '2차 항의 계수는 0이 될 수 없습니다.'
        self.b = b
        self.c = c
        self.xm = - b / 2 * a

    def numpy_solver(self):
        """use to compare the results"""
        roots = np.roots([self.a, self.b, self.c])
        return roots

    def quadratic_function(self, x):
        f = self.a * pow(x, 2) + self.b * x + self.c
        return f

    def newton(self, x):
        fx = QuadraticEquationSolver.quadratic_function(self, x)
        while abs(fx) >= 1e-10:
            fx = QuadraticEquationSolver.quadratic_function(self, x)
            Dfx = 2 * self.a * x + self.b
            x = x - fx / Dfx
        return x

    def get2solutions(self):
        """Use to find the two different real number roots."""
        x1 = self.xm
        x2 = self.xm

        while QuadraticEquationSolver.quadratic_function(self, x1) < 0:
            x1 += 1
        while QuadraticEquationSolver.quadratic_function(self, x2) < 0:
            x2 -= 1    

        x1 = QuadraticEquationSolver.newton(self, x1)
        x2 = QuadraticEquationSolver.newton(self, x2)

        return (x1, x2)

    def result(self):
        """Arrange and return the final result"""
        solutions = []

        if self.a > 0:
            if QuadraticEquationSolver.quadratic_function(self, self.xm) >= 0:
                solutions.append(f'{self.xm:0.2f}')
                solutions.append(f'{self.xm:0.2f}')
            else:
                solutions.append(f'{QuadraticEquationSolver.get2solutions(self)[0]:0.2f}')
                solutions.append(f'{QuadraticEquationSolver.get2solutions(self)[1]:0.2f}')

        elif self.a < 0:
            if QuadraticEquationSolver.quadratic_function(self, self.xm) <= 0:
                solutions.append(f'{self.xm:0.2f}')
                solutions.append(f'{self.xm:0.2f}')
            else:
                solutions.append(f'{QuadraticEquationSolver.get2solutions(self)[0]:0.2f}')
                solutions.append(f'{QuadraticEquationSolver.get2solutions(self)[1]:0.2f}')

        return solutions


a = 1
b = 2
c = 1

qes = QuadraticEquationSolver(a, b, c)
solutions = qes.result()
print('Solution(s): {}'.format(solutions))
print('근의 공식으로 구한 값은 {}입니다.'.format(qes.numpy_solver()))    

2020/09/09 15:19

돈 벌면 뭐하노

python 3.9.1

def f(a, b, c, x):
    return a * pow(x, 2) + b * x + c
def diff(a, b, x):
    return 2 * a * x + b
def newton(a, b, c, x):
    return -1 * f(a, b, c, x) / diff(a, b, x) + x
a, b, c = map(int, input('Enter three intergers: ').split())
x = 0
num = 0
if a < 0:
    a *= -1
    b *= -1
    c *= -1
if f(a, b, c, -b / 2 / a) == 0:
    num = 1
    x = -b / 2 / a
elif f(a, b, c, -b / 2 / a) > 0:
    x = -b / 2 / a
else:
    num = 2
    while f(a, b, c, x) < 0:
        x += 1
    while abs(x - newton(a, b, c, x)) > 0.01:
        x = newton(a, b, c, x)
    x2 = -x - b / a
if num == 0:
    print('There is no soluiton. The closest point\'s x coordination is {}'.format(x))
elif num == 1:
    print('There is 1 solution. It is {}'.format(x))
else:
    print('There are 2 solutions. They are {} and {}'.format(x, x2))

뉴턴 랩슨법을 사용했습니다.

우선 최고차항의 계수가 음수일 경우 계산을 반대로 해야해서 복잡해지므로 -1을 곱해서 양수로 만들었습니다.

이후 -a/2b가 꼭짓점의 x좌표인 것을 이용해 이곳에서의 함숫값을 구합니다.

이 함숫값이 0보다 크면 해가 없고, 0이면 중근을 가지고, 0보다 작을 경우 2개의 해를 갖습니다.

해가 없는 경우와 중근인 경우는 해가 x = -a/2b에서 나오므로 각각 해가 몇개인지만 판단해 넘겨 줍니다.

뉴턴 랩슨법은 함수의 꼭짓점에서는 사용할 수 없기 때문에 x에 1을 계속 더해 함숫값이 0보다 커지도록 합니다.

왜냐면 함숫값이 음수일 때 뉴턴 랩슨법을 사용하면 양수로 가서 애초에 양수인 것이 계산량이 적기 때문입니다.

그렇게 해서 뉴턴 랩슨법을 반복하다가 오차가 0.001이하가 되면 그 값을 반환합니다.

이러면 꼭짓점 기준 오른쪽의 해를 구하게 됩니다.

이때 이차함수의 해가 꼭짓점 기준 좌우대칭인 것을 이용하면

x2 = x1 - b/a가 됨을 알 수 있습니다.

이를 이용해 2개의 해를 모두 구할 수 있습니다.

근데 저거 print 구문에서 format 함수 쓸때 소수점 2번째까지만 나오게 하는거 찾아봐도 모르겠던데 누가 알려주실분 없나요....

2021/01/21 23:55

김민수

근삿값을 구하지 않고 근과 계수의 관계를 이용하였습니다. 우선, 두 근을 m+루트n, m-루트n으로 나타냅니다. 다음으로, 2m = -b/a를 이용하여 m을 구합니다. (두 근의 합 = m+루트n+m-루트n = 2m = -b/a) 또한, m^2 - n = c/a를 이용하여 n을 구합니다. (두 근의 곱 = (m+루트n)(m-루트n) = m^2 - n = c/a) 여기에서 n의 부호로 실근, 허근, 중근을 결정할 수 있습니다. 마지막으로, 처음의 근 표기에 m과 n을 대입하면 됩니다. 이 방법은 수치해석이 아니므로 허근이 나오면 000을 출력하도록 했습니다. 이렇게 하면 근의 공식 없이 정확한 값을 구할 수 있습니다. 소스 코드입니다.

a = int(input('이차항의 계수를 입력하세요. '))
b = int(input('일차항의 계수를 입력하세요. '))
c = int(input('상수항의 계수를 입력하세요. '))

m = (-b/a) / 2
n = m**2 - c/a
if n < 0:
    print('000')
elif n == 0:
    print(round(m, 2))
else:
    print(round(m + n**0.5, 2), end=' ')
    print(round(m - n**0.5, 2))

d = b**2 - 4*a*c
print('근의 공식으로 계산하면...')
if d < 0:
    print('허근입니다.')
elif d == 0:
    print(int((-b + d ** 0.5) / (2*a)))
else:
    print(round((-b + d ** 0.5) / (2*a), 2), end=' ')
    print(round((-b - d ** 0.5) / (2*a), 2))

실행 결과입니다.

이차항의 계수를 입력하세요. 1
일차항의 계수를 입력하세요. 4
상수항의 계수를 입력하세요. 3
-1.0 -3.0
근의 공식으로 계산하면...
-1.0 -3.0

2021/06/25 17:59

이준우

while True:
  a, b, c = input().split(" ")
  a, b, c = float(a), float(b), float(c)
  if abs(a)<=10 and abs(b)<=10 and abs(c)<=10:
    break

if b**2-4*a*c ==0:
  print("한 개의 근", round(-0.5*b/a,2))
elif b**2-4*a*c<0:
  print("근이 없습니다")
else:
  x = -0.5*b/a
  y = a*x**2+b*x+c
  while True:
    x_next = x-0.001
    y_next = a*x_next**2+b*x_next+c
    x = x_next 
    if y*y_next <0:
      print(round(x,2))
      break
  while True:
    x_next = x+0.001
    y_next = a*x_next**2+b*x_next+c
    x = x_next 
    if y*y_next <0:
      print(round(x,2))
      break

2023/07/16 23:08

스탠리

using System;

namespace solution
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("이차방정식 a X^2 + b X + C = 0 의 a, b, c 의 값을 입력하세요.\n "+
                "  (-10 <= a, b, c <=10인 정수). 범위의 수를 입력하세요");
            decimal a=0, b=0, c=0;
            bool isOK = false;
            while (!isOK)
            {
                isOK = true;
                Console.Write("정수 a값을 입력하세요: ");
                a = decimal.Parse(Console.ReadLine());
                if (a < -10 || 10 < a || a == 0)
                    isOK = false;
                Console.Write("정수 b값을 입력하세요: ");
                b = decimal.Parse(Console.ReadLine());
                if (b < -10 || 10 < b)
                    isOK = false;
                Console.Write("정수 c값을 입력하세요: ");
                c = decimal.Parse(Console.ReadLine());
                if (c < -10 || 10 < c)
                    isOK = false;
                if(isOK == false)
                    Console.WriteLine("-10 <= a, b, c <=10인 정수로 다시 입력하세요(a는 0이 아니어야 함)!!");
                Console.WriteLine();
            }

            Console.WriteLine(solEquation(a, b, c));
        }

        private static string solEquation(decimal a, decimal b, decimal c)
        {
            if(a < 0)
            {
                a = -a;
                b = -b;
                c = -1;
            }
            decimal sX = -b / (2 * a);  //대칭축
            decimal value = a * sX * sX + b * sX + c;
            if (value == 0)
            {
                return "근이 한 개: " + value;
            }
            else if (value > 0)
                return "해가 없습니다..";
            else
            {
                decimal d = 1;
                decimal res = sX;
                while(d > 0.01m)
                {
                    res = findAns(res, d, a, b, c);
                    d = 0.1m * d;
                }
                res = Decimal.Round(res, 2);
                return 2 * sX - res + ", " + res;
            }
        }

        private static decimal findAns(decimal res, decimal d, decimal a, decimal b, decimal c)
        {
            decimal x = res;
            decimal v = a * x * x + b * x + c;

            while(v <= 0)
            {
                x += d;
                v = a * x * x + b * x + c;                
            }
            return x - d;
        }
    }
}

2023/07/18 17:02

insperChoi

def solv(x, d, a, b, c):
    val = a*x*x + b*x +c
    while val <= 0:
        x += d
        val = a * x * x + b * x + c
    return x - d

def solvFunction(a, b, c):
    if a < 0:
        a, b, c = -a, -b, -c

    X = -b / (2*a)
    cX = X
    val = a*cX*cX + b*cX + c
    if val == 0:
        print(' 중근: ', cX)
    elif val > 0:
        print(' 해가 없슴')
    else:
        d = 1
        while d > 0.01:
            cX = solv(cX, d, a, b, c)
            d = d * 0.1
        cX = round(cX, 2)

        print( cX, ', ', 2*X - cX)


while True:
    try:
        a, b, c = map(int, input('a, b, c의 값을 입력 하세요. (-10 <= a, b, c <=10인 정수).(예: 1 -2 -3): ').split( ))
        if (-10<=a<=10) and a!=0 and (-10<=b<=10) and (-10<=c<=10):
            solvFunction(a,b,c)
            break
        else:
            continue
    except :
        print(' 다시 입력하세요..')
        continue

2023/07/18 19:15

insperChoi

목록으로