TIL인데 가독성도없고 내가 뭘쓰는지 모르겠어서 짤같은거 넣으면서 아 그때 이랬지 하면서 리뷰에 도움이되게 하려고 노력해보겠다.......!!!!!!!!



레벨3계산기로 넘어오면서 내가 뭘 놓쳤는지 오류가 일어나야하지만 그냥 정의불가넝~! 하고 계산이 후룩되버린다..

멈춰!!!!!!!!!!!!!!!!!!!
..
참고로 레벨1,2 계산기에서는 0으로 나누려고할 때

이런식으로 막아뒀다

연산진행할 때 try-catch문을 써서 에러걸리면 에러메시지 출력이 되는데
레벨3도 동일한 방식으로 했는데도 잘 안된다
public void cacultate(CalculateValue calculateValueA, CalculateValue calculateValueB, OperatorType operator) {
//oper종류에 따라서 뭐...... 계산ㄱ하기
double a = calculateValueA.toDouble();
double b = calculateValueB.toDouble();
try{
switch (operator){
case ADD :
result = a+b;
resultStr = "더하기 계산 결과는 " + result + "입니다.";
savedResults.add(result);
break;
case SUBTRACT :
result = a-b;
resultStr = "빼기 계산 결과는 " + result + "입니다.";
savedResults.add(result);
break;
case MULTIPLY :
result = a*b;
resultStr = "곱하기 계산 결과는 " + result + "입니다.";
savedResults.add(result);
break;
case DIVIDE:
result = a/b;
resultStr = "나누기 계산 결과는 " + result + "입니다.";
savedResults.add(result);
break;
}
System.out.println(resultStr);
}catch (Exception e){
System.out.println("연산을 진행할 수 없어요. 에러를 확인해주세요 : " + e.getMessage());
}
}
이런식으로 사용했었음....

몰라서그냥 지피티의 힘을 빌렸다..

Java에서 double 타입을 사용할 때, 0으로 나누는 연산이 Infinity로 결과가 나오는 이유는 IEEE 754 부동소수점 표준에 따른 규칙 때문입니다. 이 표준은 실수의 표현과 연산에 대한 규칙을 정의하는데, double 타입도 이 표준을 따릅니다.
이 표준에서는 부동소수점 연산에서 0으로 나누는 경우를 특정 방식으로 처리합니다. 그 규칙에 따라, 0.0으로 나누면 다음과 같은 결과가 나옵니다:
double positive = 1.0 / 0.0; // 결과는 Infinity
double negative = -1.0 / 0.0; // 결과는 -Infinity
double zeroDivide = 0.0 / 0.0; // 결과는 NaN
부동소수점 연산에서 0으로 나누는 것에 대해 예외를 던지지 않고 Infinity를 반환하는 이유는 수학적으로 0으로 나누는 것이 정의되지 않기 때문입니다.
Infinity는 이와 같은 연산을 다룰 수 있는 방법을 제공하는 수학적 개념입니다. 이 방식은 다음과 같은 논리로 설명할 수 있습니다:
양의 실수 / 0.0: 양의 숫자를 0으로 나누면 결과는 "무한히 커지므로" Infinity가 됩니다.
음의 실수 / 0.0: 음의 숫자를 0으로 나누면 결과는 "무한히 작아지므로" -Infinity가 됩니다.
0.0 / 0.0: 0을 0으로 나누는 것은 정의할 수 없으므로 NaN이 반환됩니다.
그림은 내가 그렸음
Java에서 double 타입의 나누기 연산에서 0.0으로 나누면 예외를 발생시키지 않고 Infinity 또는 NaN을 반환하는 것은 IEEE 754 부동소수점 표준에 의한 처리 방식입니다. 이를 통해 계산이 계속 진행될 수 있도록 하고, 이후 계산에서 이러한 값을 처리할 수 있게 됩니다.

