HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2016
0309
ケイジ入力した文字列の計算5解決


ケイジ

リンク

2016/3/9(Wed) 10:44:39|NO.74834

閲覧、ありがとうございます!

現在、入力した文字列を読み取り計算するツールを作成している途中です。
細かい問題は残るものの形にはしたのですが、機構部分に無駄な処理が多くないかと不安です。

もしよろしければ、改善案やアドバイスを頂けると嬉しいです。

初めての書き込みなので、
書き込みに問題があればお手数ですが教えていただけると嬉しいです!


作成途中のため、
 ・負の乗算
 ・0での除算
 ・負以外の符号、演算子を先頭に入力する
 ・小数点以下は切り捨て
 など、問題に対応する処理が施されていないので、実行する場合は気をつけてください。

以下はソースです。ご一読ありがとうございます!


// 変数に見立てたモノ repeat 100 p.cnt = cnt loop color : boxf color 255, 255, 255 font "メイリオ" objmode 2 sdim 文字列 文字列 = "1+2-3*4/5-2*2*2" 座標X = 12 座標Y = 18 pos 座標X, 座標Y Input 文字列, 640 -座標X * 2 objsize 640 -座標X * 2 button "計算", *計算 座標Y += ginfo_cy stop *計算 color : boxf color 255, 255, 255 pos 座標X, 座標Y 文字列C = 文字列 mes 文字列 // 変数の置換 repeat 100 変数 = "p" + cnt strrep 文字列C, 変数, str(p.cnt) loop // 演算 repeat 文字列S = 文字列C 算出 = 0 // 演算子の置換 strrep 文字列S, "*", "S" strrep 文字列S, "/", "S" strrep 文字列S, "+", "T" strrep 文字列S, "-", "T" 文字列D = 文字列S strrep 文字列D, "F", " " strrep 文字列D, "S", " " strrep 文字列D, "T", " " sdim 演算子番号 演算子座標 = 0 // 演算子座標の割り出し repeat 演算子番号.cnt = instr(文字列D, 演算子座標, " ") if 演算子番号.cnt = -1 : break 演算子番号.cnt += 演算子座標 演算子座標 = 演算子番号.cnt + 1 loop if 演算子番号 = -1 : break if 演算子番号 = 0 & 演算子番号.1 = -1 : break // 演算 演算 = instr(文字列S, 0, "F") if 演算 = -1 { 演算 = instr(文字列S, 0, "S") if 演算 = -1 : 演算 = instr(文字列S, 0, "T") } if 演算子番号 = 0 : 演算 = 演算子番号.1 repeat if 演算子番号.cnt = -1 : break if 演算子番号.cnt != 演算 : continue if cnt = 0 { 左辺位置 = 0 } else { 左辺位置 = 演算子番号.(cnt -1) + 1 } if 演算子番号.(cnt + 1) = -1 { 右辺位置 = 演算 + 5 } else { 右辺位置 = 演算子番号.(cnt + 1) } 演算子 = strmid(文字列C, 演算, 1) 演算式 = strmid(文字列C, 左辺位置, 右辺位置 -左辺位置) title ""+文字列C split 演算式, 演算子, 左辺, 右辺 if 演算子 = "*" : 算出 = int(左辺) * int(右辺) if 演算子 = "/" : 算出 = int(左辺) / int(右辺) if 演算子 = "+" : 算出 = int(左辺) + int(右辺) if 演算子 = "-" : 算出 = int(左辺) - int(右辺) if 演算子 = "-" & 演算子番号 = 0 : 算出 = 0 - int(左辺) - int(右辺) : 算出 * -1 strrep 文字列C, 演算式, str(算出) loop await 1 loop mes "=" + 文字列C



この記事に返信する


kanamaru

リンク

2016/3/9(Wed) 13:34:26|NO.74835

試しに実行してみたところ、
答えが-7.4のはずなのに、
-7と表示されますね。
計算をdouble型で行うようにすればいいと思います。
無駄な処理は特にないと思います。
http://hsp.tv/play/pforum.php?mode=all&num=70812
のようにかっこに対応させてみてはどうでしょうか?



スペース

リンク

2016/3/9(Wed) 16:04:46|NO.74836

特に問題ないかと。

>kanamaruさん
作成途中のため、小数点以下は切り捨てで、問題に対応する処理が施されていないそうです。



ケイジ

リンク

2016/3/9(Wed) 16:08:26|NO.74837

>kanamaruさん
ご指摘とURL、ありがとうございます!
自身での使用は切り捨てでも問題はなかったのでint型で作成してしまいましたが、
やはり正確なのにこしたことはありませんからね! 頑張ってみようと思います!



Noap

リンク

2016/3/9(Wed) 16:39:54|NO.74838

そのモジュールはわたしがかいたのですが(そのときの名前はNoaでした)そのモジュールは確か動作が少しおかしかったのと、あまりにもきたないスクリプトなので、参考にはできればしてほしくないです。
整数と実数、どちらで計算するか切りかえられたらいいなとおもいました。



ケイジ

リンク

2016/3/10(Thu) 08:59:25|NO.74845

皆さん書き込みありがとうございます!
無駄な処理がないと言われ、安心して書き続けることができました。

汎用性の面から処理をモジュールに変え、
初めに書き込んだ問題点の修正。加えて、括弧の実装に至りました!

double型にも対応し、
型を変更すれば、実数・小数点以下切り捨ての切り替え可能です。

いくつか問題が見つかるかもしれませんが、
致命的なものはないと思われるので、解決とします。

ご協力ありがとうございました!
また困り事で書き込むかもしれませんが、その時もどうかよろしくお願いします。


以下はソースです。ご一読ありがとうございます!


// モジュール領域 #module // 文字列計算 #deffunc 文字列計算 str 式, val 解 代入式 = 式 // 括弧判定 repeat 括弧左 = instr(代入式, 0, "(") if 括弧左 != -1 { 括弧右 = instr(代入式, (括弧左 + 1), ")") if 括弧右 = -1 : dialog "括弧が閉じられていません。" : 解 = 0 : return 括弧右 += 括弧左 括弧内 = strmid(代入式, (括弧左 + 1), (括弧右 -括弧左)) 括弧式 = 代入式 括弧演算式 = "(" + 括弧内 + ")" 文字列計算 括弧内, 括弧解 strrep 括弧式, 括弧演算式 , str(括弧解) 代入式 = 括弧式 continue } break loop // 演算子の追加 strrep 代入式, "*", "*+" strrep 代入式, "/", "/+" strrep 代入式, "+-", "-" strrep 代入式, "--", "+" // 演算 repeat // 演算子の置換 評価 = 代入式 strrep 評価, "*", "A" strrep 評価, "/", "A" strrep 評価, "+", "B" strrep 評価, "-", "B" 位置 = 評価 strrep 位置, "A", " " strrep 位置, "B", " " // 演算子位置の割り出し dim 演算子位置 演算子位置 = instr(位置, 0, " ") if 演算子位置 != 0 : 代入式 = "+" + 代入式 : continue repeat if cnt = 0 : 演算子位置 = 0 : continue 演算子位置.cnt = instr(位置, (演算子位置.(cnt -1) + 1), " ") if 演算子位置.cnt = -1 : break 演算子位置.cnt += 演算子位置.(cnt -1) + 1 loop // 乗除の演算 対象位置 = instr(評価, 0, "A") if 対象位置 != -1 : { repeat if 演算子位置.cnt = -1 : break if 演算子位置.cnt != 対象位置 : continue if cnt = 0 { 左辺位置 = 0 } else { 左辺位置 = 演算子位置.(cnt -1) } if 演算子位置.(cnt + 2) = -1 { 右辺位置 = 対象位置 + 65536 } else { 右辺位置 = 演算子位置.(cnt + 2) } 演算子 = strmid(代入式, 対象位置, 1) 演算式 = strmid(代入式, 左辺位置, 右辺位置 -左辺位置) split 演算式, 演算子, 左辺, 右辺 if 演算子 = "*" : 解 = double(左辺) * double(右辺) if 演算子 = "/" { if 右辺 = "+0" : dialog "0で除算しました。" : 解 = 0 : return 解 = double(左辺) / double(右辺) } 解 = "+" + 解 strrep 解, "+-", "-" strrep 代入式, 演算式, 解 loop continue } 解 = double(代入式) if 演算子位置.1 = -1 : break // 加減の演算 左辺 = strmid(代入式, 演算子位置, 演算子位置.1 -演算子位置) if 演算子位置.2 = -1 { 右辺 = strmid(代入式, 演算子位置.1, 演算子位置.1 +65536) } else { 右辺 = strmid(代入式, 演算子位置.1, 演算子位置.2 -演算子位置.1) } 解 = double(左辺) + double(右辺) 解 = "+" + 解 strrep 解, "+-", "-" 演算式 = 左辺 + 右辺 strrep 代入式, 演算式, 解 await loop return // グローバル領域 #global sdim 式 objsize 640 式 = "-2+(2.32+5)*2+(2+2)/4" input 式 button "演算", *演算 stop *演算 color 255, 255, 255 boxf : color pos ,50 文字列計算 式, 解 mes 式 mes "=" + int(解) mes "=" + double(解)



ONION software Copyright 1997-2023(c) All rights reserved.