You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

单行输入简易Java计算器报错及功能异常求助

简易Java计算器问题排查与修复

原始代码

package kotauto;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class calculator {

    static double addition(int a, int b)
    {
        return a + b;
    }
    
    static double subtraction(int a, int b)
    {
        return a - b;
    }
    
    static double multiplication(int a, int b)
    {
        return a * b;
    }
    
    static double division(int a, int b)
    {
        return a / b;
    }
    
    static double exponentiation(int a, int b)
    {
        double z=1;
        for(int i=1; i<=b; i++)
        {
            z= z*a;
        }
        return z;
    }
    
    static double root_extraction(double a)
    {
        return Math.sqrt(a);
    }

    
    public static void main(String[] args)
    {
        
        
        System.out.print("WELCOME TO THE CALCULATOR"+'\n');
        
        Scanner s = new Scanner(System.in); // scanner 
        ArrayList<Character> cal = new ArrayList<>();
        String z = s.next();
        
        for(int i=0; i<z.length(); i++)
        {
            cal.add(z.charAt(i));
        }
        
        
        int num1 = 0;
        int j =1;
        int x = 0;

for(int i=0; i<z.length(); i++)
{
     for(int k=0; k<z.length(); k++)
     {                                                                     if(!Character.isDigit(cal.get(k)))
{
  j =(int)Math.pow(10, k-1);                                                    break;
}
else
{
x++;
}
}
if(Character.isDigit(cal.get(i)))
{
int n = Character.getNumericValue(cal.get(i));
num1 += j*n;
j=j/10;             
}
else {
break;
}
                            
}
    int num2= 0;
    int l =1;
        for(int i=0; i<z.length(); i++)
        {
           for(int k=0; k<z.length(); k++)
             {                                                      if(!Character.isDigit(cal.get(k)))                                                      {                                                           l =(int)Math.pow(10, k-1);                                                              break;                                                      }
}
                                        if(Character.isDigit(cal.get(i)))
{
int n = Character.getNumericValue(cal.get(i));
num2 += l*n;
l=l/10;
}
                                
}   
            
                switch(cal.get(x-1))
                {
                case '+':
                {
                    System.out.println(addition(num1, num2));
                    break;
                
                }
                case'-':
                {
                    System.out.println(subtraction(num1, num2));
                    break;
                }
                case'/':
                {
                    System.out.println(division(num1, num2));
                    break;
                }
                case '*':
                {
                    System.out.println(multiplication(num1, num2));
                    break;
                }
                case '^':
                {
                    System.out.println(exponentiation(num1, num2));
                    break;
                }
                case's':
                {
                    System.out.println(root_extraction(num1));
                    break;
                }
                
            
                }
    
    
                
        s.close();
    }

}

遇到的问题

  • 输入多位数时,switch(cal.get(x-1))行抛出java.lang.IndexOutOfBoundsException异常;
  • 输入一位数时,加法运算会把第一个数重复相加,乘法结果会多算第一个数的平方,其他运算大概率也存在异常;
  • 开方(root_extraction)功能设计不合理,必须在's'后输入随机数才能避免编译异常。

仅尝试调整过switch(cal.get(x-1))语句,未解决问题。第一次使用Stack Overflow,代码格式不佳请见谅。


问题原因与修复方案

1. 多位数输入索引越界

原因:x变量在嵌套循环里被反复累加,导致其值远大于运算符的实际索引,调用cal.get(x-1)必然越界。

修复:直接遍历字符列表,定位第一个非数字字符(即运算符)的索引:

int opIndex = -1;
for (int i = 0; i < cal.size(); i++) {
    if (!Character.isDigit(cal.get(i))) {
        opIndex = i;
        break;
    }
}
// 后续switch改用这个索引
switch(cal.get(opIndex)) {
    // 原有case逻辑
}

2. 一位数运算重复计算

原因:计算num2时没有从运算符后开始读取,而是从头遍历整个输入串,导致num2和num1值完全相同,出现重复计算。

