일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 자바스크립트심화
- 컴퓨터비전
- 중학수학
- 컴퓨터구조
- 자바 실습
- 디버깅
- JSP
- 자바스크립트
- JSP/Servlet
- 데이터분석
- CSS
- 딥러닝
- 파이썬
- 혼공머신
- ChatGPT
- 개발일기
- html/css
- rnn
- 중학1-1
- 정보처리기사필기
- SQL
- 연습문제
- JDBC
- c언어
- 상속
- 정보처리기사실기
- 자바
- 데이터베이스
- 머신러닝
- 순환신경망
- Today
- Total
클라이언트/ 서버/ 엔지니어 "게임 개발자"를 향한 매일의 공부일지
[Spring반] 중간시험 10 - Java 실기 시험 및 문제 풀이 2 : 문제 3번 <사칙연산 계산기> 본문
[Spring반] 중간시험 10 - Java 실기 시험 및 문제 풀이 2 : 문제 3번 <사칙연산 계산기>
huenuri 2024. 12. 9. 08:36이 문제를 풀다가 아마 졸려서 취침하게 될 것 같다. 풀 수 있는 데까지 풀고 다음날 아침에 일어나서 하면 된다. 이제 3번 문제부터 풀어보겠다.
Java 실기 시험 두 번째
문제 3번
두 개의 정수를 입력받은 후 입력한 연산자에 따라 연산결과가 나오는 프로그램을 작성하시오.
방법 1 - 클래스 하나로 작성하기
코드 설명
- 입력값 처리
- Scanner를 사용해 두 정수와 연산자를 입력받음
- 연산자는 next().charAt(0)을 사용하여 첫 번째 문자만 처리
- 연산자에 따른 분기
- switch-case를 사용해 입력된 연산자에 따라 연산을 수행
- 기본 값(default)으로는 잘못된 연산자 입력에 대해 오류 메시지 출력
- 나눗셈 처리
- 나눗셈의 경우, 0으로 나누는 오류를 방지하기 위해 조건문(if) 추가
- 결과를 실수(double)로 처리하여 정확한 계산 수행
- 프로그램 안정성
- 모든 입력과 연산에 대해 예외 상황을 처리하여 프로그램이 중단되지 않도록 설계
방법 2 - 클래스를 나누어서 작성하기 + 새로운 연산자 추가하기
이 방법은 솔직히 많이 어려워서 푸는데 시간이 많이 걸리고 코드 오류가 많이 났다.
코드 구조
- Operations 클래스
- 연산 메서드(덧셈, 뺄셈, 곱셈, 나눗셈)를 정의
- 모든 메서드는 static으로 선언하여, 인스턴스 생성 없이 직접 호출 가능
- Calculator 클래스
- 사용자 입력을 처리하고, 입력된 연산자를 기반으로 ArithmeticOperations 클래스의 메서드를 호출
장점
- 코드의 역할 분리
- Operations 클래스는 연산 기능만 담당
- Calculator 클래스는 사용자 입력과 프로그램 흐름 제어를 담당
- 유지보수 용이
- 연산 로직에 변경이 필요하면 Operations 클래스만 수정하면 됨
- 확장성
- 새로운 연산(예: 나머지 %, 제곱 ^)을 추가할 때, Operations에 메서드를 추가하고 switch문에 추가하면 쉽게 확장 가능
% 연산자를 사용했을 때 소수형이 아닌 정수형으로 반환되도록 만들고 싶어졌다.
방법 3 - 나머지 연산자만 정수형으로 반환하기
네 가지 연산 외에 % 연산자를 한번 추가했다. 그리고 정수형으로 받기 위해 반환값을 바꾸었지만 형 변환을 할 때 계속 오류가 뜨는 문제가 발생했다.
오류가 발생하는 이유는 modulo 메서드가 int 타입을 매개변수로 받도록 설계되었지만, 호출 시 num1과 num2가 double 타입으로 전달되었기 때문이다. double 값을 int로 변환하지 않으면, modulo 메서드와 호출 간의 타입 불일치로 인해 컴파일 오류가 발생한다.
해결 방법
1. modulo 메서드의 매개변수 타입을 double로 변경
- 메서드 호출 시 타입 변환 없이 사용할 수 있도록 modulo 메서드의 매개변수를 double로 변경
public static double modulo(double a, double b) {
return a % b;
}
2. 호출하는 쪽에서 명시적 형변환
- modulo 메서드의 매개변수를 그대로 int로 유지하려면, 호출하는 쪽에서 전달값(num1, num2)을 int로 명시적 형변환
case '%':
result = Operations.modulo((int) num1, (int) num2); // 명시적 형변환
System.out.println("연산 결과: " + result);
break;
각 방법의 차이점
방법 | 장점 | 단점 |
메서드 매개변수를 double로 변경 | int와 double 모두 처리 가능. 추가 변환 없이 다양한 타입에 대해 유연하게 동작 | 나머지 연산이 double로 수행되므로, 값이 소수점까지 포함될 수 있음 |
명시적 형변환 추가 | 나머지 연산을 항상 int 타입으로 제한. 결과 값이 정수로 보장됨 | 호출하는 모든 코드에서 형변환이 필요. 입력값 손실 가능성(소수점 이하 절삭) |
이렇게 코드를 수정한 후 실행해보았다.
하지만 이렇게 수정해도 정수형으로 나오지 않았다. 결과값을 int형으로 받도록 코드를 따로 작성해 주었다.
코드 수정하기
이제 정수형으로 잘 출력된다.
하지만 나눗셈을 할 때 소수점 첫째 자리까지만 나오도록 만들고 싶다.
방법 4 - 나눗셈 연산 시 소수점 첫째 자리까지만 출력하도록 하기
나눗셈 결과를 소수점 첫째 자리까지만 출력하려면 **printf**를 사용하거나 DecimalFormat 클래스를 활용할 수 있다.
1. printf를 사용하는 방법
printf는 포맷을 지정하여 출력할 수 있는 간단한 방법이다.
case '/':
if (num2 != 0) {
result = Operations.divide(num1, num2);
System.out.printf("연산 결과: %.1f\n", result); // 소수점 첫째 자리까지 출력
} else {
System.out.println("0으로 나눌 수 없습니다.");
}
break;
2. DecimalFormat을 사용하는 방법
DecimalFormat 클래스는 숫자를 원하는 형식으로 포맷팅할 때 사용돼.
import java.text.DecimalFormat;
// 나눗셈 케이스
case '/':
if (num2 != 0) {
result = Operations.divide(num1, num2);
DecimalFormat df = new DecimalFormat("#.0"); // 소수점 첫째 자리까지 포맷
System.out.println("연산 결과: " + df.format(result));
} else {
System.out.println("0으로 나눌 수 없습니다.");
}
break;
하지만 이때 주의할 점은 result를 반환할 때 문자열 결합 연산자를 사용해서는 안된다. 만약 사용 시 이러한 오류가 뜬다.
printf는 형식 지정자를 사용한 출력 메서드인데, 문자열 결합(+)과 함께 사용할 수 없다. System.out.printf에서 형식 지정자와 값을 따로 전달해야 한다.
이제 전체 코드를 올려보면 다음과 같다.
전체 코드
이제 드디어 해결했다. 이 문제 하나 푸는데 1시간 반도 넘게 걸렸다.
학습을 마치고
오늘 새벽에 2시쯤 문제를 풀어보려다가 문제만 써놓고 아침 7시에 일어나서 다시 풀어보았다. 이 문제는 혼자서 풀기는 어려워서 자료를 참고하며 풀었다. 그리고 여러 가지 방법을 연구하며 이제 드디어 내 마음에 드는 코드로 완성했다. 이렇게 코드를 수정하며 만들어가는 과정이 즐겁다.
비록 힘들기는 했으나 수십 번 코드를 수정하며 정말 많은 것들을 배울 수 있었다.