완전이해함
그럼 고전적이지만 나누기에 들어올때 검증을 해줘야겠다!!
해주는김에 throw 하는 방법도 익혀보려고 한다.
throws/throw 를 알고 사용해보자throw 사용📌
throws/throw차이점!!throw는 실제로 예외를 던지는 키워드이고, throws는 예외를 메서드 밖으로 선언하는 키워드임!
throw예시
throw new ArithmeticException("0으로 나눌 수 없습니다.");
직접 예외를 처리하는 부분에서 사용됨
throws는 메서드에서 예외를 발생시킬 가능성이 있다는 것을 선언하는 키워드이다.
주로 메서드에서 발생할 수 있는 예외를 호출하는 곳에서 처리히ㅏ도록 할 때 사용한다.
public void cacultate(int a, int b) throws ArithmeticException {
함수 선언할때 앞에 명시해주면서 사용됨
throws를 사용하지 않는 경우 (예외를 메서드 안에서 처리)public class ExceptionPractice {
public void callUncheckedException() {
if (true) {
System.out.println("언체크 예외 발생");
throw new RuntimeException(); // ✅ 예외발생
}
}
}
이 경우, 예외를 메서드 내부에서 처리하고 있으므로 throws가 필요 없음.
throws를 사용하는 경우 (예외를 메서드 밖으로 던짐)public class Calc {
public void divide(int a, int b) throws ArithmeticException {
if (b == 0) {
throw new ArithmeticException("0으로 나눌 수 없습니다."); // 예외 던지기
} else {
System.out.println("결과: " + (a / b));
}
}
public static void main(String[] args) {
Example example = new Example();
try {
example.divide(10, 0); // 0으로 나누기 시도
} catch (ArithmeticException e) {
System.out.println("예외 발생: " + e.getMessage()); // 예외 처리
}
}
}

내가만들엇음 튜터님께 물어보고 이해한 것 바탕으로!!!
만약 throws가 여러개고, throws를 가진 함수들이 서로서로를 호출하는 형태를 지녔다면
예외가 발생했을 때, 예외처리는 3가지 종류로 종료될 수 있다.
- 이를 처리할 수 있는
catch문.- 시스템종료가 가능한 위치(주로
main문)throws가 없고, 예외가 발생한 함수 호출에 연관이 된 함수
3번도 어찌보면 내부적으로 2번처럼 시스템종료를 호출할 때까지 올라가는거라서 비슷하게 볼 수 있겠다.
3번의 경우는 예외처리가 해결되지 않은 상태로 종료되기 때문에 콘솔창이 피바다가된다.

그냥 함수가 함수를 호출하는 방식을 조심조심쓰자
문제가 있던 곳은 바로 여기다
OperatorType inputOperator(){
System.out.print("계산할 사칙연산 기호를 정해주세요: ");
String temp = sc.nextLine();
OperatorType operator;
if(temp.length() == 1){
try{
operator = OperatorType.findSymbol(temp);
//System.out.println("입력한 연산자: " + operator);
return operator;
}catch (Exception e){
System.out.println("에러메시지 :" + e);
System.out.println(temp + "은 유효한 연산 기호가 아니에요 ");
}
}
return inputOperator();
}
enum OperatorType {
ADD("+"),
SUBTRACT("-"),
MULTIPLY("*"),
DIVIDE("/");
private final String symbol;
OperatorType(String symbol) {
this.symbol = symbol;
}
public String getSymbol() {
return symbol;
}
public static OperatorType findSymbol(String symbol) throws Exception {
for (OperatorType op : OperatorType.values()) {
if (op.symbol.equals(symbol)) {
return op;
}
}
throw new Exception(symbol+ "은 유효한 연산 기호가 아니에요 ");
}
}
언듯보면 엥 문제없는데? 시펑지만

유효한 연산기호가 아닐 때 연산 기호가 아니라고 말을해줘야하는데 안하고있음 ㄷㄷ
이유가 뭐지 곰곰이 고민하다가 Exception이 너무 포괄적이라 그런건가?? 싶어서 확실하게
유효 하지 않는 입력값을 뜼하는 오류인 IllegalArgumentException를 사용해봤다.
public static OperatorType findSymbol(String symbol) throws IllegalArgumentException{
for (OperatorType op : OperatorType.values()) {
if (op.symbol.equals(symbol)) {
return op;
}
}
throw new IllegalArgumentException(symbol+ "은 유효한 연산 기호가 아니에요 ");
}
이걸쓰니 된다.
뭐지???????? Exception 발생해도 작동할때가 있고 안할때가 잇나?????
뭐지?? 싶어서 다시 IllegalArgumentException을 Exception으로 고쳐서 해봤는데 또된다
if(temp.length() == 1){
try{
operator = OperatorType.findSymbol(temp);
//System.out.println("입력한 연산자: " + operator);
return operator;
}catch (Exception e){
System.out.println("에러메시지 :" + e);
System.out.println(temp + "은 유효한 연산 기호가 아니에요 ");
}
}
오류가 나는 원인은 사칙연산 기호에 여러글자를 넣었을 때 문자열의 길이가 1이상이기 때문에 if문을 거치지 못하고 나가서 그런거다 ㅋㅋㅋ
뭐함..?
하는김에 재귀호출보다는 while문이 메모리적으로 이득이라는 소리를 들어서 (특히 사용자 입력을 받을 때 !!!!!!!!!!!!!!!!!) while문으로 입력받는 형식을 모두 바꿔주었다.



망했다
...............................................
처음부터 이해를 잘못하고이썽ㅆ다...........................................난독잇나진짜
3단계 다시 해야겠다..

이번엔진짜.............................마지막이엇으면 좋겠다 완성하고싶어 ㅠㅠ

메인함수 흐름이다
입력은 메인함수에서만 받으려고 스캐너 있느 ㄴ기능은 전부 메인함수로 뺐다.
계산 기록관리와 계산기는 각각 서로서로 기능을 침범할 수 없고
서비스 이용도 한번에 하나마 ㄴ가능하다
서비스 이용이 완료되면 다시 서비스를 선택하던지, 아니면 프로그램을 종료하도록 했다..