<!-- #include file="../../include.asp" --> <html> <% = HtmlHeader("Calc") %> <SCRIPT LANGUAGE="JavaScript"> <!-- var Tmp; Tmp = ""; var calcFlg = 0; //↓↓↓061120小野 /////////////////////////////////////////////////////////////////////////////// // shisokuenzan(String) // usage:shisokuenzan('1.1*1.1') // 数列から小数点を除いてから四則演算を行うことで // 浮動小数による2進10進変換誤差を最小限に留めます。 // 理論上は加算・減算・乗算では誤差が完全に排除されます。 // 除算は計算結果が小数になる場合にのみ誤差が発生し得ます。 /////////////////////////////////////////////////////////////////////////////// function shisokuenzan(str) { //先頭が'*''/'ならそのまま終了 if (str.charAt(0) == '*' || str.charAt(0) == '/') return str; //先頭が'--'ならそのまま終了 if (str.charAt(0) == '-' && str.charAt(1) == '-') return str; //先頭が'++'ならそのまま終了 if (str.charAt(0) == '+' && str.charAt(1) == '+') return str; for (i=0; i<str.length; i++) { //数字・小数点・演算子以外ならそのまま終了 if (isNaN(str.charAt(i))) { if (str.charAt(i) != '.' && str.charAt(i) != '*' && str.charAt(i) != '/' && str.charAt(i) != '+' && str.charAt(i) != '-') return str; } //ピリオドの次に現れる数字以外の文字がピリオドならそのまま終了 if (str.charAt(i) == '.') { for (ii=i+1; ii<str.length; ii++) { if (isNaN(str.charAt(ii))) { if (str.charAt(ii) == '.') return str; break; } } } //'+''-'の直後に'*''/'があればそのまま終了 if (str.charAt(i) == '+' || str.charAt(i) == '-') { if (str.charAt(i+1) == '*' || str.charAt(i+1) == '/') return str; } //演算子が3つ並んでいればそのまま終了 if (str.charAt(i) == '*' || str.charAt(i) == '/' || str.charAt(i) == '+' || str.charAt(i) == '-') { if (str.charAt(i+1) == '*' || str.charAt(i+1) == '/' || str.charAt(i+1) == '+' || str.charAt(i+1) == '-') { if (str.charAt(i+2) == '*' || str.charAt(i+2) == '/' || str.charAt(i+2) == '+' || str.charAt(i+2) == '-') return str; } } } //計算上余分な'+'単純演算子をトリミング if (str.charAt(0) == '+') { str = str.substring(1,str.length); } for (i=0; i<str.length; i++) { if (str.charAt(i) == '*' || str.charAt(i) == '/' || str.charAt(i) == '+' || str.charAt(i) == '-') { if (str.charAt(i+1) == '+') { str = str.substring(0,i+1) + str.substring(i+2,str.length); } } } //数列と演算子を配列に格納 j = 0; //カラムカウンタ num = 0; //アレイカウンタ ope = 0; //アレイカウンタ numary = new Array(); //数列用配列 opeary = new Array(); //演算子用配列 for (i=0; i<str.length; i++) { if (str.charAt(i) == '*' || str.charAt(i) == '/' || str.charAt(i) == '+' || str.charAt(i) == '-') { //発見した演算子が'-'の際にそれが1文字目であれば'-'単純演算子として無視 if (str.charAt(i) == '-' && i == 0); //発見した演算子が'-'の際に直前が演算子であれば'-'単純演算子として無視 else if (str.charAt(i) == '-' && str.charAt(i-1) == '+'); else if (str.charAt(i) == '-' && str.charAt(i-1) == '-'); else if (str.charAt(i) == '-' && str.charAt(i-1) == '*'); else if (str.charAt(i) == '-' && str.charAt(i-1) == '/'); else { numary[num] = inttrim(str.substring(j,i)); //数列格納 num = num + 1; j = i; opeary[ope] = inttrim(str.substring(j,i+1)); //演算子格納 ope = ope + 1; j = j + 1; } } } numary[num] = inttrim(str.substring(j,str.length)); //最終数列格納 //桁あふれ時のeval抜け用文字列作成 str = ''; //初期化 for (i=0; i<num+1; i++) { str = str + numary[i]; if (i == num) break; str = str + opeary[i]; } /////// 数列表示用/////////////// // for (i=0; i<num; i++) { // alert(numary[i]); // alert(opeary[i]); // } // alert(numary[num]); // alert(str); ///////////////////////////////// //左から数列毎に演算処理 //※計算が発生した場合は次回処理でも同じ数列位置を //※処理しなければならないのでループカウンタは使わない j = 0; //処理位置カウンタ //※処理後の配列左シフトでアレイ数を直接減少させると //※ループ回数が減ってしまうのでサブカウンタを使う inum = num; //アレイサブカウンタ iope = ope; //アレイサブカウンタ //先に左から乗算と除算を行う for (i=0; i<num; i++) { if (j > num) break; if (opeary[j] == '*' || opeary[j] == '/') { kakeju = 0; //初期化 wariju = 0; //初期化 //演算子の直前の数字から小数点を除く numtmp = numary[j].split('.'); if (numtmp.length == 2) { wariju = wariju + numtmp[1].length; numary[j] = numtmp[0] + numtmp[1]; } //演算子の直後の数字から小数点を除く numtmp = numary[j+1].split('.'); if (numtmp.length == 2) { if (opeary[j] == '*') { wariju = wariju + numtmp[1].length; } else { kakeju = kakeju + numtmp[1].length; //割る数の場合のみ計算後に積算 } numary[j+1] = numtmp[0] + numtmp[1]; } if (inttrim(numary[j]) != "" && inttrim(numary[j+1]) != "") { //演算子の前後を計算 numary[j] = '' + eval(inttrim(numary[j]) + opeary[j] + inttrim(numary[j+1])); } //桁あふれ対策(妥協(^^;) for (ii=0; ii<numary[j].length; ii++) { if (numary[j].charAt(ii) == 'e') return eval(str); } //数列・演算子の配列を左シフト for (ii=j+1; ii<inum; ii++) { numary[ii] = numary[ii+1]; } inum = inum - 1; for (ii=j; ii<iope; ii++) { opeary[ii] = opeary[ii+1]; } iope = iope - 1; //計算結果に小数点を戻す mnsflg = ''; //マイナス演算子フラグ tmpstr = numary[j].split('.'); //計算結果を小数点で分割 if (tmpstr[0].charAt(0) == '-') { //整数部分の先頭に'-'が存在する場合は一時カットオフ tmpstr[0] = tmpstr[0].substring(1,tmpstr[0].length) mnsflg = '-'; } //小数点右シフト if (tmpstr.length == 2) { if (tmpstr[1].length > kakeju) { tmpstr[0] = tmpstr[0] + tmpstr[1].substring(0,kakeju); tmpstr[1] = tmpstr[1].substring(kakeju,tmpstr[1].length); } else { tmpstr[0] = tmpstr[0] + tmpstr[1]; kakeju = kakeju - tmpstr[1].length; for (ii=0; ii<kakeju; ii++) { tmpstr[0] = tmpstr[0] + '0'; } tmpstr[1] = '' } } else { for (ii=0; ii<kakeju; ii++) { tmpstr[0] = tmpstr[0] + '0'; } tmpstr[1] = ''; } //小数点左シフト if (tmpstr[0].length > wariju) { //整数部分が残存する場合 tmpstr[1] = tmpstr[0].substring(tmpstr[0].length-wariju,tmpstr[0].length) + tmpstr[1]; //小数部分の前にwarijuの分を整数部分から追加 tmpstr[0] = tmpstr[0].substring(0,tmpstr[0].length-wariju); //整数部分からwarijuの分だけ切り落とし } else { //整数部分が残存しない場合 tmpstr[1] = tmpstr[0] + tmpstr[1]; wariju = wariju - tmpstr[0].length; for (ii=0; ii<wariju; ii++) { tmpstr[1] = '0' + tmpstr[1]; } tmpstr[0] = ''; } //結合処理 if (tmpstr[0] == '') { numary[j] = mnsflg + '0.' + tmpstr[1]; } else if (tmpstr[1] == '') { numary[j] = mnsflg + tmpstr[0]; } else { numary[j] = mnsflg + tmpstr[0] + '.' + tmpstr[1]; } } else { j = j + 1; } } num = inum; //テンポラリ代入 ope = iope; /////// 数列表示用/////////////// // for (i=0; i<num; i++) { // alert(numary[i]); // alert(opeary[i]); // } // alert(numary[num]); ///////////////////////////////// j = 0; //処理位置カウンタ初期化 //左から加算と減算を行う for (i=0; i<inum; i++) { if (num == 0) break; kakeju = 0; //初期化 wariju = 0; //初期化 //演算子の左右の数字の桁合わせ numtmpl = numary[j].split('.'); numtmpr = numary[j+1].split('.'); if (numtmpl.length < 2) numtmpl[1] = ''; //小数部分が無い場合は空白文字に if (numtmpr.length < 2) numtmpr[1] = ''; if (numtmpl[1].length > numtmpr[1].length) { jj = numtmpl[1].length - numtmpr[1].length; for (ii=0; ii<jj; ii++) { numtmpr[1] = numtmpr[1] + '0'; } } else if (numtmpr[1].length > numtmpl[1].length) { jj = numtmpr[1].length - numtmpl[1].length; for (ii=0; ii<jj; ii++) { numtmpl[1] = numtmpl[1] + '0'; } } wariju = wariju + numtmpl[1].length; numary[j] = numtmpl[0] + numtmpl[1]; numary[j+1] = numtmpr[0] + numtmpr[1]; //演算子の前後を計算 numary[j] = '' + eval(inttrim(numary[j]) + opeary[j] + inttrim(numary[j+1])); //桁あふれ対策(妥協(^^;) for (ii=0; ii<numary[j].length; ii++) { if (numary[j].charAt(ii) == 'e') return eval(str); } //数列・演算子配列を左シフト for (ii=j+1; ii<num; ii++) { numary[ii] = numary[ii+1]; } num = num - 1; for (ii=j; ii<iope; ii++) { opeary[ii] = opeary[ii+1]; } ope = ope - 1; //計算結果に小数点を戻す mnsflg = ''; //マイナス演算子フラグ tmpstr = numary[j].split('.'); //計算結果を小数点で分割 if (tmpstr[0].charAt(0) == '-') { //整数部分の先頭に'-'が存在する場合は一時カットオフ tmpstr[0] = tmpstr[0].substring(1,tmpstr[0].length); mnsflg = '-'; } //小数点右シフト if (tmpstr.length == 2) { if (tmpstr[1].length > kakeju) { tmpstr[0] = tmpstr[0] + tmpstr[1].substring(0,kakeju); tmpstr[1] = tmpstr[1].substring(kakeju,tmpstr[1].length); } else { tmpstr[0] = tmpstr[0] + tmpstr[1]; kakeju = kakeju - tmpstr[1].length; for (ii=0; ii<kakeju; ii++) { tmpstr[0] = tmpstr[0] + '0'; } tmpstr[1] = ''; } } else { for (ii=0; ii<kakeju; ii++) { tmpstr[0] = tmpstr[0] + '0'; } tmpstr[1] = ''; } //小数点左シフト if (tmpstr[0].length > wariju) { //整数部分が残存する場合 tmpstr[1] = tmpstr[0].substring(tmpstr[0].length-wariju,tmpstr[0].length) + tmpstr[1]; //小数部分の前にwarijuの分を整数部分から追加 tmpstr[0] = tmpstr[0].substring(0,tmpstr[0].length-wariju); //整数部分からwarijuの分だけ切り落とし } else { //整数部分が残存しない場合 tmpstr[1] = tmpstr[0] + tmpstr[1]; wariju = wariju - tmpstr[0].length; for (ii=0; ii<wariju; ii++) { tmpstr[1] = '0' + tmpstr[1]; } tmpstr[0] = ''; } //結合処理 if (tmpstr[0] == '') { numary[j] = mnsflg + '0.' + tmpstr[1]; } else if (tmpstr[1] == '') { numary[j] = mnsflg + tmpstr[0]; } else { numary[j] = mnsflg + tmpstr[0] + '.' + tmpstr[1]; } } /////// 数列表示用/////////////// // for (i=0; i<num; i++) { // alert(numary[i]); // alert(opeary[i]); // } // alert(numary[num]); ///////////////////////////////// //桁合わせで生じた余分な0をカットオフ // return eval(numary[0]); return inttrim(numary[0]); } //数列文字列の先頭の余分な0をカットオフ //※整数部分の先頭に0があると8進数扱いになるので必要 function inttrim(str) { mnsflg = ''; //マイナス演算子フラグ if (str.charAt(0) == '-') { //先頭に'-'が存在する場合は一時カットオフ str = str.substring(1,str.length); mnsflg = '-'; } //先頭が'0'の場合は直後が'.'で無ければカットオフ while (str.charAt(0) == '0' && str.charAt(1) != '.') { str = str.substring(1,str.length); } str = mnsflg + str; return str; } //↑↑↑061120小野 function DispIn(v) { Tmp = v; //alert(Tmp); document.getElementById("calCDisp").value = Tmp; //DOMで画面に挿入表示 //alert(Tmp); } function DispOut() { return Tmp; // return document.getElementById('calCDisp').value ; } function DispEval(v) { return shisokuenzan(v); //061120小野 // return eval(v); } function inValue(inData) { if (calcFlg == 2) { DispIn(inData); calcFlg = 0; } else { //入力された文字をテンポラリ文字列につなげてDispIn() var TmpOut = DispOut() + inData; if (TmpOut.length > 16) { TmpOut = DispOut(); } DispIn(TmpOut); calcFlg = 0; } } function inCalc(inData) { if (inData == "=") { if (calcFlg == 1) { DispIn(DispEval(DispOut().substring(0,DispOut().length-1))); calcFlg = 2; } else { DispIn(DispEval(DispOut())); calcFlg = 2; } } else if(inData == ".") { if (calcFlg == 1) { DispIn(DispOut() + "0."); calcFlg = 1; } else { DispIn(DispOut() + inData); calcFlg = 1; } } else { if (calcFlg == 1) { DispIn(DispOut().substring(0,DispOut().length-1) + inData); calcFlg = 1; } else { DispIn(DispOut() + inData); calcFlg = 1; } } } function inClear() { DispIn(""); calcFlg = 1; } function keyProc(ev) { var evCh = String.fromCharCode(ev); if (ev == 13) { inCalc('='); } else if (evCh >= "0" && evCh <= "9") { // 数値キー inValue(evCh); } else if (evCh == "+" || evCh == "-" || evCh == "*" || evCh == "/" || evCh == ".") { // 四則演算 inCalc(evCh); } } //--> </SCRIPT> <style type="text/css"> <!-- .caldsp { font-family: Arial; font-size: 16px; font-weight: bold; color: #FFFFFF; background-color: #666666; text-align: right; border: solid 2px; border-color: #CBCBCC #A2A2A2 #CECECE #B5B5B7; padding: 3px; } --> </style> <SCRIPT LANGUAGE="JavaScript"> <!-- ExitFlg = 1; --> </SCRIPT> <body onkeydown="if(ExitFlg==2)ExitFlg=3;" bgcolor="#8D9BCC" onkeypress="keyProc(event.keyCode);" topmargin="0" leftmargin="0"> <table width="100%" height="100%" border="0" cellpadding="0" cellspacing="0"> <tr> <td align="center" valign="middle"> <table width="180" height="255" border="0" cellpadding="0" cellspacing="5" background="../../images/calc_bk.jpg?<% = GB_STU %>"> <tr> <td height="10" colspan="6"><img src="../../images/spacer.gif?<% = GB_STU %>" width="150" height="5"></td> </tr> <tr align="center"> <td height="32" colspan="6" valign="top"> <input id="calCDisp" readonly type="text" class="caldsp" style="width:160px;height:25px;" value=""> </td> </tr> <tr> <td width="3" rowspan="5"><img src="../../images/spacer.gif?<% = GB_STU %>" width="3" height="100"></td> <td width="35" height="23" class="tbtn" onClick="ExitFlg=0;window.close()"> </td> <td width="35" height="23" class="tbtn" onclick="inClear()"> </td> <td width="35" height="23" class="tbtn" onclick="inValue('00')"> </td> <td width="35" height="23" class="tbtn" onclick="inValue('000')"> </td> <td width="2" rowspan="5"><img src="../../images/spacer.gif?<% = GB_STU %>" width="2" height="100"></td> </tr> <tr> <td width="35" height="35" class="tbtn" onclick="inValue(7)"> </td> <td width="35" height="35" class="tbtn" onclick="inValue(8)"> </td> <td width="35" height="35" class="tbtn" onclick="inValue(9)"> </td> <td width="35" height="35" class="tbtn" onclick="inCalc('/')"> </td> </tr> <tr> <td width="35" height="35" class="tbtn" onclick="inValue(4)"> </td> <td width="35" height="35" class="tbtn" onclick="inValue(5)"> </td> <td width="35" height="35" class="tbtn" onclick="inValue(6)"> </td> <td width="35" height="35" class="tbtn" onclick="inCalc('*')"> </td> </tr> <tr> <td width="35" height="35" class="tbtn" onclick="inValue(1)"> </td> <td width="35" height="35" class="tbtn" onclick="inValue(2)"> </td> <td width="35" height="35" class="tbtn" onclick="inValue(3)"> </td> <td width="35" height="35" class="tbtn" onclick="inCalc('-')"> </td> </tr> <tr> <td width="35" height="35" class="tbtn" onclick="inValue(0)"> </td> <td width="35" height="35" class="tbtn" onclick="inValue('.')"> </td> <td width="35" height="35" class="tbtn" onclick="inCalc('=')"> </td> <td width="35" height="35" class="tbtn" onclick="inCalc('+')"> </td> </tr> <tr> <td height="5" colspan="6"><img src="../../images/spacer.gif?<% = GB_STU %>" width="150" height="5"></td> </tr> </table> </td> </tr> </table> </body> </html>