📄 operator.java
字号:
/* * MC2 -- j2me spreadsheet * * Copyright (c) 2004-2006 Michael Zemljanukha (mixaz@mail.ru) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//* * Operator.java * * Conception: * Operators handle only args of the same datatype, so we convert * arguments to max. datatype. * 'Special' features such as datetime ops, SUM(), will be supported as functions (not OperatorName class), and implemented in other module * Unary minus is not supported too, among other infix/postfix ops. Use UMIN() function instead * * Created on February 25, 2004, 4:41 PM */package com.wapindustrial.calc;import java.util.*;import ral.Real;/** * * @author mzemlyan */public class Operator extends FunctionModule { public static final Operator OPERATOR = new Operator(); private static final int USED_BITS = 16; /** Creates a new instance of Operator */ private Operator() { } private static final String _namesArray = "\03add" + "\03sub" + "\03mul" + "\03div" + "\02eq" + "\02ne" + "\02le" + "\02lt" + "\02ge" + "\02gt" + "\04umin" + "\11parenthis" + "\03and" + "\02or" + "\03not" ; private static final int NAME_ADD = 0; private static final int NAME_SUB = NAME_ADD + 3 + 1; private static final int NAME_MUL = NAME_SUB + 3 + 1; private static final int NAME_DIV = NAME_MUL + 3 + 1; private static final int NAME_EQ = NAME_DIV + 3 + 1; private static final int NAME_NE = NAME_EQ + 2 + 1; private static final int NAME_LE = NAME_NE + 2 + 1; private static final int NAME_LT = NAME_LE + 2 + 1; private static final int NAME_GE = NAME_LT + 2 + 1; private static final int NAME_GT = NAME_GE + 2 + 1; private static final int NAME_UMIN = NAME_GT + 2 + 1; private static final int NAME_PARENTHIS = NAME_UMIN + 4 + 1; private static final int NAME_AND = NAME_PARENTHIS + 9 + 1; private static final int NAME_OR = NAME_AND + 3 + 1; private static final int NAME_NOT = NAME_OR + 2 + 1; public static final int INDEX_ADD = 0; public static final int INDEX_SUB = 1; public static final int INDEX_MUL = 2; public static final int INDEX_DIV = 3; public static final int INDEX_EQ = 4; public static final int INDEX_NE = 5; public static final int INDEX_LE = 6; public static final int INDEX_LT = 7; public static final int INDEX_GE = 8; public static final int INDEX_GT = 9; public static final int INDEX_UMIN = 10; public static final int INDEX_PARENTHIS = 11; public static final int INDEX_AND = INDEX_PARENTHIS+1; public static final int INDEX_OR = INDEX_AND+1; public static final int INDEX_NOT = INDEX_OR+1; public void initializeNames() { namesArray = _namesArray.getBytes(); namesArrayCount = namesArray.length; table = new ModuleName[] { new OperatorName("+",NAME_ADD), new OperatorName("-",NAME_SUB), new OperatorName("*",NAME_MUL), new OperatorName("/",NAME_DIV), new OperatorName("=",NAME_EQ), new OperatorName("!=",NAME_NE), new OperatorName("<=",NAME_LE), new OperatorName("<",NAME_LT), new OperatorName(">=",NAME_GE), new OperatorName(">",NAME_GT), new OperatorName("-",NAME_UMIN), new OperatorName("(",NAME_PARENTHIS), new ModuleName(NAME_AND), new ModuleName(NAME_OR), new ModuleName(NAME_NOT) }; namesCount = table.length; } public LispObject evaluate(ModuleName modulename, FunctorList sexp) throws EvaluateException {// OperatorName name = (OperatorName)sexp.functor; int size = sexp.listSize(); int optype = modulename.offset; LispObject rez = FormulaError.ERROR; switch( optype ) { case NAME_PARENTHIS: rez = sexp.evaluateArg1(); break; case NAME_UMIN: { LispObject arg = sexp.evaluateArg1(); switch( arg.typeNumber() ) { case TYPE_SHORT: rez = ShortAtom.createShortAtom( -((ShortAtom)arg).value ); break; case TYPE_LONG: rez = new LongAtom( -((LongAtom)arg).value ); break; case TYPE_FLOAT: Real r1 = new Real(((FloatAtom)arg).value); r1.neg(); rez = new FloatAtom( r1 ); break; default: throw new EvaluateException("wrong type for umin", sexp); } break; } case NAME_AND: return BooleanAtom.createBoolean( sexp.getBoolean(1) && sexp.getBoolean(2) ); case NAME_OR: return BooleanAtom.createBoolean( sexp.getBoolean(1) || sexp.getBoolean(2) ); case NAME_NOT: return BooleanAtom.createBoolean( !sexp.getBoolean(1) ); case NAME_ADD: case NAME_SUB: case NAME_MUL: case NAME_DIV: case NAME_LE: case NAME_LT: case NAME_GE: case NAME_GT: case NAME_EQ: case NAME_NE: { int sa1=0,sa2=0; long la1=0L,la2=0L; Real ra1= new Real(), ra2= new Real(); int i_rez=0; long l_rez=0L; boolean b_rez=false; LispObject arg1 = sexp.evaluateArg1(); LispObject arg2 = sexp.evaluateArg2(); int type1 = arg1.typeNumber(); if( type1 < TYPE_SHORT ) type1 = TYPE_SHORT; int type2 = arg2.typeNumber(); if( type2 < TYPE_SHORT ) type2 = TYPE_SHORT; int maxtype = type1 > type2 ? type1 : type2; arg1 = arg1.convertToType( maxtype ); // this will throw exception for incompatibe datatypes, this is OK arg2 = arg2.convertToType( maxtype ); if ( maxtype == TYPE_DATE ) { ra1 = new Real( ((DateAtom) arg1).value ); ra2 = new Real( ((DateAtom) arg2).value ); ra1.fromDHMS(); ra2.fromDHMS(); } else if( maxtype == TYPE_SHORT ) { sa1 = ((ShortAtom) arg1).value; sa2 = ((ShortAtom) arg2).value; } else if( maxtype == TYPE_LONG ) { la1 = ((LongAtom) arg1).value; la2 = ((LongAtom) arg2).value; } else if( maxtype == TYPE_FLOAT ) { ra1 = new Real(((FloatAtom) arg1).value); ra2 = new Real(((FloatAtom) arg2).value); } switch( (optype<<USED_BITS) | maxtype ) { case (NAME_ADD<<USED_BITS)|TYPE_SHORT: i_rez = sa1 + sa2; break; case (NAME_SUB<<USED_BITS)|TYPE_SHORT: i_rez = sa1 - sa2; break; case (NAME_MUL<<USED_BITS)|TYPE_SHORT: i_rez = sa1 * sa2; break; case (NAME_DIV<<USED_BITS)|TYPE_SHORT: try { i_rez = sa1 / sa2; } catch( ArithmeticException ee ) { throw new EvaluateException( "Divide by zero", sexp ); } break; case (NAME_LE<<USED_BITS)|TYPE_SHORT: b_rez = sa1 <= sa2; break; case (NAME_LT<<USED_BITS)|TYPE_SHORT: b_rez = sa1 < sa2; break; case (NAME_GE<<USED_BITS)|TYPE_SHORT: b_rez = sa1 >= sa2; break; case (NAME_GT<<USED_BITS)|TYPE_SHORT: b_rez = sa1 > sa2; break; case (NAME_EQ<<USED_BITS)|TYPE_SHORT: b_rez = sa1 == sa2; break; case (NAME_NE<<USED_BITS)|TYPE_SHORT: b_rez = sa1 != sa2; break; case (NAME_ADD<<USED_BITS)|TYPE_LONG: l_rez = la1 + la2; break; case (NAME_SUB<<USED_BITS)|TYPE_LONG: l_rez = la1 - la2; break; case (NAME_MUL<<USED_BITS)|TYPE_LONG: l_rez = la1 * la2; break; case (NAME_DIV<<USED_BITS)|TYPE_LONG: try { l_rez = la1 / la2; } catch( ArithmeticException ee ) { throw new EvaluateException( "Divide by zero", sexp ); } break; case (NAME_LE<<USED_BITS)|TYPE_LONG: b_rez = la1 <= la2; break; case (NAME_LT<<USED_BITS)|TYPE_LONG: b_rez = la1 < la2; break; case (NAME_GE<<USED_BITS)|TYPE_LONG: b_rez = la1 >= la2; break; case (NAME_GT<<USED_BITS)|TYPE_LONG: b_rez = la1 > la2; break; case (NAME_EQ<<USED_BITS)|TYPE_LONG: b_rez = la1 == la2; break; case (NAME_NE<<USED_BITS)|TYPE_LONG: b_rez = la1 != la2; break; case (NAME_ADD<<USED_BITS)|TYPE_FLOAT: case (NAME_ADD<<USED_BITS)|TYPE_DATE: ra1.add(ra2); break; case (NAME_SUB<<USED_BITS)|TYPE_FLOAT: case (NAME_SUB<<USED_BITS)|TYPE_DATE: ra1.sub(ra2); break; case (NAME_MUL<<USED_BITS)|TYPE_FLOAT: ra1.mul(ra2); break; case (NAME_DIV<<USED_BITS)|TYPE_FLOAT: if( ra2.isZero() ) throw new EvaluateException( "Divide by Zero", sexp ); ra1.div(ra2); break; case (NAME_LE<<USED_BITS)|TYPE_FLOAT: case (NAME_LE<<USED_BITS)|TYPE_DATE: b_rez = ra1.lessEqual(ra2); break; case (NAME_LT<<USED_BITS)|TYPE_FLOAT: case (NAME_LT<<USED_BITS)|TYPE_DATE: b_rez = ra1.lessThan(ra2); break; case (NAME_GE<<USED_BITS)|TYPE_FLOAT: case (NAME_GE<<USED_BITS)|TYPE_DATE: b_rez = ra1.greaterEqual(ra2); break; case (NAME_GT<<USED_BITS)|TYPE_FLOAT: case (NAME_GT<<USED_BITS)|TYPE_DATE: b_rez = ra1.greaterThan(ra2); break; case (NAME_EQ<<USED_BITS)|TYPE_FLOAT: case (NAME_EQ<<USED_BITS)|TYPE_DATE: b_rez = ra1.equalTo(ra2); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -