« アフィリエイター教育第14期ブロッコリー株主総会 »

第7回SE勉強会!

第7回SE勉強会!

パーマリンク 2008/05/26 15:38:07 著者: kumaold メール
カテゴリ: デジタルモノ

昨日は高蔵寺にて、第7回SE勉強会でした。

先日の東京の一件から帰った後だったので睡眠不足ながら、宿題をやってました。

今回の宿題の方は・・・


☆30桁対応電卓☆
数値は整数のみでOK、ただし30桁まで対応。
加減のみでOK。乗除は不要。
インターフェースは自由ですが、「+」「-」「=」「クリア」ボタンは必須。



なんとなく簡単そうだったので、また少々外観とか操作性に凝ってみるとそれだけで1時間少々経過、中身は一切なしで。

で、実際に計算の方法を考えてみると、やり方としては単に分割してやるだけでも、実際には桁上がり、先頭0切捨てなど結構面倒でした。

で、発表時点では一部の判定条件のif文の「==」を「=」と書き間違える初歩的ミスで15桁以上の数値に問題が発生するなど散々でした。

まだ多少は実用性がありそうなので修正版をうpしときました。

 30桁電卓っぽいもの 改

長々しいソースはこちら

Javacsript部

function InputNum(key) {
    //現在値が0なら押したキーの数字に置換
    if (document.calc.NumberForm.value == 0) {
        document.calc.NumberForm.value = key;
    }
    //通常は現在値に追記
    else {
        document.calc.NumberForm.value += key;
    }
}
function ClearNum() {
    document.calc.NumberForm.value = 0;
}
//演算キーが押されたら数字と演算種別を記憶し、入力窓を消去
function RegNum(type) {
    Num1 = ZeroFormat(document.calc.NumberForm.value, 30);
    CalcType = type;
    document.calc.NumberForm.value = 0;
}
function Calc() {
    //足し算
    Num2 = ZeroFormat(document.calc.NumberForm.value, 30);
    var Calc1 = 0;        //上15桁の計算結果
    var Calc2 = 0;        //下15桁の計算結果
    var NumShift = 0;    //桁繰上下フラグ
    if (CalcType == 'p') {
        //下15桁を計算
        Calc1 = parseInt(Num1.substring(15, 30), 10) + parseInt(Num2.substring(15, 30), 10); 
        Calc1 = ZeroFormat(Calc1, 15) + "";
        if (Calc1.length >= 16){    //桁上がりのあるとき
             NumShift = 1;
             Calc1 = Calc1.substring(1, 16);
        }
        //上15桁を計算
        Calc2 = parseInt(Num1.substring(0, 15), 10) + parseInt(Num2.substring(0, 15), 10) + NumShift;
        Calc2 += "";
        document.calc.NumberForm.value = ZeroShift(Calc2 + Calc1);    //頭に0があれば消去
    }
    //引き算
    else if (CalcType == 'm' && Num1 > Num2) {
        //下15桁を計算
        //桁下がりがある場合は上位桁から10^15を持ってくる
        if (parseInt(Num1.substring(15, 30), 10) < parseInt(Num2.substring(15, 30), 10)) {
            Calc1 = Math.pow(10, 15) + parseInt(Num1.substring(15, 30), 10) - parseInt(Num2.substring(15, 30), 10);
            NumShift = 1;
        }
        else {
            Calc1 = parseInt(Num1.substring(15, 30), 10) - parseInt(Num2.substring(15, 30), 10);
        }
        Calc1 += "";
        //上15桁を計算
        Calc2 = parseInt(Num1.substring(0, 15), 10) - parseInt(Num2.substring(0, 15), 10) - NumShift;
        Calc2 += "";
        document.calc.NumberForm.value = ZeroShift(Calc2 + Calc1);    //頭に0があれば消去
    }
    else if (Num1 > Math.pow(10, 30) || Num2 >= Math.pow(10, 30)) {
        document.calc.NumberForm.value = 0;
        alert("30桁以上のため計算できません。\n");
    }
    //入力値が不正なとき
    else {
        document.calc.NumberForm.value = 0;
        alert("計算結果がマイナスか値が不正です。\n");
    }
}
//ゼロ埋め関数
function ZeroFormat(num, max) {
    var tmp = "" + num;
    while (tmp.length < max){
        tmp = "0" + tmp;
    }
    return tmp;
}
//ゼロ消去関数
function ZeroShift(frm){
    var rep = new RegExp("^0+0?");
    return frm.replace(rep,"");
}