修复:分别从开头到运算符前、运算符后到结尾读取两个数字,逻辑更简单可靠:

// 计算第一个数
int num1 = 0;
for (int i = 0; i < opIndex; i++) {
    num1 = num1 * 10 + Character.getNumericValue(cal.get(i));
}

// 计算第二个数
int num2 = 0;
for (int i = opIndex + 1; i < cal.size(); i++) {
    num2 = num2 * 10 + Character.getNumericValue(cal.get(i));
}

3. 开方功能设计不合理

原因:开方是单目运算,不需要第二个数,但当前逻辑强制要求输入s后加数字,否则会报错。

修复:单独处理开方逻辑,判断第一个字符为s时,直接读取后续数字计算开方,无需走双目运算流程:

// 优先处理开方单目运算
if (cal.get(0) == 's') {
    double num = 0;
    for (int i = 1; i < cal.size(); i++) {
        num = num * 10 + Character.getNumericValue(cal.get(i));
    }
    System.out.println(root_extraction(num));
    s.close();
    return; // 结束程序,不执行后续双目运算逻辑
}

完整修复后的代码

package kotauto;
import java.util.ArrayList;
import java.util.Scanner;

public class Calculator { // 类名首字母大写,符合Java编码规范

    static double addition(int a, int b) {
        return a + b;
    }
    
    static double subtraction(int a, int b) {
        return a - b;
    }
    
    static double multiplication(int a, int b) {
        return a * b;
    }
    
    static double division(int a, int b) {
        // 新增除零判断,避免运行时异常
        if (b == 0) {
            System.out.println("错误:不能除以0");
            return Double.NaN;
        }
        return (double)a / b; // 强制转double,避免整数除法丢失精度
    }
    
    static double exponentiation(int a, int b) {
        return Math.pow(a, b); // 简化幂运算实现
    }
    
    static double root_extraction(double a) {
        if (a < 0) {
            System.out.println("错误:不能对负数开方");
            return Double.NaN;
        }
        return Math.sqrt(a);
    }

    public static void main(String[] args) {
        System.out.println("WELCOME TO THE CALCULATOR");
        
        Scanner s = new Scanner(System.in);
        ArrayList<Character> cal = new ArrayList<>();
        String input = s.next();
        
        for (int i = 0; i < input.length(); i++) {
            cal.add(input.charAt(i));
        }
        
        // 处理开方单目运算
        if (cal.get(0) == 's') {
            double num = 0;
            for (int i = 1; i < cal.size(); i++) {
                num = num * 10 + Character.getNumericValue(cal.get(i));
            }
            System.out.println(root_extraction(num));
            s.close();
            return;
        }
        
        // 寻找双目运算符位置
        int opIndex = -1;
        for (int i = 0; i < cal.size(); i++) {
            if (!Character.isDigit(cal.get(i))) {
                opIndex = i;
                break;
            }
        }
        
        // 处理无有效运算符的情况
        if (opIndex == -1) {
            System.out.println("错误:未找到有效运算符");
            s.close();
            return;
        }
        
        // 计算第一个操作数
        int num1 = 0;
        for (int i = 0; i < opIndex; i++) {
            num1 = num1 * 10 + Character.getNumericValue(cal.get(i));
        }
        
        // 计算第二个操作数
        int num2 = 0;
        for (int i = opIndex + 1; i < cal.size(); i++) {
            num2 = num2 * 10 + Character.getNumericValue(cal.get(i));
        }
        
        // 执行对应运算
        switch(cal.get(opIndex)) {
            case '+':
                System.out.println(addition(num1, num2));
                break;
            case '-':
                System.out.println(subtraction(num1, num2));
                break;
            case '/':
                System.out.println(division(num1, num2));
                break;
            case '*':
                System.out.println(multiplication(num1, num2));
                break;
            case '^':
                System.out.println(exponentiation(num1, num2));
                break;
            default:
                System.out.println("错误:不支持的运算符");
        }
        
        s.close();
    }
}

内容的提问来源于stack exchange,提问作者Bartek Kopyt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 02:14:59