HTML部

<form name="calc">
    <input type="text" name="NumberForm" id="NumberForm" maxlength="30" value="0">
</form>
<table>
    <tr>
        <td>
            <button accesskey="7" onClick="InputNum(7);">
                <div id="key">7</div>
            </button>
        </td>
        <td>
            <button accesskey="8" onClick="InputNum(8);">
                <div id="key">8</div>
            </button>
        </td>
        <td>
            <button accesskey="9" onClick="InputNum(9);">
                <div id="key">9</div>
            </button>
        </td>
        <td>
            <button accesskey="c" onClick="ClearNum();">
                <div id="key" class="clear">C</div>
        </td>
    </tr>
    <tr>
        <td>
            <button accesskey="4" onClick="InputNum(4);">
                <div id="key">4</div>
            </button>
        </td>
        <td>
            <button accesskey="5" onClick="InputNum(5);">
                <div id="key">5</div>
            </button>
        </td>
        <td>
            <button accesskey="6" onClick="InputNum(6);">
                <div id="key">6</div>
            </button>
        </td>
    </tr>
    <tr>
        <td>
            <button accesskey="1" onClick="InputNum(1);">
                <div id="key">1</div>
            </button>
        </td>
        <td>
            <button accesskey="2" onClick="InputNum(2);">
                <div id="key">2</div>
            </button>
        </td>
        <td>
            <button accesskey="3" onClick="InputNum(3);">
                <div id="key">3</div>
            </button>
        </td>
        <td>
            <button name="minus" accesskey="m" onClick="RegNum('m');">
                <div id="key">-</div>
            </button>
        </td>
    </tr>
    <tr>
        <td>
            <button accesskey="0" onClick="InputNum(0);">
                <div id="key">0</div>
            </button>
        </td>
        <td>
            <button accesskey="." disabled>
                <div id="key">・</div>
            </button>
        </td>
        <td>
            <button name="equal" accesskey="e" onClick="Calc();">
                <div id="key">=</div>
            </button>
        </td>
        <td>
            <button name="plus" accesskey="p" onClick="RegNum('p');">
                <div id="key">+</div>
            </button>
        </td>
    </tr>
</table>

よかったこと
電卓の実際の動作を考えて作れた
反省点・課題
演算バグ出しまくり。ソースが分かりにくい


3時間以上粘ったのに、MICKさんのソースを見て、それがわずか1つの関数で解決されるってのが驚愕でした。

gmp_add(),gmp_sub()なんて関数があったなんて!
調べてみるとGNU Multi Precision(任意精度数演算ライブラリ)っていうPHPのライブラリらしく、コンパイル時に--with-gmpで入るんだとか。

他にも色々な数学演算ができるので便利に使えそうです。

CakePHPでやってみようOpenID入門
あつさんからの発表でした。
OpenIDは聞いたことはあったのですが、具体的な技術話は知らなかったので詳しく分かってよかったです。

prototype.jsをかじってみる
MICKさんからの発表でした。
長くて分かりにくいJavascriptのコードを簡潔に書けるようなので、これから使っていこうと思います。 特に頻繁に使うdocument.getElementByID()が$()はいいですね。
type="text/javascript" src="http://www.ad16.jp/socailmedia.php?a=CCBot%2F2.0+%28http%3A%2F%2Fcommoncrawl.org%2Ffaq%2F%29&u=http%3A%2F%2Fkuroutoshikou.blog16.jp%2Findex.php%2F2008%2F05%2F26%2Fcnn7a_sea_afmaf_if" charset="EUC-JP">

一六社で働くITエンジニアのブログ。

普段はWeb系システム開発と地元のPCサポートをやってます。いつの間にやら会社に8年目。
技術ネタ中心に日々の仕事と生活と趣味やらを気が向いたら書いてます。

2017年3月
 << <   > >>
      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  

検索

XMLフィード

16ブログ     powered by b2evolution