11048/11048 BQO00549 konno としきさんの msgview 完璧なツリー
( 1) 24/01/27 16:28 コメント数:1
今までとしきさんに何度も指摘されていた msgview 個別発言のツリーのバグですが
としきさんに私の msgview.cgi を見て頂き、修正していただきました。
おかげさまでツリー表示は完璧になりました。\(^^)/ ヤッタ-
としきさん、ありがとうございました。m(__)m
11053/11048 CXB00940 としき Re: としきさんの msgview 完璧なツリー
( 1) 24/01/28 13:58 11048:konnoさんへのコメント コメント数:2
参照先:http://toshiki.la.coocan.jp/
いやぁ、何とか動いてくれたようで助かりました。
一応、かなり複雑なツリー構造も含め、一通りの動作確認はしていますがね。
何せ、使ったデータが、うちの板塀のデータですから。
どんなチェック漏れがあるやら、想像もつきません。
というか、コードを書いた人が想像できないところにバグが忍び込むわけで。
そのうち、異常なパターンが発覚したら、そのたびに直すしか。
だって私、konnoさんのコードを読みきって修正したわけではなく。
正常な出力のallreadと異常なmsgviewを比較しただけなんで。
どういうロジックでツリーを出力しているのか、いまだによくわかっていない。
ま、動けば正義、というのはあるわけで。
とはいえ、動かないとき、だとか、動かなくなってしまったとき、のことを考えて
プログラミングしておいたほうが、いろいろと楽ができるとは思いますけど。
かつて、20年ぐらい前だったかな、同じ職場にいた人で、この人は楽をしたくない
のかな、わざと難しくなることを好んでいるのかな、マゾっ気があるのか? と
思わせられる人がいたことを思い出したりしました。
11054/11048 BQO00549 konno Re^2: としきさんの msgview 完璧なツリー
( 1) 24/01/28 17:37 11053:としきさんへのコメント コメント数:1
としきさん
> いやぁ、何とか動いてくれたようで助かりました。
としきさんのチェックなら間違いないと思っていました。
ありがとうございました。
> 一応、かなり複雑なツリー構造も含め、一通りの動作確認はしていますがね。
> 何せ、使ったデータが、うちの板塀のデータですから。
> どんなチェック漏れがあるやら、想像もつきません。
なるほど、人任せではなく自分でもチェックはした方がいいということですね。
お送りいただいた msgview3.cgi と自分の wforum.cgi で比較してみました。
wforum.cgi
($no,$re,$lx,$sub,$eml,$url,$nam,$dat,$msg,$lt,$ho,$pw,$wrap,$oya,$sml,$com) = split(/<>/);
$j++;
if ($in{'oya'} == $oya) { push(@new,$_);
msgview3.cgi
($no,$re,$lx,$sub,$eml,$url,$nam,$dat,$msg,$lt,$ho,$pw,$wrap,$oya,$sml,$com) = split(/<>/);
if ($in{'oya'} == $oya) { push(@new,$_);
$j++;
うげ、$j++; の位置が分岐前から分岐後になってる!!
他にも $mx=0; が追加されたり "}" の位置が、if の前になったりしていますね。
違いはこのくらいでしょうか。
実は昨日から STIME.EXE のソースを弄っていたのですが、うまく動かなくて・・・
色々調べたら、変数の設定を if 分岐の前にやっていたのが原因でした。(>_<)
どうやら私は分岐で躓く傾向があるようです。
> とはいえ、動かないとき、だとか、動かなくなってしまったとき、のことを考えて
> プログラミングしておいたほうが、いろいろと楽ができるとは思いますけど。
メールで言っていた、インデントや不要なコメントなどですね。
これからは気を付けるようにします。
> かつて、20年ぐらい前だったかな、同じ職場にいた人で、この人は楽をしたくない
> のかな、わざと難しくなることを好んでいるのかな、マゾっ気があるのか? と
> 思わせられる人がいたことを思い出したりしました。
うう、私のソースってそんなふうに見えているのですか・・・ (;_;)
11055/11048 CXB00940 としき Re^3: としきさんの msgview 完璧なツリー
( 1) 24/01/28 20:01 11054:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
実は私自身、$mxの初期化漏れってそんなに影響があるとは思っていませんでした。
でも、なんかうまく行かなかったので、わりと早い目に追加しました。
そして、$jは配列の添え字。
配列を設定する側で添え字のインクリメントが間違っていたため、配列を読み出す
部分で配列の正しい位置にアクセスしてもデータが取り出せず、未定義の情報で
条件判断するはめになってしまい、"┃"と空白のどちらを出力するかという部分が
うまくいっていなかったのでした。
> メールで言っていた、インデントや不要なコメントなどですね。
不要なコメントの部分、あれはほんと、まるで迷彩のような。
軍事用語でもありますが、私がコードを読んだ第一印象は、マージャン漫画での
この言葉。そして、SFへのマジレスでよくある、透明人間は回りを見ることが
できないとの説から、光学迷彩を放った本人(konnoさん自身)が迷彩にやられて
しまった、という感じも受けました。
インデントのほうはねぇ。こちらはちょっと長くなります。
これは、コーディングスタイルとかいって、スタイル、つまり美学の領域。
美学って確か、文太先生の専門だったような気もする。
それはさておき。
たとえば、最近のkonnoさんのBASICのコード。
最近いじった部分がわかるほうが良い、と思う人なら、昔のコードの部分は行番号
があって大文字、最近いじった部分は行番号無しで小文字にする、とか。一方で
統一感があったほうが美しいと思う人なら、全て大文字で行番号つきに統一、と
いろいろな考え方があるわけです。
でも、どの立場に立とうが、プログラムの論理構造、つまり順次・選択・反復と
いった構造をわかりやすくするためには字下げしかありません。既に30年以上
前から、これは当たり前のこととされています。昭和60年ごろに書かれた本には
「いまや字下げをしないプログラマは・・・」などという記述があったりします。
えぇと、いい機会だから書いてしまおうかな。
上記の本の紹介。#10398でも書いていますね。
林晴比古著「BASICによるプログラミングスタイルブック」
ISBN4-930795-28-1
定価1800円
昭和60年12月25日初版発行
私の持っているのは昭和61年11月の第4刷。
この本が出る2年位前からOh!PCに掲載されていたものがまとめられたのですがね。
この本が出た前後で、Oh!PCに掲載されるサンプルコード、特に学習用の講座などの
コードはみんな、なだれを打って、という感じで、読みやすいコードになりました。
その後、ベーマガのコードはあまり変わったようには見受けられませんでしたが、
ASCIIやI/Oのコードは、数年後には少し変わったかも。
> うう、私のソースってそんなふうに見えているのですか・・・ (;_;)
ま、私がとりわけぐうたら、と言うのもありますが。
プログラムを作るのって、結果が欲しいから作るものだと思っております。
なので、過程は楽をしたい。つまり、デバッグは楽なほうがいいと思っています。
だけど、あのコードは、なんかわざわざデバッグそのものを楽しむためのコードの
ような。
「デバッグ楽しいなぁ〜(;_;)」という経験の多寡でも考え方は変わるかも。
11057/11048 BQO00549 konno Re^4: としきさんの msgview 完璧なツリー
( 1) 24/01/28 22:48 11055:としきさんへのコメント コメント数:1
> 実は私自身、$mxの初期化漏れってそんなに影響があるとは思っていませんでした。
> でも、なんかうまく行かなかったので、わりと早い目に追加しました。
> そして、$jは配列の添え字。
> 配列を設定する側で添え字のインクリメントが間違っていたため、配列を読み出す
> 部分で配列の正しい位置にアクセスしてもデータが取り出せず、未定義の情報で
> 条件判断するはめになってしまい、"┃"と空白のどちらを出力するかという部分が
> うまくいっていなかったのでした。
うう、やっぱり基本がわかっていないとこういうミスを出しやすいのですね。
今回 BASICでも同じようなところで躓いて直すのにえらく時間がかかってしまいました。
> 不要なコメントの部分、あれはほんと、まるで迷彩のような。
> 軍事用語でもありますが、私がコードを読んだ第一印象は、マージャン漫画での
> この言葉。そして、SFへのマジレスでよくある、透明人間は回りを見ることが
> できないとの説から、光学迷彩を放った本人(konnoさん自身)が迷彩にやられて
> しまった、という感じも受けました。
私も義体化が進んできたので、バトーのようになるのでしょうか。(違)
BASICではコメントを緑に表示しているので、マジで迷彩服のようになってます。(^^;
> 上記の本の紹介。#10398でも書いていますね。
> 林晴比古著「BASICによるプログラミングスタイルブック」
うう、いまさら聞けないBASIC みたいに微妙な・・・ 見かけたら読んでみたいですね。(^^;
> だけど、あのコードは、なんかわざわざデバッグそのものを楽しむためのコードの
> ような。
> 「デバッグ楽しいなぁ〜(;_;)」という経験の多寡でも考え方は変わるかも。
↑ ↑
ククッ、、思わず吹いてしまいました。
まさに私のことを的確に言い当てているような。(^^;
11059/11048 CXB00940 としき Re^5: としきさんの msgview 完璧なツリー
( 1) 24/01/29 01:43 11057:konnoさんへのコメント コメント数:2
参照先:http://toshiki.la.coocan.jp/
追伸というか。
きちんと理解できていないというのもあって。
もしかしたら、$mxの初期化って、それほど重要ではないかもしれない。
ただ、少なくとも、allreadのほうでは初期化してあったような。
それに、初期化しておいて害になることもないし。
> > 上記の本の紹介。#10398でも書いていますね。
> > 林晴比古著「BASICによるプログラミングスタイルブック」
> うう、いまさら聞けないBASIC みたいに微妙な・・・
私には、文体が引っかかるんですよ。
ただ、この時代のコンピュータの本を書く人って、特徴的な文体の人が何人かいて。
もう一人、ナツメ社あたりからアセンブラか何かの本を出していた人で、どうにも
文体が肌に会わなかった人がいたような記憶もある。
さて。
よく見たらタイトルが微妙に違う。
「BASICによるプログラミング・スタイルブック」
と、中黒があるのが正解。
章立ては
STEP1 基本を知る
STEP2 型にはめる
STEP3 サブルーチンの整理
STEP4 視点を変える
STEP5 工夫に、工夫を
となっている。中身に文法解説はほとんどない。
章の中の各節は、抜粋ですがたとえば
1 BASICの能力を見直そう
5 字下げをしよう
9 意味のわかる変数名にしよう
12 ブロック構造にしよう
15 マルチステートメントは上手に使おう
16 空白を入れよう
19 行番号をそろえよう
といった項目が46個あり、各節の中でそれぞれ根拠と共に例示がなされている。
当時の普通科高校生でも十分読める文章でしたから、文章としては今なら中学生
にも理解できると思う。いや、BASICのほうを解説してやらんとダメか。
さて、それでは、ちょっと一休みして。
つぎはいよいよ、konnoさんご希望の、掲示板検索ルーチンに取り掛かってみますか。
って、いつ開始するか全くめどは立っていませんが。
11061/11048 CRG00666 文太 Re^6: としきさんの msgview 完璧なツリー
( 1) 24/01/29 11:46 11059:としきさんへのコメント コメント数:1
ククッ、、思わず吹いてしまいました。
会話の意味がまったく分からない。これが日本語であることは認知して
おりますが。
それより、おお、そんな会話があったのか、1年ちょっと前。すごい
記憶力 >としきさん。もちろん、検索したのは分かりますが。
というわけで、 林晴比古著『BASICによるプログラミング・スタイルブック』
を図書館で探してみましょう。(注)
解説:まったく本腰が入ってませんが、僕は BASIC に興味をもっている
のですね。だから、この前のオフ会にも岡田元治さんの BASIC コンパイラの
マニュアル・プリントアウトを持って行ったのです。「ハノイの塔」の
コード・プリントアウトとともに。
学習は「ハノイの塔」とは何か? から始まる予定。まだ始まらない……。
>小さい円盤の上に大きいものを重ねることはできない。 [補説]フランスの数学者
>リュカによって1883年に考案された。 発売時に、アジアに伝わるパズルという
>架空の設定で宣伝されたため名付けられた。
という語源だそうです。ベトナムはベトナム戦争の前までフランスの
植民地でした。日本もほぼ瞬間的に植民地化しましたけれど。
ああ、インパール作戦。
konnoさん、
konnoさんのお祈りのおかげで、例の地獄の作業、あの日のうちに終わりました。
いまは次の修羅場に備えております。ふらっふらになった記憶は新しいのですが、
そのとき、ちゃんと konnoさんに感謝し、お祈り返しもいたしました。m(__)m
鈴木康弘大先輩、
お初です! いらっしゃいませ!!! Win7マシンでパーティション切り、DOS
(FAT16)ドライブ!!! やるぅ。
「Vzマクロほんとの入門」の作者さんですよね!!! お世話になりました。
江戸地方、今日は晴れです。(う、孝義さんだった。弟さん?)
(注)しかし、こういうのばっかですねぇ、>己。_Software Tools in Pascal_は、
Vz黒本の隣に鎮座している。ここから1メートル以内。
11062/11048 BQO00549 konno Re^6: としきさんの msgview 完璧なツリー
( 1) 24/01/29 15:41 11059:としきさんへのコメント
> もしかしたら、$mxの初期化って、それほど重要ではないかもしれない。
> ただ、少なくとも、allreadのほうでは初期化してあったような。
> それに、初期化しておいて害になることもないし。
変数の初期化は最近の速いCPUでは特に必要かもしれませんね。
初期化してないせいでタイミングが狂い挙動がおかしくなることもありそうで。
> よく見たらタイトルが微妙に違う。
> 「BASICによるプログラミング・スタイルブック」
> と、中黒があるのが正解。
内容の紹介を見て、読んでみたくなりました。
ちょっと前までは本を読む気にもならなかったのが、目が復活したら読書欲も復活?
> さて、それでは、ちょっと一休みして。
> つぎはいよいよ、konnoさんご希望の、掲示板検索ルーチンに取り掛かってみますか。
> って、いつ開始するか全くめどは立っていませんが。
おお、期待しています。(^_^)
ログ形式が同じならそのまま動くのではないかと思っています。
11066/11048 CXB00940 としき Re^7: としきさんの msgview 完璧なツリー
( 1) 24/01/30 12:45 11061:文太さんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> 学習は「ハノイの塔」とは何か? から始まる予定。まだ始まらない……。
「ハノイの塔」って、再帰のサンプルとしては非常に有名。
プログラム初心者に再帰を説明するのは「ハノイの塔」かフィボナッチ数列か、
というくらい。再帰を使ったほうがシンプルなものって、実生活ではあまり
見かけませんからね。
また、再帰でできるものは必ずループでもできるらしい。
なので、再帰からループへコードを変更するための題材にも使われるらしい。
で、ループならどうということもないのですが。
8ビットパソコンの時代のBASICでは、再帰というものが使えませんでした。
なので、そこでわざとループを使わず、いかに擬似的な再帰を実現するか、という
のも、ちょっと気取ったプログラマたちの力試しの例題に使われていたりして。
ま、再帰が使えない、という意味ではVzのマクロも同様。
だけど、Vzのマクロでも「ハノイの塔」はしっかりあるわけで。
結局、アルゴリズムなんて、どんな言語で実現しようが大差はないはず。
もちろん、向き不向きはあるでしょうが。
11074/11048 CRG00666 文太 Re^8: としきさんの msgview 完璧なツリー
( 1) 24/01/31 20:21 11066:としきさんへのコメント コメント数:2
としきさん、
詳細にありがとうございます。もともと「再帰」を狙ってあのサンプルを
選んだわけではなくて、単に「BASIC って読みやすいね。英語じゃん」という
だけだったのですが、この際ですから、「再帰」と「ループ」がどう違うのか
分かってやろうじゃないの、という気分になっています。
多謝です。
とはいえ、もうちょい待って。次々いろいろ起こるのですよねぇ、、、。
とほほ。
ま、岡田元治さんのコンパイラに通るコードは、構造化もできるし、
「再帰」もできるし、十分にモダンなもの、ということですね。
あ、マニュアルにね、FortranとかPascalとか出てきて(もちろん、
過去と歴史の話として)、そしてCは出てこなくて、そうですかぁ、よい
ですねぇ、その語り口というものでした。
まったく無駄話をしない学者肌な方ですが。
行くぞ、ハノイ! 3月あたり。「ハノイへ行ってみよう!」とかいう
タイトルで、少しは勉強してから、再帰いたします。
ありがとうございます。
そうそう、BASIC のユーザ変数に「型」がある、そのトークンがある、
というけっこう前の解説にも感謝していました。重ねてありがとうございます。
血糖値(糖尿)のあとは、胃がんか? やれやれ。
長生きするぞ!
11077/11048 CRG00666 文太 『スタイルブック』
( 1) 24/02/01 11:16 11074:文太さんへのコメント コメント数:1
どうでもよい追記です。書くのを忘れていました。少し古い話。
近場のも都立のも、図書館にはありませんでした。PC関係の古い本って
わりと廃棄される可能性が高いような印象。
というわけで、いちおう古書店をサーチ。ビンゴ! 送料込み \1220 。
こうして、書庫の肥やしが、いえ、さらなる幸福コレクションがもう1冊、
本棚に追加される予定です。今日か明日には、着くのではないかしら。
ま、どうでもよいことですが。
11079/11048 CXB00940 としき Re: 『スタイルブック』
( 1) 24/02/05 18:20 11077:文太さんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> 本棚に追加される予定です。今日か明日には、着くのではないかしら。
もう届いていそうですね。
ま、気が向いたら本文を読みましょう。
推理小説でもありませんから、結末から読まなくても大丈夫。
#おいこら
とりあえず、序文と目次くらいは読んでおいてもいいかも。
内容に対する批判はあったかもしれないけど、文体が合わない、というのは私くらい
のものでしょう。あ、でも、雰囲気が合わなくて上村さんの本に手を出さなかった、
というのはめざらさんでしたっけ。
そして、私の場合、文体ではなく内容のほうは、とても勉強になりました。
本文で作者は
> だから、筆者の書くプログラムは使用する言語がBASICだろうがCだろうがPascal
> だろうが、ほとんど同じスタイルをしている。
と書いていますが、私も、BASICだろうがPerlだろうがVzマクロだろうが、ほとんど
同じようなスタイルのプログラムになっています。この辺はまさに、この本からの
影響でしょう。
11080/11048 BQO00549 konno ハノイを目指して
( 1) 24/02/05 23:23 11074:文太さんへのコメント コメント数:1
文太さん
> 行くぞ、ハノイ! 3月あたり。「ハノイへ行ってみよう!」とかいう
> タイトルで、少しは勉強してから、再帰いたします。
ハノイの塔の話題が出たので、見てみたら VZマクロと Turbo Basic のサンプルソースにありました。
Turbo Basic のはそのままコンパイルできて、USモードで実行出来ました。
プレート 17枚でも数秒で完了するほど高速で、目に見えないので ウエイトを入れました。
自分好みの改造が整ったら公開しようかな。?
VZマクロは、軟体にある田野村さんのマクロで、プレート12枚まで実行出来ますが、流石に遅いです。
枚数を 14枚まで増やしたり、高速化の改造をして、ある程度形になりました。
秒数の比較
オリジナル 改造
数n 回数i W80*25 W136*35 W80*25 W136*35
12 4095 89秒 95秒 47秒 52秒
13 8191 112秒
14 16383 240秒
↑
1枚増えるごとに約2倍の回数というのが面白いですね。
さて、これらのマクロや BASIC(実行ファイルのみ)をアップしたら
文太さんの勉強にかえって邪魔になってしまうかな。(^^;
# タイトル変更した。これで安心。(^^;;
11081/11048 CRG00666 文太 Re^2: 『スタイルブック』
( 1) 24/02/06 17:20 11079:としきさんへのコメント コメント数:1
ハノイへようこそ、じゃないな。
手を動かさず、クチばっかり動かしている文太です。
目で活字を追うだけの日常は、まだまだ続くのですが。
あ、体ぜんぶを使って、雪かきはしましたよん。
さてさて、良書だろうと思います。ちらちら眺めただけですが。
>私も、BASICだろうがPerlだろうがVzマクロだろうが、ほとんど
>同じようなスタイルのプログラムになっています。
こうなるでしょうね、この抽象度の高さだと。
えーと、あれだけ詳細に内容を紹介していたので、あ、わたくしに
買えと仰ってる、と誤解したのです。これは、konnoさんが勧められて
いる本でした。
が、僕も楽しくよめそうですよ。BASICのコードを覚えながら。
konnoさんが勧められている点とは違いますが(?)、−−ごめん
なさい、長すぎて引用できません >konnoさん−−、たとえば、
p.231。まあ、広義に文体と言ってもいいですが、この作者の読者
への姿勢みたいなのは、僕も鼻につきました。僕は、何かを伝える
人が偉そうなのは好きです。僕に何かを教えてくれる人はみな先生で、
「先生はいつも偉い、絶対的にエライ」と思っています。
が、ここ、しつこい。「自己満足におちいり、自己陶酔にひたる」。
ここでお仕舞でいい。この上の段落も4行ぐらい削除したい。この
段落も残り全部カットしたい。説教がうるさすぎ、という印象ですね。
具体的に中身のあることを語れ。
ま、これも一度はまると、このムチが快感、となることもあるので、
こちらの気分次第という面もあろうかと思いますが。
と、同調して批判的なことを書きましたが、これがなければ、という
気持ちです。ゆっくり3回読む価値はあるな、と思っています。
本を手に取れる人にしか通じない書き方でごめんなさい。
konnoさん、僕はちょっと時間がかかりそうですので、熱いうちに、
としきさんに借りてみましょう!
田野村さんでしたか、そんな記憶がおぼろげにありましたが……。
あの人、そういう本格的な王道を生きた人でしたね。
が、僕の手、動かず。
11082/11048 BQO00549 konno Re: ハノイを目指して
( 1) 24/02/06 23:52 11080:konnoさんへのコメント
タイトルに合わせてこちらにレスします。
ハノイの塔のマクロ関連情報を得ようとnifty会議室の過去ログを検索しましたら
としきさんの書き込みがありました。
> 18134/19000 PEB03250 としき 再帰マクロ
> (15) 01/03/24 00:49 コメント数:2
> マクロで再帰を使う実験をしてみました。
> = フィボナッチ数
>
> では、ついでにもう一つ。
> 昔、再帰が使えない N88-BASIC で使った、配列を擬似的なスタックとして使うと
> いう技をマクロで使ってみました。別にスタック領域が足りない訳でもないのだ
> から、素直な push pop でもいいと思いますが。
> = ハノイの塔
今回はソースは省略しますが、#11066 の としきさんの書き込みを思い出しました。
> プログラム初心者に再帰を説明するのは「ハノイの塔」かフィボナッチ数列か、
> というくらい。再帰を使ったほうがシンプルなものって、実生活ではあまり
> 見かけませんからね。
> また、再帰でできるものは必ずループでもできるらしい。
> なので、再帰からループへコードを変更するための題材にも使われるらしい。
23年前に実際にマクロコードを書いていたのですね。流石です。
> で、ループならどうということもないのですが。
> 8ビットパソコンの時代のBASICでは、再帰というものが使えませんでした。
> なので、そこでわざとループを使わず、いかに擬似的な再帰を実現するか、という
> のも、ちょっと気取ったプログラマたちの力試しの例題に使われていたりして。
> ま、再帰が使えない、という意味ではVzのマクロも同様。
この再帰というのが私はいまいち理解できていなくて。
BASIC で言えば、サブルーチンの中でそのルーチンの先頭に飛んで条件を満たすまで繰り返す。
みたいな感じでいいのかしら。
実際VZマクロでもそういう動作をしているように思いました。
としきさんのコード、わかりやすそうですね。
いつか使わせてもらうかもしれません。
11083/11048 CXB00940 としき Re^3: 『スタイルブック』
( 1) 24/02/07 02:12 11081:文太さんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
雪は夜更けすぎに、雨へと変わるだろう、サイレ(以下略)
俺は何を歌っているのだ。
いやぁ、2月5日は深夜、23時ごろになって大雪も峠を越えて、みぞれか雨か、
というものが弱く降ってくるだけになったので、そこから雪かき開始。
だって、6日は日勤で出社しないといけないのだもの。
結局、1時間あまり汗を流して、自宅前の道路の雪は概ね撤去。
撤去した雪のほとんどは、自宅の庭に放り込みました。他に置く場所がないから。
多少は側溝にも押し込みましたけどね。
それから入浴して就寝は2時過ぎ。
だけど、夜通し続いた落雪の音がまるで爆撃のようで、一晩中まんじりとせず。
6日は普通に5時起きして、いつもより5分早く6時前には出社。眠い。
ちなみに、7日も日勤なので5時起き予定。
あぁ、掲示板に書き込んでる余裕なんてない。はず。
7日も眠そうだ。
それはさておき。
> さてさて、良書だろうと思います。ちらちら眺めただけですが。
以前にも書きましたが、内容については、王道も王道。
重箱の隅はともかく、全体的には、あまり批判できない。
ところで、この本、雑誌連載をまとめたものです。
不定期連載みたいな形で、1年ぐらいに渡って書かれたものだったかと。
当然、読者からの感想みたいなものが編集部に届くわけですよ。
そんな中に「これはもはや宗教だ」みたいな内容が混じっていたことがあったらしい。
でも、決してそんな事はない。
他のえらい学者さんたちが唱えたことのBASICでの実装例をひたすら紹介しているだけ
の、単なる工学の本です。
ただ、対象とする読者層の設定には苦労したと思う。
だって、中身は大学の学部情報科の初級クラス。
だけど、実際にその雑誌を読んでいる人や読んでほしい人といったら、プログラムを
専門としていないけど業務命令その他でプログラムを作成するハメになった社会人
から小中学生まで、多岐に渡るわけです。そして、それら全ては素人前提。
いわば、英語の先生が、大学英文科で教えるような正当な文法を、小学生から社会人
までをすべて対象とする1冊の教科書を作る、みたいなもので、ある程度の無理が
発生するのは当然かもしれません。そして、そのしわ寄せとか作者へのプレッシャー
といったものが、どこかで発現してもおかしくはないと思います。
だけど、雑誌連載時も否定的な意見は届いたはずだけど、そこそこ少ないはず。
なぜなら、連載継続とか単行本出版という結果に至ったわけだから。
ということは、ある程度の成功と推測してもいいんでしょうね。
11084/11048 CRG00666 文太 Re^4: 『スタイルブック』
( 1) 24/02/08 00:27 11083:としきさんへのコメント コメント数:1
としきさん
雪かきと落雪の爆撃への守り(寝れんぞ)、お疲れ様でした。
すごいなぁ、その体力。うらやまし。
>他のえらい学者さんたちが唱えたことのBASICでの実装例をひたすら
>紹介しているだけの、単なる工学の本です。
はい、「構造化は BASIC でも十分できる」という本ですね。
「えらい学者さんたち」とは、クヌース、カーニハン、リッチー、
ダイクストラ、N・ヴィルトなんて人たちです。
プログラミングって何? と思ったことのある人なら、聞いたこと
のある名前たち。
王道。
(僕的には、〔少し嘘かもしれないけど〕榊原さんがsyoさんに
教えていたことの反復、という印象でした。自己評価、高すぎかな?)
僕としては、ここ3年くらい、楽しく考えてきたこと(Fortran, Pascal,
Ratforなどを題材に)が、きれいに整理されてるな、というのが
『プログラミング・スタイル』についての最初の感想でした。
>いわば、英語の先生が、大学英文科で教えるような正当な文法を、
>小学生から社会人までをすべて対象とする1冊の教科書を作る、
>みたいなもので、
あまり良い比喩とは言えないかと愚考いたします。そんなの、まず
僕には無理で、嫌だ、そんな仕事、やらないからね、と言うような
問題設定。
でも、初出雑誌が何だったか思い出せませんが、やっぱり
「プログラミングって何?」という興味と動機のある人たちが読者
だったんじゃないのかな、と想像します。
「動いた、楽しい!」という経験がある人たち。
おお、Cも出てきた。林先生、この時期にコンピュータの全体像を
把握されていらっしゃったのですね、と思いました。
この本の初版は、「昭和60年12月」=1985年。僕の本は、
2刷(昭和61年)。僕が、将来まさかPC方面に関心をもつなんて、
夢にも思わなかった時代の本。
すごい本ですね。自信はありませんが、色あせない本です。
11085/11048 CXB00940 としき Re^5: 『スタイルブック』
( 1) 24/02/10 20:45 11084:文太さんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> あまり良い比喩とは言えないかと愚考いたします。そんなの、まず
> 僕には無理で、嫌だ、そんな仕事、やらないからね、と言うような
> 問題設定。
確かによい比喩ではないと思う。
でも、ならどう例えればよいかというと、あまり思いつかない。
文太さんは知っていると思うけど、私、あまり例え話が得意ではないので。
ちなみに、初出雑誌は、当時の日本ソフトバンク社の月刊「Oh!PC」。
当時のソフトバンクが出していた、いわゆる機種別誌というヤツですね。
広告によると、当時は他に
月刊「Oh!MZ」
隔月刊「Oh!FM」
季刊「Oh!HC」「Oh!55」
などといった雑誌が出ていたようです。
最初の掲載は1983年10月。本棚から引っ張り出してきました。
懐かしいですね。というか、しまいこまれず本棚にあると言うのがなんとも。
最初の掲載時は、まだその後が続くとは思われておらず、特集扱いでした。
あ〜、読み直しているうちにだんだん思い出してきた。
最初のうちは、それほど文体にも引っ掛かりを覚えなかったんですよ。
単なる、淡々とした文章だ、と言うだけで。
なので、単行本化されたときも大して加筆されていないという評判を聞いたもので、
なら雑誌掲載記事は全て持っているわけだからわざわざ買うには及ばないな、と判断
して、すぐには購入しなかったのですよ。ただ、やはり毎回大きいサイズの雑誌を
引っ張り出すよりは小さくまとまった単行本のほうがいいという判断で、最初に発売
されてから2〜3年ぐらいしてから購入したのでした。
だから、私の持っているのは昭和61年11月の第4刷。
たぶん、62年か63年になってから買ったはず。
上記、1983年10月号の目次をみると、以下のような記事があります。
まず、目次で特集の次に並んでいるのは、海外のCG展示会の記事。
次が「新作ゲーム画面集」。やっぱりみんな、ゲームが好きなんですよ。
ついで「超大型オリジナルプログラム第1部」としてPC-9801用の家計簿プログラム
が「パーソナルバランスシート」なる大仰なタイトルで載っている。
これは連載というより、複数回掲載の初回、という感じ。
そして「4つのBASICへの入門」というサブタイトルのついている講座。おそらく、
NECの各機種用のBASICの差異の解説まで踏み込もうとしているのではないかなぁ。
でも、このときはまだ第3回。
さらに「マシン語超入門講座」や「機械語熟語集」といった連載では8ビットのZ80が
対象。
「ミニフロッピーの活用法」という連載もあるけど、この号は番外編で、拡張メモリ
をフロッピー的に扱うソフトが掲載。ま、RAMディスクですね。しかも、これの対象は
8ビットパソコンであるPC-8001とPC-8801。他の号をみていないけど、この連載が
そもそも8ビットパソコン対象なのかも。
そして、ハードウェア工作の「PC工作入門」は、この号ではPC-9801用の記事だけど、
それまでの記事はみんな8ビットパソコン用だったらしい。
さらに、機種別のページも、取り上げられているのは8ビットマシンだけ。
つまり、業務にもバリバリ使える16ビットパソコンは、まだまだ黎明期。
この時期のこの雑誌が、ソフトウェア工学の、ある意味で理論的な記事を掲載すると
いうのは、少なくともニーズとしては顕在化していないはず。
というか、ミスマッチもいいところ。
また、商業的な意味では冒険というか、よく掲載に踏み切ったものだと思います。
そして実際、このときか2回目の掲載のときか、連載陣の一人がけんかを吹っかけた
というか婉曲に批判したけど、そもそもけんかにならず、逆にその人の連載が終了
するハメになっていたり。さすがに打ち切りではなく、最終回まで掲載されたけど。
ということで
> 「プログラミングって何?」という興味と動機のある人たちが読者
> だったんじゃないのかな、と想像します。
これはどうなんだろう。
konnoさんならあのころのベーマガとかの雰囲気を覚えているかもしれない。
みんな、いかに自分のアイディアを実装するかしか考えていないような感じ。
なので、その先、というか、どうすれば効率的にバグなく実装できるか、などという
ところまでは思い至っていないんですよ。
特にゲームなんかはある意味で一発勝負のようなところもあったし。
11086/11048 BQO00549 konno Re^6: 『スタイルブック』
( 1) 24/02/10 22:48 11085:としきさんへのコメント コメント数:1
> > 「プログラミングって何?」という興味と動機のある人たちが読者
> > だったんじゃないのかな、と想像します。
>
> これはどうなんだろう。
> konnoさんならあのころのベーマガとかの雰囲気を覚えているかもしれない。
このころベーマガとか読んでいたかは覚えていませんが、BASICはやってましたね。
当時円弧と直線の交点だったかを求めるのに方程式がわからなくて困ってしまい
ポケコンのBASICで2分法というのを使って、それですました記憶があります。(^^;
> みんな、いかに自分のアイディアを実装するかしか考えていないような感じ。
> なので、その先、というか、どうすれば効率的にバグなく実装できるか、などという
> ところまでは思い至っていないんですよ。
まさにそのとおりで、プログラムを組めば仕事が楽になるという思いで必死でした。
パソピア16を見つけた時は、「こいつ、動くぞ」とつぶやきながらマニュアルをめくり
「武器はないのか」と見たら、BASIC で動いているのがわかり、自分でテキをやっつける
武器を作り、大危険に突入していったのでした。(^^;
11089/11048 CXB00940 としき Re^7: 『スタイルブック』
( 1) 24/02/16 17:00 11086:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> まさにそのとおりで、プログラムを組めば仕事が楽になるという思いで必死でした。
最近konnoさんが公開されたBASICのコードを見ても、必死さはにじみ出ている感じ。
だけど
> 「武器はないのか」と見たら、BASIC で動いているのがわかり、自分でテキをやっつける
> 武器を作り、大危険に突入していったのでした。(^^;
作った武器が手作りの竹やり同然、かもしれず。
#この艦では勝てない・・・
先般、見せていただいたPerlのコードなんかも、工夫の跡は見て取れるのですが、
これ以上、どこにどう手を入れてよいかわからない。
いや、高度に完成されて手を入れる余地がない、という意味ではなく。
ちょっと手を入れたらすべて崩壊しそうなジェンガというか砂上の楼閣というか。
ソフトウェア工学の教育を受けていないから仕方ないのですが。
全面的なリファクタリングをしたくなってしまう。
逆にいうと、konnoさん、伸びしろは無限大。
今からでもきちんとソフトウェア工学の基礎を勉強してみるのも一興かと。
11091/11048 BQO00549 konno Re^8: 『スタイルブック』
( 1) 24/02/17 00:43 11089:としきさんへのコメント コメント数:1
> 作った武器が手作りの竹やり同然、かもしれず。
ランボーなら竹槍でテキを全部やっつけられるかも。(^^;
私はランボーではないので、乱暴なコードになってしまうのです。
> ちょっと手を入れたらすべて崩壊しそうなジェンガというか砂上の楼閣というか。
> ソフトウェア工学の教育を受けていないから仕方ないのですが。
まったくそのとおりです。
なんせ自分で昨日書いたコードが読めないのですから。(-_-;)
> 今からでもきちんとソフトウェア工学の基礎を勉強してみるのも一興かと。
最近物忘れが地方レベルになってきてるので、難しいですね。(^^;
11092/11048 CXB00940 としき Re^9: 『スタイルブック』
( 1) 24/02/17 11:33 11091:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> 最近物忘れが地方レベルになってきてるので、難しいですね。(^^;
アップル認定の世界最高齢のプログラマは現在88歳だとか。
そういう人にkonnoさんのせりふを聞かせたら「最近の若い者は〜」とか言いそう。
それはさておき。
konnoさんに勉強してもらってきれいなコードを書いてもらいたい、というのは決して
konnoさんのためではなく。
ざっくりレベルで、今のままのkonnoさんがバグのありそうなコードを3つ書き上げる
のに要する同じ所要時間で、勉強したkonnoさんならバグのなさそうなコードを5つは
書き上げられそう、という見積もりをしたのですよ。
つまり、それだけアウトプットの質・量が向上すると、私を始めみんながうれしい、
ということ。つまるところ、私利私欲なわけですよ。
あるいは、先日BASICのコードを公開されたように、今後はオープンソースの方向に
舵を切っていく、とか。
11094/11048 BQO00549 konno Re^10: 『スタイルブック』
( 1) 24/02/18 15:10 11092:としきさんへのコメント
> アップル認定の世界最高齢のプログラマは現在88歳だとか。
> そういう人にkonnoさんのせりふを聞かせたら「最近の若い者は〜」とか言いそう。
うう、それを言われたら弱音を吐けないではないですか。(^^;
まあ、何故か今は色々プログラミング欲が出てきて同時に2〜3種のコードを見てたり。(^^;
> ざっくりレベルで、今のままのkonnoさんがバグのありそうなコードを3つ書き上げる
> のに要する同じ所要時間で、勉強したkonnoさんならバグのなさそうなコードを5つは
> 書き上げられそう、という見積もりをしたのですよ。
> つまり、それだけアウトプットの質・量が向上すると、私を始めみんながうれしい、
> ということ。つまるところ、私利私欲なわけですよ。
そ、そんなこと言われたって木に登ったりなんかしないんだからね! (^^;
> あるいは、先日BASICのコードを公開されたように、今後はオープンソースの方向に
> 舵を切っていく、とか。
私はあくまで個人的な趣味でやっているので、その辺は変わらないかもしれないです。
11096/11096 BQO00549 konno MS-DOS Player の更新 2024/2/19
( 1) 24/02/20 22:06 コメント数:3
MS-DOS Player が立て続けに更新されていました。
http://takeda-toshiya.my.coocan.jp/msdos/index.html
---------------------------------------------------------------------
2024/2/19
strcpy_s()で、指定したバッファ長よりも長い文字列をコピー元として指定したときに、
例外0xc0000417が発生することがあるようです。
ひとまずstrncpyで処理をするように対策をいれました。
2024/2/18
cracyc様のforkから、更に修正を取り込ませていただきました。
INT 67h, AX=5B00h/5B01h/5B04hについて、BHに00h以外を指定したときにエラーを返すようにしました。
MDA(Monochrome Display Adopter)をサポートしました。
その代わりに、コンベンショナルメモリの上限がB8000hからB0000hとなり、32KBだけ減少しています。
(それでも、VGAのVRAMがない分だけ、通常の環境より64KB大きいのですが)
CRTC, Status Registerも、MDAのアドレスでアクセス出来るようにしたのと、同期信号を50Hzにしました。
2024/2/15
cracyc様とroytam様のforkから、修正を取り込ませていただきました。
FCBを使ったファイルアクセスと、MAME版i386コアのFPU周りの例外の修正などです。
また、MAME版i386コアのDAA/DAS/AAA/AAS/AAM/AAD命令を、DOSBoxの実装を基に修正しました。
Pentium4版で、testi386.exeが実機と同じ結果が得られるようになっています。
NP21/WのI386コアを、ver0.86 rev92 beta2相当に更新しました。
また、ビルド時のワーニングが出ないように修正しました。
環境変数のアクセス時に、正しくない環境テーブルを参照したときのチェックを強化しました。
最近のビルドでtesti386.exeが動かなくなっていた問題が解決しています。
メモリアクセスの処理を効率化しました。
基本メモリ、拡張メモリ、予約領域(VRAMなど)の順に、少ない条件分岐でアクセスできるようにしています。
微妙に処理速度が上がっているかもしれません。
---------------------------------------------------------------------
主にメモリやCPU関係の修正のようです。
処理速度が上がっていたらうれしいですね。
作者様に感謝します。
11097/11097 BQO00549 konno 素数を表示、カウントするテスト
( 1) 24/02/20 23:45 コメント数:3
TurboBasicで素数を表示、カウントするテストプログラムを作りました。
DOSVAXJ3 や MS-DOS Player の JP モードで動きます。
自己流で考えて作ったので間違いがある可能性はあります。
指定範囲は20から 10万まです。配列数や時間的な限界がこの辺ということで。
一応、1000 までは 合っていました。
Wikipediaを見ると
--------------------------------------------------------------------------
最も素朴な方法は、2 から √n 以下の素数まで順番に割っていく、試し割り法と呼ばれる方法である。
n が √n 以下の全ての素数で割り切れなければ n は素数である。
試し割り法は、n が大きくなるに従って、急速に速度が低下するため、実用的ではない。
--------------------------------------------------------------------------
私が考えた方法は、どうやらこの方法と同じようですね。
1万を超えると急速に速度が落ちて、10万くらいが限界のようなので。(^^;
SOSU4.EXE Ver.240220
・DOSVAXJ3 の VGAで動く 素数表示テストです。
・DOSVAXJ3 を起動したら、chev jp でVGAモードにして、SOSU4.EXE を起動してください。
・MS-DOS Player では、chej jp でVGAモードにすれば動作します。
・VTDOS では動作しません。
・ソースも付けます。
・1000までは合っていると思いますが、それ以上は保証できないので表示しません。
・1000を超えたら 数字や時間情報を SOSU.DAT に追加出力します。
・数字が大きくなると急速に速度が落ちるので、初めは 100くらいから始めてください。
・更新履歴
2024-02-20 公開用に色々弄りました。
2024-02-17 とりあえず作成?
動作保証はでき無いので実行は自己責任で。
自作、改作アプリの放置部屋に置きました。
http://tamaneko.world.coocan.jp/execom.htm
11098/11098 BQO00549 konno ハノイの塔マクロ HANOI.DEF の改造
( 1) 24/02/22 01:27 コメント数:3
ハノイの塔マクロ HANOI.DEF を改造しました。
オリジナルは、T.Tanomura さんの名作です。作者様に感謝です。
===== hanoi_k.def ハノイの塔 =====
; ハノイの塔マクロ HANOI.DEF
; (VZ Editor version 1.5/1.6 共通)
; (C) T.Tanomura, 1992/7/5, 1994/7/31
; h.konno 2024-02-22 円盤の枚数 1〜15 に改造、速度アップ
【機能】
ハノイの塔の問題を解きます。
【用法】
編集モードで起動し、円盤の枚数として 1〜15 の数を入力してください。
ハノイの塔の問題を知らない方は、最初は 3 にするといいでしょう。
【補足】
'Q' を押すと、中止になります。★##k
'G'(=go)を押すと、残りの移動を一気に行います。
マクロの連続実行を中止するには [ESC] を押せば止まります。★##k
マクロを中断したり実行後おかしくなったらオプション初期化してください。
改造して速度が倍近く上がっています。(当社比)★
下のリンクをクリックすると hanoi_k.def のソースが表示されます。
当社の新リンク機能です。(^_^)
#txt:hanoi_k.def
11099/11099 BQO00549 konno オートリンクで新機能 ファイルへのリンク
( 1) 24/02/22 17:37
BBSのオートリンク機能を応用して新リンク機能が出来ました。(^_^)
#11098 で使っています。
ソースは、wforum.cgi の最後の方
#--------------#
# 自動リンク #
#--------------#
sub auto_link {
# #txt:FILE text macro doc etc
$_[0] =~ s/(^|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC]|[^0-9a-zA-Z\/\#\"]+)#txt:([A-Za-z0-9_-]+\.[A-Za-z0-9]+)/$1<a href='http:\/\/tamaneko.world.coocan.jp\/bbs\/count\/count.cgi?mode=download;target=http:\/\/tamaneko.world.coocan.jp\/vz\/$2' title='Text'>#txt:$2<\/a>/g;
このように、サーバーのフォルダに置いたファイル名を指定すれば $2 の変数に置き換えて表示出来ます。
書式は
#txt:ファイル名
この機能を実現することでいくつかのメリットがあります。
・長いソースファイルも5文字のコマンド+ファイル名の直リンクで手軽に見ることができる。
・長いソースを張り付けて掲示板の閲覧性を損ねることを防げる。
・長いソースを張り付けてコピペするよりこのリンクを右クリックで即ファイル保存のほうが楽かも。
・長いソースやドキュメント類を見たくない人にも優しい。
・リンク済みのファイルは誰でも記事中に直リンクして手軽に参照できるので便利。
・手持ちのソースやドキュメント類を記事中で参照希望のメール送付等は前向きに検討します。
・オートリンクにカウンタを仕込んであるので閲覧数を確認できる。
この機能を思いついた動機は、上に書いていますが、本当は個人的趣味で不純なので内緒。(^^;
この機能が便利だと思ったらぜひとも他の掲示板でも採用願いたいです。(^^;
11100/11098 CXB00940 としき Re: ハノイの塔マクロ HANOI.DEF の改造
( 1) 24/02/23 00:33 11098:konnoさんへのコメント コメント数:2
参照先:http://toshiki.la.coocan.jp/
> ハノイの塔マクロ HANOI.DEF を改造しました。
> オリジナルは、T.Tanomura さんの名作です。作者様に感謝です。
実行してみました。gコマンドの速度は速いですね。
ただ、画面の表示が正しくないです。何が悪いのかな。
konnoさんのところではきちんと表示されているのでしょうから、私の環境かな。
Tanomuraさんのマクロは、正しく表示されています。
で、まぁ、マクロコードを読もうとしたのですが。
あきらめました。
なぜって、コードとコメントの混在で。
一応、読もうと努力はしたんですよ。
だけど、例えばコードの最初のほう、属性などのいくつかの変数をプッシュする
コードがコメントアウトされていて、でもその理由が明記されているわけでもなし、
明記せずとも暗黙で理解できるようなコードでもなし。
まぁ、コード本体というか内部ではこれらの属性が変更されていないからプッシュ
されていないのだろうな、とは想像できますが、ならばなぜ、わざわざ記載した
上でコメントアウトされているのか、全くの謎。
おそらく、konnoさん的にはこういうコードが理解しやすいのでしょう。
でも、申し訳ない、私は脱落しました。
もっとも、世の中には、いわゆる「汚いコード」というのがいくらでもあって、
そういうのに比べればkonnoさんのコードは、まだまし、といったところでしょう。
11101/11098 DGF01024 めざら Re: ハノイの塔マクロ HANOI.DEF の改造
( 1) 24/02/23 08:45 11098:konnoさんへのコメント コメント数:1
参照先:http://mezala.la.coocan.jp/
実行してみたところ,数回の移動でコマンドラインに降り,最終的に VZ が落ちました。
(「落ちた」は正確ではなく,VZの子プロセスから離脱……かな。戻れず強制終了。)
まず,最初にきれいに積み上がっていないです。
次のコードがあります……
#E #m #[ &k
……が,実行中にコマンドラインに降りるのは何故なのですか?
ここの意図についてコメントがないので,想像もつきませんが……
11102/11098 DGF01024 めざら Re^2: ハノイの塔マクロ HANOI.DEF の改造
( 1) 24/02/23 11:29 11100:としきさんへのコメント コメント数:2
参照先:http://mezala.la.coocan.jp/
> なぜって、コードとコメントの混在で。
(外野の言い訳になってしまうけれど)他の方のプログラムを改造する場合,
わたしも元の行をコメントアウトした上で,改造コードを記載してしまいます。
「ここをこうしたよ」ということを明示しているつもりなんですよね。
そういうのは,プログラミングに慣れた人には嫌われるのでしょうか。
田野村さんはタブを使わず4字下げだったので,それをそのまま行にコメントすると,
字下げが4の倍数にならずにグチャグチャした印象を与えてしまいますね。
> 属性などのいくつかの変数をプッシュするコードがコメントアウトされていて、
> でもその理由が明記されているわけでもなし、
グローバル変数のプッシュ/ポップの辻褄を合わせる努力をするよりも,
ローカル変数にしてしまえば他に影響はないという考え方なのでしょう。
ただ,はっきり言ってしまうと,典型的な「スパゲティ」になっているコードを
改善する気がない表明とも受け取られかねないわけで,見た目の印象以上に
コードを追う気力を失わせることはままあることかもしれないと思います。(自省)
上記は,自分への反省とか注意喚起という意味あいの方が強いかもしれません。
それより,わたしがちょっと引いたのは,
「マクロを中断したり実行後おかしくなったらオプション初期化してください。」
かな。
中断が予想される場合は,その処理を入れておくのがふつうかなと思います。
(まぁ,&k で拾う場合は終了処理が無理なことも多いんですけどね。)
11103/11098 BQO00549 konno Re^2: ハノイの塔マクロ HANOI.DEF の改造
( 1) 24/02/23 13:21 11100:としきさんへのコメント コメント数:1
> 実行してみました。gコマンドの速度は速いですね。
> ただ、画面の表示が正しくないです。何が悪いのかな。
> konnoさんのところではきちんと表示されているのでしょうから、私の環境かな。
試していただきありがとうございます。
画面表示は具体的にはどんな感じになるのでしょうか。
> Tanomuraさんのマクロは、正しく表示されています。
Tanomuraさんのマクロの回数の数字だけ増やしても80*25画面で平気で動作しますね。
環境に左右されないようしっかり作られているのは流石です。
> で、まぁ、マクロコードを読もうとしたのですが。
> あきらめました。
> なぜって、コードとコメントの混在で。
す、すみません、公開するなら修正前の不要なコメントは消すべきでしたね。
修正して差し替えます。m(__)m
11104/11098 BQO00549 konno Re^2: ハノイの塔マクロ HANOI.DEF の改造
( 1) 24/02/23 13:41 11101:めざらさんへのコメント
> 実行してみたところ,数回の移動でコマンドラインに降り,最終的に VZ が落ちました。
> (「落ちた」は正確ではなく,VZの子プロセスから離脱……かな。戻れず強制終了。)
げげ、これはヤバいですね、オプション絡みでしょうか。
スタートして直ぐと終了時に時間計測のためにコマンドラインに降りていますが
移動中は関係ないし、もしかして EP かなぁ。
時間計測部分はコメントにします。
> まず,最初にきれいに積み上がっていないです。
オリジナルで問題無いなら何かのオプションの影響ではないかと思いますが・・・
> #E #m #[ &k
> ……が,実行中にコマンドラインに降りるのは何故なのですか?
> ここの意図についてコメントがないので,想像もつきませんが……
上に書いたように時間計測のために追加したのをそのままにしていました。
プロンプトを $t$p$g にして時間表示させ、マクロの実行時間を測定しています。
これが悪さをしている可能性があるのでこの部分はコメントにします。
不完全なままアップしてすみませんでした。m(__)m
11105/11098 CXB00940 としき Re^3: ハノイの塔マクロ HANOI.DEF の改造
( 1) 24/02/23 13:42 11102:めざらさんへのコメント
参照先:http://toshiki.la.coocan.jp/
めざらさんのところでも同じようですが、うちも最初が正しく積みあがっていません。
> わたしも元の行をコメントアウトした上で,改造コードを記載してしまいます。
> 「ここをこうしたよ」ということを明示しているつもりなんですよね。
> そういうのは,プログラミングに慣れた人には嫌われるのでしょうか。
コメントアウトされているのが全て改造前、ということがわかれば私はOKです。
それでも見づらいことは見づらいので、プログラミングに慣れた多くの人は嫌う
かもしれない。
概ね、プログラミングの世界では、例えばバグの混入を避けるなどの目的で、可読性
というものが重視されます。これもある種の理想論なんで、現実にはメモリ量とか
速度とかを目的として最適化というものも行われますが、でも最適化は最後の段階。
実際、遅いのはアルゴリズムが悪いことが多いので、アルゴリズムの見直しを行い、
それでも所要の性能が出ない場合に最適化する、というのが通常の段取り。
そういう潮流なので、コードが読みやすいことが尊ばれるのですよ。
ある種、読みやすさは正義、みたいな。
そして、読みやすくするためにはどうするか、という様々な研究もあって。
その中に、余分な情報は少なければ少ないほうが良い、というのもあります。
余分な情報は正しい認識を阻害する、ということから、私は迷彩という表現を使って
います。そして、このコードは何をする、というコメントなら多くの場合問題はない
のですが、旧のコードと新のコードが並列されていて、単にコメントアウトされて
いるだけ、という場合、混乱を招きやすいのではないかなぁ。
だって、行の途中を読んでいて、その行がコメントであるか確認するために行の先頭
に視線を戻して、という手間が発生するので、少なくとも私には心理的負担。
あるいは、例えばウィルスなんかだと「コードの難読化」なんていう技術が使われて
いたりします。つまり、わざと読みづらくすることにより、どういう挙動を示すか
わからないようにしているのですが、だから一部の口の悪いプロのプログラマーは
「そんなウィルスのようなコードを書くな」
などと後輩に指導して、もはやこの表現はパワハラ案件だという冗談もあるくらい。
> > 属性などのいくつかの変数をプッシュするコードがコメントアウトされていて、
> > でもその理由が明記されているわけでもなし、
> グローバル変数のプッシュ/ポップの辻褄を合わせる努力をするよりも,
> ローカル変数にしてしまえば他に影響はないという考え方なのでしょう。
すごい、きちんと読まれたのですね。
もう私、プッシュポップをしていないということは、これらは内部では使われて
いないんだ、というところでそれ以上読むことをあきらめていました。
> それより,わたしがちょっと引いたのは,
> 「マクロを中断したり実行後おかしくなったらオプション初期化してください。」
> かな。
私は逆というか、この表現を見た瞬間、画期的だと思いました。
積極的にオプションを初期化するって発想がなかったもので。
でも、過去の多くのコードを見てきためざらさんがそういう反応をするということ
は、これはいわゆるマクロ師的には邪道なのかもしれませんね。
11106/11098 CXB00940 としき Re^3: ハノイの塔マクロ HANOI.DEF の改造
( 1) 24/02/23 13:50 11103:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
まず、うちの環境では、めざらさんのところと違い、落ちたことは一度もありません。
> 画面表示は具体的にはどんな感じになるのでしょうか。
円盤が3枚のときの初期画面。(右側省略)
■
■■
■■■
~~~~~~~~~~~~~~~~~~~
円盤が3枚のときのgコマンドでの終了画面。(右端まで)
■ ■
■■
■■■■■■ ■■■
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
円盤の表示位置が正しくないようですが、空白での上書き消去は正しく行えているので
ゴミが残っている、というようにも見えます。
11107/11098 BQO00549 konno Re^3: ハノイの塔マクロ HANOI.DEF の改造
( 1) 24/02/23 14:03 11102:めざらさんへのコメント
> (外野の言い訳になってしまうけれど)他の方のプログラムを改造する場合,
> わたしも元の行をコメントアウトした上で,改造コードを記載してしまいます。
> 「ここをこうしたよ」ということを明示しているつもりなんですよね。
そのとおりなんですが、私の場合統一性が無く文字通りぐちゃぐちゃになってました。
流石にこのままアップしたのは不味かったですね。m(__)m
> 田野村さんはタブを使わず4字下げだったので,それをそのまま行にコメントすると,
> 字下げが4の倍数にならずにグチャグチャした印象を与えてしまいますね。
これは公開を考えたら統一するべきでしたね、修正します。m(__)m
> > 属性などのいくつかの変数をプッシュするコードがコメントアウトされていて、
> > でもその理由が明記されているわけでもなし、
修正前のコードをコメントして残すなら理由を明記するべきでしたね。
> グローバル変数のプッシュ/ポップの辻褄を合わせる努力をするよりも,
> ローカル変数にしてしまえば他に影響はないという考え方なのでしょう。
そのとおりですが、実際には不具合が出たようで、難しいですね。
> ただ,はっきり言ってしまうと,典型的な「スパゲティ」になっているコードを
> 改善する気がない表明とも受け取られかねないわけで,見た目の印象以上に
> コードを追う気力を失わせることはままあることかもしれないと思います。(自省)
m(__)m m(__)m m(__)m
> それより,わたしがちょっと引いたのは,
> 「マクロを中断したり実行後おかしくなったらオプション初期化してください。」
> かな。
> 中断が予想される場合は,その処理を入れておくのがふつうかなと思います。
中断とは、マクロを Ctrl Break などで強制的に止めるという意味だったのですが
このマクロは止まらないみたいですね。
なので、中止のコードを追加したのですが、そうするとプッシュポップの辻褄が合わなくなります。
変なところにポップしてメモリを壊すよりは変数保存のプッシュポップをやめるのがいいかと。
プッシュポップの辻褄が合わなくてもマクロを終了したら SP は初期化するかな。
と思ったのです。
不要なコメントを整理してコードも見直しますのでしばしお待ちください。m(__)m
11108/11098 BQO00549 konno Re^4: ハノイの塔マクロ HANOI.DEF の改造
( 1) 24/02/23 14:52 11106:としきさんへのコメント
> > 画面表示は具体的にはどんな感じになるのでしょうか。
>
> 円盤の表示位置が正しくないようですが、空白での上書き消去は正しく行えているので
> ゴミが残っている、というようにも見えます。
げげ、これはひどいバグですね。すみませんでした。m(__)m
80*25の画面でスペースがはみ出てしまってますね。
途中で数値変更して確認していませんでした。お恥ずかしい。m(__)m
諸々修正して再アップします。しばしお待ちください。m(__)m
11109/11098 BQO00549 konno ハノイの塔マクロ 改造差替え版
( 1) 24/02/23 18:09 11098:konnoさんへのコメント コメント数:2
ハノイの塔マクロ HANOI.DEF 改造の差し替え版です。
オリジナルは、T.Tanomura さんの名作です。作者様に感謝です。
バグバグの物を上げてしまいすみませんでした。m(__)m
コメントも整理しました。
これでめざらさんのところで問題なく動きますように。(-人-)
下のリンクをクリックすると hanoi_k.def 差替え版のソースが表示されます。
#txt:hanoi_k.def
11110/11098 DGF01024 めざら Re: ハノイの塔マクロ 改造差替え版
( 1) 24/02/23 21:03 11109:konnoさんへのコメント コメント数:1
参照先:http://mezala.la.coocan.jp/
ふつうに実行できました。
結局,何が問題だったのか分からないままでしたが……
11111/11098 BQO00549 konno Re^2: ハノイの塔マクロ 改造差替え版
( 1) 24/02/23 23:27 11110:めざらさんへのコメント コメント数:1
> ふつうに実行できました。
> 結局,何が問題だったのか分からないままでしたが……
問題なさそうで、ホッとしました。(^^;
コマンドラインに降りたのがまずかったと思い、EP0 にしたくらいですが
多分違いますよね。(^^;
ともあれ良かったです。(^_^)
11112/11098 CXB00940 としき ゾロ目を踏んだのはやっぱり管理人
( 1) 24/02/23 23:48 11111:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
いや、ほとんどT/Oで申し訳ない。
酔ってるもんで。
11113/11098 BQO00549 konno Re: ゾロ目を踏んだのはやっぱり管理人
( 1) 24/02/24 00:08 11112:としきさんへのコメント
> いや、ほとんどT/Oで申し訳ない。
> 酔ってるもんで。
あ、全然気が付きませんでした。(^^;
おめでとうございます。(って、自分に言うか)
11114/11098 CXB00940 としき Re: ハノイの塔マクロ 改造差替え版
( 1) 24/02/26 01:37 11109:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> ハノイの塔マクロ HANOI.DEF 改造の差し替え版です。
やっと試すことができました。
きれいに動いています。
ただ、うちでは、マシンのせいなのか、konnoさんのところほどTanomura版との差は
大きくなっていません。12枚で、Tanomura版だと45秒強、konno版だと35秒弱、
といったところです。
なお、実行したのはVTDOS、画面サイズは横80桁、縦50行です。
でも、konnoさんのところでは、画面サイズで実行速度が変わる、というのは面白い
ですね。速度が画面サイズに依存しないようにする、という改造もいいかも。
11115/11097 CXB00940 としき Re: 素数を表示、カウントするテスト
( 1) 24/02/26 13:22 11097:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> TurboBasicで素数を表示、カウントするテストプログラムを作りました。
中身を見させていただきました。
どうも解せない部分がいくつか。
冒頭、「DEFINT A-Z」と宣言されています。
これはいわば、ある意味お約束のようなものかもしれません。
でも、実際にコードの中で使っている変数は、整数の範囲外までサポートするため
実数型。だもので、いちいち実数指定の「!」が必要になっています。
これ、冒頭の整数宣言を外してしまったほうがよくありませんか?
コード全体をざっくり見た範囲で、整数型の変数は末尾の時間計測ルーチンで使って
いる変数ぐらい。なら、こちらのほうに整数指定をするほうがいいような。
で、尻尾から見ていって。
9050行、もしIERLが10000より大きければ、THENそのとき10000となっていますが、
THEN直後の数値はその行番号へのジャンプ。でも10000行ってないのですが、これで
いいのですか?
って、これ、コメント文になっているぅ〜!
またぞろ、konnoさんお得意の迷彩にやられちまったぜ。
9030行、「RESUME 9032」となっていますが、RESUME文て指定した行番号に処理を
飛ばす、という挙動だったはず。この処理系ではその他の副作用があるかもしれない
のですが、このステートメント、本当に必要ですか?
あ、ERRとERLがクリアされてしまうとかあるのかな。
であってもなくても、わざわざIERRとIERLに代入せず、そのまま表示してしまえば
余分な変数も使わずに済むし、コードはよりシンプルになる気がする。
ま、私のような処理系の挙動を把握していない人向けのコメントは不要として、
処理系の挙動を知っている人ですら疑問を抱きそうな部分にはきちんとコメントを
つけたほうが言いと思う。
と、言うところで、根性と時間がつきました。
今日のところはそんなところで。
11116/11098 BQO00549 konno Re^2: ハノイの塔マクロ 改造差替え版
( 1) 24/02/26 21:58 11114:としきさんへのコメント
> やっと試すことができました。
> きれいに動いています。
無事に動いたようでなによりです。(^_^)
> ただ、うちでは、マシンのせいなのか、konnoさんのところほどTanomura版との差は
> 大きくなっていません。12枚で、Tanomura版だと45秒強、konno版だと35秒弱、
> といったところです。
> なお、実行したのはVTDOS、画面サイズは横80桁、縦50行です。
うーむ、差が少ないのは気になるところですね。私の各種環境で比較してみました。
VTDOS org 69秒
VTDOS kon 33秒
CKWV+VTDOS org 63秒 80*25
CKWV+VTDOS org 69秒 136*34
CKWV+VTDOS kon 33秒 80*25
CKWV+VTDOS kon 36秒 136*34
DOSVAXJ3 64 org 70秒
DOSVAXJ3 64 kon 34秒
M Player pen4_x64 org 171秒
M Player pen4_x64 kon 71秒
ckwv のが時間が掛かると思いましたがそうでもないですね。
> でも、konnoさんのところでは、画面サイズで実行速度が変わる、というのは面白い
> ですね。速度が画面サイズに依存しないようにする、という改造もいいかも。
移動のたびに &d で全画面表示しているので大画面の方が不利かと思いましたが
オリジナルでも大画面の方が遅いですね。
MS-DOS Player は画面表示が遅いのかな、また検証してみます。
11117/11097 BQO00549 konno Re^2: 素数を表示、カウントするテスト
( 1) 24/02/26 22:12 11115:としきさんへのコメント コメント数:1
> 冒頭、「DEFINT A-Z」と宣言されています。
> これはいわば、ある意味お約束のようなものかもしれません。
> でも、実際にコードの中で使っている変数は、整数の範囲外までサポートするため
> 実数型。だもので、いちいち実数指定の「!」が必要になっています。
> これ、冒頭の整数宣言を外してしまったほうがよくありませんか?
> コード全体をざっくり見た範囲で、整数型の変数は末尾の時間計測ルーチンで使って
> いる変数ぐらい。なら、こちらのほうに整数指定をするほうがいいような。
全くその通りです、手抜きのために既存のルーチンを stime などから寄せ集めたもので。
冒頭の「DEFINT A-Z」も、
ON ERROR GOTO 9000:DEFINT A-Z
このように、エラールーチンにくっ付いていたのをそのままにしていたのでした。
> 9050行、もしIERLが10000より大きければ、THENそのとき10000となっていますが、
> THEN直後の数値はその行番号へのジャンプ。でも10000行ってないのですが、これで
> いいのですか?
> って、これ、コメント文になっているぅ〜!
> またぞろ、konnoさんお得意の迷彩にやられちまったぜ。
これも同じで、エラー処理が無いといきなり終了するので、とりあえず張り付けたのでした。
としきさんは、TAGLIGHT.EXE はお使いではないですか。
コメントなどが色分けされて非常に見やすくなります。って言い訳。
> 9030行、「RESUME 9032」となっていますが、RESUME文て指定した行番号に処理を
> 飛ばす、という挙動だったはず。この処理系ではその他の副作用があるかもしれない
> のですが、このステートメント、本当に必要ですか?
> あ、ERRとERLがクリアされてしまうとかあるのかな。
> であってもなくても、わざわざIERRとIERLに代入せず、そのまま表示してしまえば
> 余分な変数も使わずに済むし、コードはよりシンプルになる気がする。
> ま、私のような処理系の挙動を把握していない人向けのコメントは不要として、
> 処理系の挙動を知っている人ですら疑問を抱きそうな部分にはきちんとコメントを
> つけたほうが言いと思う。
これも同じ手抜きで、以下同文。m(__)m
11118/11096 BQO00549 konno 素数計算 SOSU4で MS-DOS Playerの速度計測
( 1) 24/02/26 23:05 11096:konnoさんへのコメント
MS-DOS Player の更新でメモリ関連が速くなったかもしれないので、
素数計算 SOSU4 で、各CPUのエミュレーション速度を計測してみました。
23-12-14版 24-02-19版
PC1 MS-DOS Player 231214 PC1 MS-DOS Player 240219
ia32_x64 ia32_x64
Number = 10000 0: 0' 3 Number = 10000 0: 0' 2
Number = 20000 0: 0' 9 Number = 20000 0: 0' 6
pentium4_x64
無し Number = 10000 0: 0' 5
Number = 20000 0: 0'14
i486_x64 i486_x64
Number = 10000 0: 0' 4 Number = 10000 0: 0' 2
Number = 20000 0: 0'14 Number = 20000 0: 0'14
i386_x64 i386_x64
Number = 10000 0: 1'40 Number = 10000 0: 1'39
Number = 20000 0: 5'31 Number = 20000 0: 5'27
i286_x64 i286_x64
Number = 10000 0: 0'45 Number = 10000 0: 0'50
Number = 20000 0: 2'29 Number = 20000 0: 2'42
v30_x64 v30_x64
Number = 10000 0: 0'43 Number = 10000 0: 0'45
Number = 20000 0: 2'21 Number = 20000 0: 2'30
ia32_x86 ia32_x86
Number = 10000 0: 0' 3 Number = 10000 0: 0' 3
Number = 20000 0: 0' 9 Number = 20000 0: 0' 9
pentium4_x86
無し Number = 10000 0: 0' 6
Number = 20000 0: 0'20
i486_x86 i486_x86
Number = 10000 0: 0' 6 Number = 10000 0: 0' 6
Number = 20000 0: 0'18 Number = 20000 0: 0'18
i386_x86 i386_x86
Number = 10000 0: 2' 4 Number = 10000 0: 2'13
Number = 20000 0: 6'51 Number = 20000 0: 7'22
i286_x86 i286_x86
Number = 10000 0: 0'47 Number = 10000 0: 0'56
Number = 20000 0: 2'33 Number = 20000 0: 3' 6
v30_x86 v30_x86
Number = 10000 0: 0'36 Number = 10000 0: 0'45
Number = 20000 0: 2' 2 Number = 20000 0: 2'28
こうしてみると、新しい版が少し速くなっているようですね。
でも i286 以下では逆に旧版より遅くなっているような。
計算式のアルゴリズムとの相性もあるかもです。
私が間違えてる可能性もあります。
i386 以下は CPU エミュレーション率が高いのか、遅くなっていますが
特に i386 が突出して遅いのが気になります。
CPUエミュレーションのルーチンはいくつか種類があると思いますが、
速さより正確さを優先した結果ということでしょうか。
うーん、この結果を武田さんに送ってみようかなぁ。
新しい版の ia32_x64 がメモリ速度では良さそうですね。
みなさん、CPUを選ぶときはこの表も参考にしてね。
11119/11097 CXB00940 としき Re^3: 素数を表示、カウントするテスト
( 1) 24/02/27 23:55 11117:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
私のようなずぼらと違って、konnoさんはまめな人なのか。
私の場合、何回も登場する実数型変数にいちいち型指定の接尾辞をつけるくらいで
あれば、何とかしてそれを省略できる方法を考えたりするわけですよ。打鍵数の節約
を含めて。そして、DEFINTの型指定範囲をどうにかできないか、というのが最初の
候補になる。
あるいは、konnoさんは昔の遅いインタプリタ時代のBASICに苦しめられた経験が
少ない、とか。
少しでも速度を稼ごうと思ったら、ループの中で多用される変数を整数型にする、
というのは基本として、もし実数型不可避となったら、短い変数名にしたり、とか、
いちいち型指定の接尾辞をつけずに済ませようとしたり、とか考えるわけです。
今回のコンパイラでは大丈夫、と読みきってそうしているのであれば、私の言って
いることは余計なお世話なので、大変申し訳ない。
手抜きというか楽をするために既存のルーチンをかき集める、というのは私もよく
やるし正しい行いだとは思いますが、でも、寄せ集めのそれらのルーチンがそれぞれ
何をやっているか把握しないでただくっつけるだけだと、しつこく取れないバグの
巣窟になることが多い。それはあとからボディブローのように効いてきて、トータル
では全く楽にならない、むしろ複雑になる、というのが非常によくある結末。
やっぱりkonnoさん、深層心理では楽をすることを嫌っているとしか思えない。
私のように、骨の髄まで楽をする事を考える人間とは大違い。
あるいは、バグが取れたという結果よりもバグ取りという過程のほうが好き、とか。
世間一般の多くのプログラマは、コーディングが楽しいとか完成してきちんと動いた
ときに満足感を感じる、という人のほうが多いらしいし、私もそうなのですが、何が
楽しいかなんていうのは当然ながら人それぞれ。
いつまでたっても動かないプログラムを永遠にデバッグしているのが楽しい、という
人がいたっておかしくないし、実際にkonnoさんのコードを見ると、konnoさんは
そういうタイプに見える。
プログラムが簡単に完成したらつまらないんでしょう。
TAGLIGHTは、HTMLの編集が楽になりそうなんで気にはなっているんですけどね。
色物はあんまり好きではないんですが、導入したほうがいいかなぁ。
でも、最終的なプログラムコードは、そういうものに依存するべきではないと思う。
ま、これは私の個人的な意見なんで、異論は認める。
私、昔はBASICだったし、あるいはポケ3でコードを組んでいたこともあって、白黒
がデフォルト。紙とペンでコーディングするときも、せいぜい赤ペン止まり。
プロのプログラマだと、紙とペンでコーディングする場合でも多色のマーカーを
使っていた、なんていう話は聞いたことがあります。
だから、以下のような替え歌ができたんだ、そうです。
胸につけてるマーカーで修正
自慢のデバッガでバグを撃つ
派遣の会社から僕らのために
来たぞ我らのプログラマー
20年とか30年前に聞いた歌詞なんで、もはやうろ覚え。
元歌に沿って、替え歌のほうも3番とか4番まであったはず。
上記の1番も、1行目はたぶん間違いないと思うけど、2行目以降はかなり妖しい。
だからなんだ、という話ですが。
11120/11097 BQO00549 konno 素数表示、カウント SOSU5.EXE 更新
( 1) 24/02/28 00:47 11097:konnoさんへのコメント コメント数:2
TurboBasicで素数を表示、カウントするプログラム SOSU5 に更新しました。
DOSVAXJ3 や MS-DOS Player の JP モードで動きます。
自己流で考えて作ったので間違いがある可能性はあります。
指定範囲は20から 30万まです。配列数や時間的な限界がこの辺ということで。
一応、300000 までは 合っていると思います。
今回指定数を3倍までにし、速度アップもしました。
起動時オプションで動作変更できます。
SOSU5.ZIP サイズ 30297bytes 24-02-27 new!
SOSU5.EXE Ver.240227
・DOSVAXJ3 の VGAで動く 素数表示テストです。
・DOSVAXJ3 を起動したら、chev jp でVGAモードにして、SOSU4.EXE を起動してください。
・MS-DOS Player では、chej jp でVGAモードにすれば動作します。
・VTDOS では動作しません。
・ソースも付けます。
・300000までは合っていると思いますが時間が掛かりすぎるので注意。
・数字や時間情報を SOSU.DAT に追加出力します。
・起動時オプション 1 で S000.DAT に素数を出力します。
・起動時オプション 2 で 表示もファイル出力もしません。カウントのみ。
・数字が大きくなると急速に速度が落ちるので、初めは 100くらいから始めてください。
・更新履歴
2024-02-27 V5 バグ取りや速度アップやファイル出力など。
2024-02-20 V4 公開用に色々弄りました。
2024-02-17 V1 とりあえず作成?
動作保証はでき無いので実行は自己責任で。
http://tamaneko.world.coocan.jp/execom.htm
11121/11097 BQO00549 konno Re^4: 素数を表示、カウントするテスト
( 1) 24/02/28 01:23 11119:としきさんへのコメント コメント数:1
> 私のようなずぼらと違って、konnoさんはまめな人なのか。
逆に私はずぼらで、としきさんはマメな人だと思っていました。
> 私の場合、何回も登場する実数型変数にいちいち型指定の接尾辞をつけるくらいで
> あれば、何とかしてそれを省略できる方法を考えたりするわけですよ。打鍵数の節約
> を含めて。そして、DEFINTの型指定範囲をどうにかできないか、というのが最初の
> 候補になる。
昔は私もそういうことを考えていた気がします。今は劣化して考えられなくなっただけかも。
> あるいは、konnoさんは昔の遅いインタプリタ時代のBASICに苦しめられた経験が
> 少ない、とか。
としきさんには私はそう見えるわけですね。
私は私なりに遅いインタプリタでいかに処理速度を上げるかで必死だったんですけどね。
そのために「スーパーBASIC」という本を買って、色々参考にした覚えがあります。
> 少しでも速度を稼ごうと思ったら、ループの中で多用される変数を整数型にする、
> というのは基本として、もし実数型不可避となったら、短い変数名にしたり、とか、
> いちいち型指定の接尾辞をつけずに済ませようとしたり、とか考えるわけです。
昔はそういう考えが基本的にあったと思います。今は何も考えていないですね。(^^;
> 今回のコンパイラでは大丈夫、と読みきってそうしているのであれば、私の言って
> いることは余計なお世話なので、大変申し訳ない。
コンパイラになって、変数名の長さとか関係なくなってあまり気にしなくなったのはあります。
> 何をやっているか把握しないでただくっつけるだけだと、しつこく取れないバグの
> 巣窟になることが多い。それはあとからボディブローのように効いてきて、トータル
> では全く楽にならない、むしろ複雑になる、というのが非常によくある結末。
確かにその通りですが、私はとりあえず動くのを優先に考えてしまう癖があるようです。
> やっぱりkonnoさん、深層心理では楽をすることを嫌っているとしか思えない。
これは無いと思いますが、そう見えるのですか。
> 私のように、骨の髄まで楽をする事を考える人間とは大違い。
私にはそうは見えなかったり、考え方が人それぞれなゆえですかね。
> あるいは、バグが取れたという結果よりもバグ取りという過程のほうが好き、とか。
私はバグが無い方がいいし、バグ取りは基本嫌です。
> いつまでたっても動かないプログラムを永遠にデバッグしているのが楽しい、という
> 人がいたっておかしくないし、実際にkonnoさんのコードを見ると、konnoさんは
> そういうタイプに見える。
見え方は人それぞれですから、しかたがないですね。
> プログラムが簡単に完成したらつまらないんでしょう。
そういう境地になれたらいいなとは思います。絶対になれないので。
> TAGLIGHTは、HTMLの編集が楽になりそうなんで気にはなっているんですけどね。
> 色物はあんまり好きではないんですが、導入したほうがいいかなぁ。
Windowsの高機能エデイタは大抵色分け機能を持っていますね。
そういうのを使ってみたいとは思うのですが、VZの使い勝手は別格と思うので。
> だから、以下のような替え歌ができたんだ、そうです。
替え歌がさくっと出来るのもクリエイターならではですね。(^_^)
11122/11097 CXB00940 としき Re^5: 素数を表示、カウントするテスト
( 1) 24/02/28 17:45 11121:konnoさんへのコメント
参照先:http://toshiki.la.coocan.jp/
コードからにじみ出てくる人柄なんて当てにならない、というのが結論でしょうか。
> 逆に私はずぼらで、としきさんはマメな人だと思っていました。
この辺は相対的なものもありますがね。
親戚一同から学生時代の友人、会社での知り合いにいたるまで、他人からの評価
では、世間一般の平均からすると私はずぼらの範疇に入るらしい。マスコミなんか
の報道やネットニュースを参照することによる自己評価でも、やっぱり私はずぼら
だと思っています。
うちの父はマメな人でしたが、うちの母は
「うちの子供たちはみんな私の血を継いだ」
なんていっていて、自分でもそのとおりだと思っています。
> 昔は私もそういうことを考えていた気がします。今は劣化して考えられなくなっただけかも。
> 昔はそういう考えが基本的にあったと思います。今は何も考えていないですね。(^^;
もしかしたら、この辺がキモなのかも。
私も、最近になってプログラミングのスタイルが変わったというところはありません
けどね。かつては、特にインデントの桁数で、いろいろと変遷があったはず。
昔、N88-BASICでは、タブ幅が8桁固定で、さすがにこれは下げすぎだと思い、面倒
だったけど、空白3桁のインデントで、一生懸命スペースバーを叩いていた。
学生時代、PascalはTurboPascalと大学の大型機を使ったけど、両方でソースを統一
したくて、確かインデントは6桁。
その後、TurboCとVisualCの統合環境では、何桁だったかなぁ。
とくに、VisualCに触れたことって、ほとんど一瞬のようなものだったし。
両方とも、確か4桁だったと思うけど、全く自信なし。
その後すぐにVzに触れて、拡張子ごとにタブを4桁と8桁に設定できるようになって、
今ではこれなしにはいられない。
> 確かにその通りですが、私はとりあえず動くのを優先に考えてしまう癖があるようです。
あ〜、なんとなくわかるような。
なんと言えばいいかな。
私の場合は「長期的ずぼら」とか「ライフサイクルずぼら」。
konnoさんの場合は「近視眼的ずぼら」。
なので、konnoさん、トータルでの労力がかえって増えてしまうと思う。
11123/11097 BQO00549 konno Re: 素数表示、カウント SOSU5.EXE 更新
( 1) 24/02/29 18:45 11120:konnoさんへのコメント
SOSU5 の速度アップとバグ取りですが、他の素数計算プログラムを参考にしました。
旧版は、一桁の素数を決め打ちでやっていました。
for i!=2 to 10
if i!=2 then gosub print1:co!=co!+1:co1%(co!)=i!
if i!=3 then gosub print1:co!=co!+1:co1%(co!)=i!
if i!=5 then gosub print1:co!=co!+1:co1%(co!)=i!
if i!=7 then gosub print1:co!=co!+1:co1%(co!)=i!
next i!
これを全部コメントにして、2だけ決め打ちにしました。
さらに、偶数チェックを FOR STEP 2 で出来ることがわかり、以下のように
i!=2:gosub print1 :co!=co!+1:co1%(co!)=i! '★ 2は素数に決め打ち
a!=0
for i!=3 to no!-1 step 2 '★ 偶数をスキップ
loop1:
' no1$=str$(i!) '★ FOR steo 2 の
' le=len(no1$) '★スキップにより
' a!=val(right$(no1$,1)) '★この4行が
' b!=int (a!/2):if b!=a!/2 then i!=i!+1:goto loop1 '★要らなくなった
gosub loop2 '
next i!
これで少し速度アップ出来たようです。
SOSU4.EXE
Number = 50000 0: 0'34 Prime Number = 5133
SOSU5.EXE
Number.50000 0: 0'32 Prime Number = 5133
うーん、誤差範囲かな。(^^;
あとは配列の見直しで、10万までだったのを30万まで拡大出来ました。
速度的にも
Number.300000 0:12'20 Prime Number = 25997
12分もかかるので、この方式はこの辺が限界ですね。(^^;
さて、次はもっと速い別のアルゴリズムにしましょう。
11124/11096 BQO00549 konno MS-DOS Player の更新 2024/2/28
( 1) 24/02/29 19:03 11096:konnoさんへのコメント コメント数:1
MS-DOS Player がまた更新されていました。
http://takeda-toshiya.my.coocan.jp/msdos/index.html
---------------------------------------------------------------------
2024/2/28
INT 21h, AX=4404h/4405h/440Ahを修正しました。
BXでハンドルを指定するか、BLでドライブを指定するか、間違えて処理していました。
AX=440Ahはハンドル指定、AX=4404h/4405hはドライブ指定に修正しています。
内蔵デバッガを改良しました。
プロテクトモード時のコードページの処理を修正しました。
また実行トレースに、各命令を16bit/32bitのどちらで実行したか記録するようにしました。
(V30の場合は8080モードか否かを記録)
Uコマンド、UTコマンドで正しく命令を表示できるようになっているかと思います。
roytam様のforkを参考に、conhost-v2のクラッシュ対策を入れました。
カーソルが最後の行にあるときにウィンドウサイズを変更するとクラッシュし易いようです。
また未確認ですが、Windows NT4.0 / 2000で動作するための修正も取り込んでいます。
---------------------------------------------------------------------
VZにはあまり影響無さそうですが、更新が続いていることに感謝します。
11125/11096 BQO00549 konno SOSU4で MS-DOS Playerの速度計測 2
( 1) 24/02/29 19:38 11124:konnoさんへのコメント
MS-DOS Player の更新で CPU速度の変化が気になったので、
素数計算 SOSU4 で 各CPUのエミュレーション速度計測しました。
23-12-14版 24-02-19版 24-02-28版
MS-DOS Player 231214 240219 240228
ia32_x64 ia32_x64 ia32_x64
Number = 10000 0: 0' 3 0: 0' 2 0: 0' 3
Number = 20000 0: 0' 9 0: 0' 6 0: 0'10
i486_x64 i486_x64 i486_x64
Number = 10000 0: 0' 4 0: 0' 2 0: 0' 5
Number = 20000 0: 0'14 0: 0'14 0: 0'18
i386_x64 i386_x64 i386_x64
Number = 10000 0: 1'40 0: 1'39 0: 1'56
Number = 20000 0: 5'31 0: 5'27
i286_x64 i286_x64 i286_x64
Number = 10000 0: 0'45 0: 0'50 0: 1' 4
Number = 20000 0: 2'29 0: 2'42
最新版の速度計測は手抜きですが、少し遅くなったような気がします。
条件判定などが増えたからでしょうか。
11126/11097 CXB00940 としき Re: 素数表示、カウント SOSU5.EXE 更新
( 1) 24/03/01 01:28 11120:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
sosu5.bas を読ませてもらっています。
まだ冒頭のほうだけなんですけどね。
で、質問。
配列の確保で
dim co1%(32700)
と宣言されています。
その少しあとで入力プロンプトだと思いますが
PRINT "Prime Number (20 TO 327000)";
とあったり
if no!>327000 then inp1
となっているのですが、これはそれぞれ値は正しいのですか?
いや、似たような数値なので、ミスタイプを疑ってみました。
というか、できればこういうのは変数に定義したほうがよろしいかと。
例えば、
max=32700
dim co1%(max)
PRINT "Prime Number (20 TO "; max*10; ")";
if no!>max*10 then inp1
みたいなコードになっていれば、いらぬ疑問は招かないかと。
バグの混入も防止できるし。
アセンブラですら数値を定義して名前をつけるという機能があるのに、高級言語の
BASICでそういう機能を使わないのはもったいないと思う。
また、最近のC言語なんかでは、文法書に、この手の即値はマジックナンバーであり
使うことは悪い習慣だと書かれてしまっているらしい。そうだろうねぇ。
11127/11097 BQO00549 konno Re^2: 素数表示、カウント SOSU5.EXE 更新
( 1) 24/03/01 23:46 11126:としきさんへのコメント
> 配列の確保で
> dim co1%(32700) と宣言されています。
> その少しあとで入力プロンプトだと思いますが
> PRINT "Prime Number (20 TO 327000)";
> とあったり
> if no!>327000 then inp1
> となっているのですが、これはそれぞれ値は正しいのですか?
正しくはないというか、適当です。(^^;
> いや、似たような数値なので、ミスタイプを疑ってみました。
> というか、できればこういうのは変数に定義したほうがよろしいかと。
配列の数字と入力最大値とは関連はありません、たまたま同じ数値にしただけです。
なので、例題のようには出来ないです。
> バグの混入も防止できるし。
> アセンブラですら数値を定義して名前をつけるという機能があるのに、高級言語の
> BASICでそういう機能を使わないのはもったいないと思う。
> また、最近のC言語なんかでは、文法書に、この手の即値はマジックナンバーであり
> 使うことは悪い習慣だと書かれてしまっているらしい。そうだろうねぇ。
ご意見に従い、入力の最大値は max! にしてみました。
なるほど、修正が楽になりますね。
SOSU5 で最終と思っていましたが、修正ついでにもっと限界まで攻めてみました。
dim co1%(32766) ' これ以上は64Kオーバーエラー
max!=1000000
PRINT "Prime Number (20 TO ";max!;")";
最大値はもっといけるかもですが、時間的に100万までにしました。(^^;
こんどこそ打ち止めです。(^^;
11128/11097 BQO00549 konno SOSU6 素数を表示、カウントするテスト6
( 1) 24/03/02 00:03 11097:konnoさんへのコメント コメント数:2
TurboBasicで素数を表示、カウントするプログラム SOSU5 に更新しました。
DOSVAXJ3 や MS-DOS Player の JP モードで動きます。
自己流で考えて作ったので間違いがある可能性はあります。
指定範囲は20から 100万まです。配列数や時間的な限界がこの辺ということで。
一応、1000000 までは 合っていると思います。
今回指定数を100万までに拡大しました。
起動時オプションで動作変更できます。
SOSU6.ZIP サイズ 30299bytes 24-03-01 new!
SOSU6.EXE Ver.240301
・DOSVAXJ3 の VGAで動く 素数表示テストです。
・DOSVAXJ3 を起動したら、chev jp でVGAモードにして、SOSU4.EXE を起動してください。
・MS-DOS Player では、chej jp でVGAモードにすれば動作します。
・VTDOS では動作しません。
・ソースも付けます。
・1000000までは合っていると思いますが時間が掛かりすぎるので注意。
・数字や時間情報を SOSU.DAT に追加出力します。
・起動時オプション 1 で S000.DAT に素数を出力します。
・起動時オプション 2 で 表示もファイル出力もしません。カウントのみ。
・数字が大きくなると急速に速度が落ちるので、初めは 100くらいから始めてください。
・更新履歴
2024-03-01 V6 指定できる最大値を100万までに拡大。
2024-02-27 V5 バグ取りや速度アップやファイル出力など。
2024-02-20 V4 公開用に色々弄りました。
2024-02-17 V1 とりあえず作成?
動作保証はでき無いので実行は自己責任で。
http://tamaneko.world.coocan.jp/execom.htm
11129/11097 BQO00549 konno Re: SOSU6 素数を表示、カウントするテスト6
( 1) 24/03/03 16:48 11128:konnoさんへのコメント
> 最大値はもっといけるかもですが、時間的に100万までにしました。(^^;
SOSU6.EXE の実行時間です。
SOSU6.EXE
Number.10000 0: 0' 2 Prime Number = 1229
Number.100000 0: 1'40 Prime Number = 9592
Number.400000 0:23'20 Prime Number = 33860
Number.600000 0:52'55 Prime Number = 49098
Number.1000000 1:52'40 Prime Number = 78498
これだけ時間が掛かりますが、他の計算プログラムと結果は一致しています。
うっかり計測開始してしまったときは、Ctrl+Break で止まる設定ならあるいは。(^^;
まあ、いざという時は DOSVAXJ3 の窓を閉じればいいんだし。(^^;
11130/11096 BQO00549 konno MS-DOS Player の更新 2024/3/02
( 1) 24/03/04 00:07 11096:konnoさんへのコメント
MS-DOS Player がまた更新されていました。
http://takeda-toshiya.my.coocan.jp/msdos/index.html
---------------------------------------------------------------------
2024/3/2
INT 21h AH=43h, BL=08hが、BL=06hと同じ動作になっていた問題を修正しました。
内蔵デバッガを改良しました。
Rコマンドでレジスタ以外にフラグの値の変更もできるようにしました。
また、V30のディスアセンブラを、i386用のディスアセンブラと統合しました。
V30専用命令以外で正しく認識されない命令があったのが解決しています。
レジスタ名も標準的な名前で表示されるようになっています。
conhost-v2のクラッシュ対策の改良と、WindowsNT 3.51/4向けの修正をしています。
---------------------------------------------------------------------
クラッシュ対策とは、最近のWindowsのIMEの問題などでしょうか。
エミュレータ作者の影の苦労がうかがわれますね。
更新に感謝です。
11131/11097 CXB00940 としき Re: SOSU6 素数を表示、カウントするテスト6
( 1) 24/03/04 23:23 11128:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> TurboBasicで素数を表示、カウントするプログラム SOSU5 に更新しました。
N88-BASICもあらかた忘れ始めているので手元のDISK BASICのリファレンスを見ながら
ですが、TurboBasicはやっぱりかなり違うようです。
上のほうから見ていって、まず気がついたのがLOCATE文。
LOCATE 1, 26, ,1
というのがありましたが、N88では引数は3つまで。
つまり、カンマの数は2つまででした。
次がCOLOR文。
COLOR 14, 0
とありますが、N88では最初の引数は0から7までだけでした。
2番目と4番目の引数なら14も使えるようです。
あ、なんか、消し忘れのようなもの見つけてしまった。
a!=0
ってあるんですが、この変数、他では使われていないっぽい。
あ〜、なんか、N88-BASIICに移植したくなってきた。
といっても、動作環境は手元にはない。
実家にはDOS BASICはあるはずだけど、DOS BASICとDISK BASICって何が違っていたか
もう思い出せない。
ちょっと無謀だな。
11132/11048 CXB00940 としき Re^2: としきさんの msgview 完璧なツリー
( 1) 24/03/04 23:32 11053:としきさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> どんなチェック漏れがあるやら、想像もつきません。
いやぁ、やっぱりまだ何かおかしいですね。
#11097とか#11098からのツリーの、本来「┗」でなければいけないところがいくつか
「┣」になっていますね。
OKなところとNGなところの条件から追いかけてみましょう。
とはいえ、今日はもう終わり。
明日以降でね。
11133/11097 BQO00549 konno Re^2: SOSU6 素数を表示、カウントするテスト6
( 1) 24/03/05 00:03 11131:としきさんへのコメント コメント数:1
> 上のほうから見ていって、まず気がついたのがLOCATE文。
> LOCATE 1, 26, ,1
> というのがありましたが、N88では引数は3つまで。
> つまり、カンマの数は2つまででした。
Turbo Basic と TBasic のマニュアルが腐海から救い出せました。
思いもよらぬところの奥底に沈んでいました。(^^;
それによると、LOCATE 文の引数は 5個まであります。
LOCATE 縦位置,横位置,カーソル表示スイッチ,カーソル開始位置,カーソル終了位置
私がN88系と違うと思ったのは、縦と横が逆なところです。
他の構文は、横、縦なので、間違えやすいですね。MS系の歴史でしょうか。
> 次がCOLOR文。
> COLOR 14, 0
> とありますが、N88では最初の引数は0から7までだけでした。
> 2番目と4番目の引数なら14も使えるようです。
これもMS系と大きく違うところですね。
詳しくは以下略。(^^;
> あ、なんか、消し忘れのようなもの見つけてしまった。
> a!=0
> ってあるんですが、この変数、他では使われていないっぽい。
う、消し忘れてましたね。(^^;
> あ〜、なんか、N88-BASIICに移植したくなってきた。
> といっても、動作環境は手元にはない。
> 実家にはDOS BASICはあるはずだけど、DOS BASICとDISK BASICって何が違っていたか
> もう思い出せない。
> ちょっと無謀だな。
ネットには、N88系準拠のフリーなBASICもありそうです。
移植するなら、他の素数プログラムが良いと思います。
私のは全く実用的でないので。(^^;
これからアップしますね。
11134/11048 BQO00549 konno Re^3: としきさんの msgview 完璧なツリー
( 1) 24/03/05 00:07 11132:としきさんへのコメント コメント数:1
> #11097とか#11098からのツリーの、本来「┗」でなければいけないところがいくつか
> 「┣」になっていますね。
見てみましたが、これは正しいツリーだと私は思います。
うちのツリーは横幅を狭くしたくて見た目がいまいちなのです。(^^;
11135/11135 BQO00549 konno TurboBasicで素数を表示カウントする PRIME2.EXE
( 1) 24/03/05 00:40 コメント数:2
TurboBasicで素数を表示、カウントするプログラム PRIME2.EXE です。
元にしたのは、十進BASIC に入っていた サンプルソースです。
https://hp.vector.co.jp/authors/VA008683/
ここのダウンロードページの Windowsアーカイブ版の中の
BASIC7868.zip (1,292,876バイト)を落として展開すると
Mathフォルダがあり、その中にある
PRIME.BAS 319bytes
を Turbo Basic で動くように改造しました。
特徴は、処理が非常に速く、桁数の制限がほぼ無いことです。
DOSVAXJ3 や MS-DOS Player の JP モードで動きます。
自己流で改造したので間違いがある可能性はあります。
指定範囲は20から 1億までにしました。
起動時オプションで動作変更できます。
PRIME.ZIP サイズ 30299bytes 24-03-01 new!
PRIME2.EXE Ver.240301
・DOSVAXJ3 の VGAで動く 素数表示テストです。
・DOSVAXJ3 を起動したら、chev jp でVGAモードにして、PRIME2.EXE を起動してください。
・MS-DOS Player では、chej jp でVGAモードにすれば動作します。
・VTDOS では動作しません。
・ソースも付けます。
・20000000までは実行できると思います。
・数字や時間情報を SOSU.DAT に追加出力します。
・起動時オプション 1 で P000.DAT に素数を出力します。
・起動時オプション 2 で 表示もファイル出力もしません。カウントのみ。
・起動時オプション 100以上で 指定した数字で間欠カウント表示。若干速くなるかも。
・数字が大きくなると時間が掛かるので、初めは 1000くらいから始めてください。
・更新履歴
2024-03-03 V2 バグ取りやファイル出力やオプション追加など。
2024-02-27 V1 とりあえず作成
動作保証はでき無いので実行は自己責任で。
http://tamaneko.world.coocan.jp/execom.htm
11136/11048 CXB00940 としき Re^4: としきさんの msgview 完璧なツリー
( 1) 24/03/05 12:06 11134:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> 見てみましたが、これは正しいツリーだと私は思います。
あれ?
うちとkonnoさんのところでは、表示のされ方が違うのかな?
そんなことはないと思うけど。
たとえば、#11097から始まるツリーの#11117とか#11126が、本来は「┗」でなければ
いけないけれど「┣」になっているように見えます。
これ、konnoさんのところでは正しく「┗」になっているのか。
それとも私の勘違いで「┣」が正しいのか。
ちょっと混乱しています。
11137/11135 CXB00940 としき Re: TurboBasicで素数を表示カウントする PRIME2.EXE
( 1) 24/03/05 13:22 11135:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> 自己流で改造したので間違いがある可能性はあります。
プログラムの中身はぜんぜん読めていませんが。
> ・起動時オプション 1 で P000.DAT に素数を出力します。
> ・起動時オプション 2 で 表示もファイル出力もしません。カウントのみ。
ソースリスト冒頭のコメントで
' IF DSP=1 THEN print '画面出力
' IF DSP=1 THEN print out dat 'ファイル出力
' IF DSP=2 THEN no print 'カウントのみ
となっているのですが、これはコメントが間違っているのかな。
11138/11097 CXB00940 としき Re^3: SOSU6 素数を表示、カウントするテスト6
( 1) 24/03/05 14:12 11133:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
LOCATEなんていう、割と基本的なところからして違うものなのですね。
> LOCATE 縦位置,横位置,カーソル表示スイッチ,カーソル開始位置,カーソル終了位置
>
> 私がN88系と違うと思ったのは、縦と横が逆なところです。
> 他の構文は、横、縦なので、間違えやすいですね。MS系の歴史でしょうか。
えと、LOCATEが縦、横の順というのは、Turbo Basic と TBasic の両方ですか?
それともどちらかだけ?
ちなみに、N88の場合は
LOCATE 横位置,縦位置,カーソル表示スイッチ
だけです。
カーソルの開始位置、終了位置ってなんだろう。
横長のカーソルを表示できるのかな。
それとも、その制限の範囲にカーソルがこない場合は表示されない、とか。
> 移植するなら、他の素数プログラムが良いと思います。
konnoさんの新しいのもリリースされたし、そっちを狙おうかな。
とりあえず、SOSU6の方を移植するとなると気になる部分がひとつ。
もしかしたら16ビットのBASICでは改善されているかもしれませんが。
loop2: ' 数値を確定した素数で割り切れれば合成数
for ii!=1 to co!-1
b!=int(i!/co1%(ii!)):if b!=i!/co1%(ii!) then noflg=1:goto lpend2
next ii!
lpend2:
8ビット時代のBASICでは、こういうループの脱出方法をは推奨されなかった。
FORのループを完了させずに途中で脱出すると、スタックにデータが詰みあがった
ままになってしまうのだそうで。
たしか、新しくRUNするとクリアされるのだったかなぁ。
もしかしたら、明示的にCLEARというコードを書かないとクリアされなかったかも
しれない。
この辺は処理系によって違うかもしれないし、当時のBASICのリストを見ると、DEFINT
と同様、ソースの先頭でおまじないのようにCLEARを入れているものが多かったので、
この辺で混同している部分もあるかもしれない。
で、結局どうするのがよいかというと
*LOOP2
FOR II!=1 TO CO!-1
IF INT(I!/CO1%(II!))=I!/CO1%(II!) THEN NOFLG=1:II!=CO!-1
NEXT
こんな感じで無理やり強制的にループの制御変数の値を書き換えてしまう、という
ワザが使われていました。
11139/11048 BQO00549 konno Re^5: としきさんの msgview 完璧なツリー
( 1) 24/03/05 15:24 11136:としきさんへのコメント コメント数:1
> たとえば、#11097から始まるツリーの#11117とか#11126が、本来は「┗」でなければ
> いけないけれど「┣」になっているように見えます。
あうう、リンク先をそのまま見ていました。頭が他に行っていたみたいです。(>_<)
msgview のツリーは「┣」になっていますね。失礼しました。m(__)m
何が悪いのかはわかりません。m(__)m
11140/11135 BQO00549 konno Re^2: TurboBasicで素数を表示カウントする PRIME2.EXE
( 1) 24/03/05 15:56 11137:としきさんへのコメント コメント数:1
> ソースリスト冒頭のコメントで
> ' IF DSP=1 THEN print '画面出力
> ' IF DSP=1 THEN print out dat 'ファイル出力
> ' IF DSP=2 THEN no print 'カウントのみ
> となっているのですが、これはコメントが間違っているのかな。
コメントの間違いにコメントするなんて、鬼畜ですぅ。(;_;)
もちろん1行目は ゼロのつもりだったんですぅ。
日付や指定範囲などもおかしいような気がするけど気にしない。(^^;
11141/11097 BQO00549 konno Re^4: SOSU6 素数を表示、カウントするテスト6
( 1) 24/03/05 16:55 11138:としきさんへのコメント コメント数:1
> > LOCATE 縦位置,横位置,カーソル表示スイッチ,カーソル開始位置,カーソル終了位置
見直したらおかしなところに気が付きました。
LOCATE 1, 26, ,1
とありますが、おしりの1はカーソル開始位置なので、終了位置が無い?
これも元は何かのサンプルソースで
LOCATE 1, 26, ,1 '%CursorOff
多分これが元だと思います。
TBasicのマニュアルでは、終了位置を省略すると開始位置と同じ数値が入るらしいですが
このコメントでは、カーソルオフになっていますね? わからん。
サンプルが間違えているかもですね。(^^;
> えと、LOCATEが縦、横の順というのは、Turbo Basic と TBasic の両方ですか?
両方です。TBasicはもろMS系だと思いますが、TurboBasicもMS系準拠ということですかね。
> カーソルの開始位置、終了位置ってなんだろう。
カーソルの高さ指定だと思います。TBasicでは、0が上で 15が下みたいです。
> FORのループを完了させずに途中で脱出すると、スタックにデータが詰みあがった
> ままになってしまうのだそうで。
うげ、これは知らなかったです。ヤバイかも・・・(>_<)
STIME でたまに問題が出るのはこれかもしれないですね。
> FOR II!=1 TO CO!-1
> IF INT(I!/CO1%(II!))=I!/CO1%(II!) THEN NOFLG=1:II!=CO!-1
> NEXT
> こんな感じで無理やり強制的にループの制御変数の値を書き換えてしまう、という
> ワザが使われていました。
これも良くやっていますが、これからはループを抜ける時は気を付けます。
11142/11048 CXB00940 としき Re^6: としきさんの msgview 完璧なツリー
( 1) 24/03/05 17:24 11139:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> 何が悪いのかはわかりません。m(__)m
私にも何が悪いのか、今のところは全くわかっていません。
一応、1月にkonnoさんにお送りしたコードを再び引っ張り出してみました。
そして、うちの板塀の現行ログを表示してみたのですが、全て正常な表示に見える
のですよ。かなり複雑そうなツリーであっても。
う〜ん、まさかデータというかログファイルのほうに原因があるのか?
それとも、私がkonnoさん的なコードに転記する際にどこかを誤ったとか。
いささか複雑というか統一性に欠けたコーディングスタイルでしたから。
あるいは、konnoさんがご自分でコードをきれいにしようとして失敗したとか。
一応、ざっくりみたところ。
msgviewの中で「┗」「┣」が表示されるルーチンは以下のような感じ。
if ($tx[$lx] == 0 && $lx != 0) { print "┗"; }
else {
$jj=1;
while ( $tlx[$j+$jj] > 0 ) {
if ( $tlx[$j] == $tlx[$j+$jj] ) { $jj=0; last; }
if ( $tlx[$j] > $tlx[$j+$jj] ) { $jj=1; last; }
$jj++;
}
if ( $jj == 0 ) { print "┣"; }
elsif ($lx != 0 ) { print "┗"; }
}
一方で、正しく表示される一括表示のツリー表示部分は以下のような感じ。
if ( $tx[$lx] == 0 ) { print "┗"; }
else {
$jj=1;
while ( $tlx[$j+$jj] > 0 ) {
if ( $tlx[$j] == $tlx[$j+$jj] ) { $jj=0; last; }
if ( $tlx[$j] > $tlx[$j+$jj] ) { $jj=1; last; }
$jj++;
}
if ( $jj == 0 ) { print "┣"; }
else { print "┗"; }
}
条件式が違うじゃない。
何でこんなところを見落としたんだろう。
テストデータというか板塀のデータで正常に表示されていたからだろうなぁ。
ということで、もしかしたらこれでうまくいくかも。
もうkonnoさんのところでも不要なコメントは全部落としているでしょうから、場所は
すぐに見つかることでしょう。
とりあえず試してみてください。
11143/11097 CXB00940 としき Re^5: SOSU6 素数を表示、カウントするテスト6
( 1) 24/03/05 17:58 11141:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> これも元は何かのサンプルソースで
> LOCATE 1, 26, ,1 '%CursorOff
> 多分これが元だと思います。
> TBasicのマニュアルでは、終了位置を省略すると開始位置と同じ数値が入るらしいですが
> このコメントでは、カーソルオフになっていますね? わからん。
値を省略するとカーソルオフなんですかね。
N88だと、最後のパラメータなんでよく省略されていましたが、省略時は単にそれ以前
の値を引き継いでいました。
> カーソルの高さ指定だと思います。TBasicでは、0が上で 15が下みたいです。
あ、横方向ではなく、1つの文字の中の縦方向でしたか。
ということは、開始位置が0、終了位置を1と指定すると、アッパーラインのような感じ
になるということですね。これはVzのCiとCoみたいに変更できるということですから、
使い方によっては便利かもしれない。
> > FORのループを完了させずに途中で脱出すると、スタックにデータが詰みあがった
> > ままになってしまうのだそうで。
> うげ、これは知らなかったです。ヤバイかも・・・(>_<)
いや、昔のインタプリタの時代の話ですから。
コンパイル型言語なら大丈夫なんじゃないかなぁ。
ただ、ループをまわす回数が増えても問題がないのに、ループの回数そのものが少ない
にもかかわらず、そのループを呼び出す回数が増えると問題が出るという、謎の不具合
につながることがあって。
苦労させられた人はそれなりにいるはず。
ところで、それよりも、変なことに気がつきました。
#11097によると
> 最も素朴な方法は、2 から √n 以下の素数まで順番に割っていく
とあるのですが、コードの中にSQRT関係の関数がないようです。
これ、本当にこのアルゴリズムであっていますかね。
例えば、23が素数であるかを確認するためには√23以下の素数、つまり2と3で確認
すれば事足りるわけです。
コードを追いかけていませんが、まさか、5とか7でも割っているから余計に時間が
かかっている、ということはないでしょうか。
11144/11048 BQO00549 konno Re^7: としきさんの msgview 完璧なツリー
( 1) 24/03/05 20:04 11142:としきさんへのコメント コメント数:1
> あるいは、konnoさんがご自分でコードをきれいにしようとして失敗したとか。
私は頂いたソースをそのまま張り付けただけだったと思います。(^^;
今見たら私のバグバグなトンでもコードのコメントがそのまま大量に残っていますね。(^^;
よくこの状態で修正できたと感心します。いや、ありがたいです。
> msgviewの中で「┗」「┣」が表示されるルーチンは以下のような感じ。
> if ($tx[$lx] == 0 && $lx != 0) { print "┗"; }
ここは探してみたところ、以下のようになっていましたが修正しました。
# if ($tx[$lx] == 0 && $lx != 0) { print "┗"; }
if ( $tx[$lx] != 0 ) { print "┣"; }
↓
if ( $tx[$lx] == 0 ) { print "┗"; }
elsif ($lx != 0 ) { print "┗"; }
↓
else { print "┗"; }
最初下の1行だけ修正しましたが変わりませんでした。
それで上側も修正したら、キチンとツリー表示出来ました。\(^^)/ ヤッタ-
> もうkonnoさんのところでも不要なコメントは全部落としているでしょうから、場所は
> すぐに見つかることでしょう。
不要なコメントはまだそのままですが、これを機に削除しようと思います。(^^;
本当にありがとうございました。m(__)m
11145/11097 BQO00549 konno Re^6: SOSU6 素数を表示、カウントするテスト6
( 1) 24/03/05 23:15 11143:としきさんへのコメント
> 値を省略するとカーソルオフなんですかね。
> N88だと、最後のパラメータなんでよく省略されていましたが、省略時は単にそれ以前
> の値を引き継いでいました。
試しに
LOCATE 1, 26, ,10
にして実行してみたら、カーソル高さが半分くらいになっていました。
省略時はそれ以前の値を引き継ぐようですね。
> コンパイル型言語なら大丈夫なんじゃないかなぁ。
> ただ、ループをまわす回数が増えても問題がないのに、ループの回数そのものが少ない
> にもかかわらず、そのループを呼び出す回数が増えると問題が出るという、謎の不具合
> につながることがあって。
> 苦労させられた人はそれなりにいるはず。
やっぱりむやみにループを抜けるのは避けた方が良さそうですね。
> ところで、それよりも、変なことに気がつきました。
> #11097によると
> > 最も素朴な方法は、2 から √n 以下の素数まで順番に割っていく
> とあるのですが、コードの中にSQRT関係の関数がないようです。
気が付いてしまいましたか、そうです、私はWikiを見ないで自分で考えたのです。
素数を調べるには確定した素数で割ればいいんじゃないかと思ったのです。
それで配列に確定した素数を入れたのですが、数字が大きくなると割る回数が増えるので
時間が掛かったのでした。
> これ、本当にこのアルゴリズムであっていますかね。
PRIME2.EXE は、SQR関数を使っているので、これが本来のアルゴリズムなのでしょうね。
でも結果は一致していたので、考え方はあながち間違ってはいなかったかなと思います。
> 例えば、23が素数であるかを確認するためには√23以下の素数、つまり2と3で確認
> すれば事足りるわけです。
> コードを追いかけていませんが、まさか、5とか7でも割っているから余計に時間が
> かかっている、ということはないでしょうか。
その通りですね、ですから、SOSUシリーズは私の個人的仮説の実験だったのです。(^^;
PRIME.BAS のサンプルは学校でも使える模範的コードなのだと思います。
11146/11048 CXB00940 としき Re^8: としきさんの msgview 完璧なツリー
( 1) 24/03/07 02:17 11144:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> それで上側も修正したら、キチンとツリー表示出来ました。\(^^)/ ヤッタ-
無事に正常表示になりましたね。よかったよかった。
> 今見たら私のバグバグなトンでもコードのコメントがそのまま大量に残っていますね。(^^;
> よくこの状態で修正できたと感心します。いや、ありがたいです。
だから前にも言ったけど、ほとんど迷彩のような。
あたかも、プログラムからバグを除去することを拒むかのような。
このコードを書いた人は、プログラムの完成を見ることなく、永遠にデバッグのぬるま湯に
浸かっていたいのか。
と、誤解してしまいそうなわけですよ。誤解ですよね?
#本心だったらいやすぎ
コメントが多いというのは、決して悪くはないんですよ。
問題は、それが何を意味しているかがわからないこと。
例えば、コードの右側のほうに
「この行のコメントをはずすと××になる」
とか
「※参考 ○○氏のコード」
などときちんと記載されていればいいのですよ。
あるいは、ymfcstなんかでも採用されているような感じで
「★マークの5行のコメントをはずすとほにゃらら」
みたいなものとか。
要は、konnoさんのコードの場合、有効な情報が全くないのがイマイチ。
プログラムにおけるコメントって、コンピュータではなく人間に対して書くものですから、
人間に対して意味のない情報は少ないほうがいい。
私も、プロの書いたコードなんてあんまり見たことがありませんが、まずは目標として
コードだけで、つまりコメント全くなしで、ここは何をやっているかがわかるような
ものを目指すらしい。そうすれば、そもそもコメントを入れなくてすむから。
おおむね、人はみな横着ですからね。コメントを考える手間も省きたいわけですよ。
ただ、それはある種の理想。そんなものが実現することはまずない。
ということで、次善の策。コメントだけを追いかけることで、そのコードが何をやって
いるかがわかるようにする。
つまり、それなりにプログラムを読んできた経験のある人の場合、初めて触れる言語で
あっても、コメントのあるコードであれば、まずコメントを読む。
私も、Vzのマクロを勉強するとき、ikubohさんだったかな、もう忘れましたが、誰かの
マクロコードのコメントを見て勉強した記憶があります。
ということで、必要なコメントはバシバシ入れましょう、ということでした。
11147/11135 CXB00940 としき Re^3: TurboBasicで素数を表示カウントする PRIME2.EXE
( 1) 24/03/07 02:18 11140:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> コメントの間違いにコメントするなんて、鬼畜ですぅ。(;_;)
いや、なんとなく間違っていそうだとは思ったけど、確信がもてなかったのですよ。
だって、#11135で
> ・起動時オプション 1 で P000.DAT に素数を出力します。
> ・起動時オプション 2 で 表示もファイル出力もしません。カウントのみ
とはあったけど、起動時オプション 0 があるとは書いてなかったもので。
> 日付や指定範囲などもおかしいような気がするけど気にしない。(^^;
日付や範囲指定については、まだ見てもいない。
それより気になった部分がいくつかあって。
例えば、表示する素数の数の入力を求めるプロンプト、日本語の部分がコメント
になっていますが、これはなぜそうしているのか、とか。
メインというか j のループからは結構強引な脱出をしているな、とか。
そのループのコメントの「i;:c=c+1」っていったいなんだろう、とか。
outputのコメント、なんで素数が1個でも10000000個でも時間が同じなのかな、
とか。もしかしたら違うのかもしれないけど、この表現ではそれ以外の意図は
読み取れない。
タイマーのサブルーチンの冒頭、謎のif文がコメントアウトされているけど、
これはいったいなんだろう、とか。
一般にコードの概要をつかむにはコメント文が有効のはずなんだけど、全く有効に
見えない気がする。
11148/11048 BQO00549 konno Re^9: としきさんの msgview 完璧なツリー
( 1) 24/03/07 22:04 11146:としきさんへのコメント コメント数:1
> このコードを書いた人は、プログラムの完成を見ることなく、永遠にデバッグのぬるま湯に
> 浸かっていたいのか。
> と、誤解してしまいそうなわけですよ。誤解ですよね?
> #本心だったらいやすぎ
もちろん誤解ですよ。(^^; ただ世の中変人が多いのでそういう人もいるかも。(いねえよ)
> コメントが多いというのは、決して悪くはないんですよ。
> 問題は、それが何を意味しているかがわからないこと。
超絶ハイテク技などはそういうコメントが欲しいものですね。
> 要は、konnoさんのコードの場合、有効な情報が全くないのがイマイチ。
うう、これは BASIC コードのことを言っているのですよね。
アセンブラやVZマクロにはかなりコメントを入れているつもりです。(^^;
> ということで、次善の策。コメントだけを追いかけることで、そのコードが何をやって
> いるかがわかるようにする。
これは上で書きましたが、BASICは自分で読めるものだからあまりコメントを入れないのですね。
でも後で読むと何をやっているのかわからなくなってしまっています。(>_<)
ということで、今はサブルーチンのタイトルや説明、各行のコメントを
なるべく入れるようにやっている最中です。(^^;
達人のコードにコメントが無いのは必要を感じないからなんでしょうね。
> 私も、Vzのマクロを勉強するとき、ikubohさんだったかな、もう忘れましたが、誰かの
> マクロコードのコメントを見て勉強した記憶があります。
> ということで、必要なコメントはバシバシ入れましょう、ということでした。
ikubohさんなど達人のマクロはコメントがないと何をやっているのか全く分からないレベルですからね。
私もこれからは他人が読むことを念頭に入れてコメントを入れるようにします。
# 昨日の自分は他人と言いますからね。(゚゜)☆\(--#) それはおのれじゃ
11149/11135 BQO00549 konno Re^4: TurboBasicで素数を表示カウントする PRIME2.EXE
( 1) 24/03/07 22:28 11147:としきさんへのコメント コメント数:1
> だって、#11135で
> > ・起動時オプション 1 で P000.DAT に素数を出力します。
> > ・起動時オプション 2 で 表示もファイル出力もしません。カウントのみ
> とはあったけど、起動時オプション 0 があるとは書いてなかったもので。
お察しの通りオプション 0 はありません。(^^;
あ、P000.DAT も S000.DAT の間違いですね。P000 は PRIME2 の方でした。(>_<)
> 例えば、表示する素数の数の入力を求めるプロンプト、日本語の部分がコメント
> になっていますが、これはなぜそうしているのか、とか。
最初日本語で書いたけどUSモードだと表示しないとか色々面倒なのでコメントにしてしまい
そのまま放置してました。(^^;
> メインというか j のループからは結構強引な脱出をしているな、とか。
これは良くない抜け方でしたね、気が向けば直します。(^^;
> そのループのコメントの「i;:c=c+1」っていったいなんだろう、とか。
これは元は PRINT文だったのを、PRINT1: というサブルーチンに変更したので
IF j>SQR(i) THEN gosub PRINT1 i;:c=c+1 ' 素数
↓
IF j>SQR(i) THEN gosub PRINT1 'i;:c=c+1 ' 素数
こういうように、コメントで手抜きをしてました。(^^;
まあ、飛び先でやってることをコメントに残したとも言えなくもないし。(^^;
> outputのコメント、なんで素数が1個でも10000000個でも時間が同じなのかな、
> とか。もしかしたら違うのかもしれないけど、この表現ではそれ以外の意図は
> 読み取れない。
'Number.1 0: 0' 4 Prime Number = 9592
'Number.10000000 0: 0' 4 Prime Number = 9592
これですね、Prime Number が同じということでお察しください。(^^;
手抜きの残骸だったのかなんなのか、今はもうわからないです。(^^;
> タイマーのサブルーチンの冒頭、謎のif文がコメントアウトされているけど、
> これはいったいなんだろう、とか。
これも借り物のルーチンの残骸ですね。他人に見せることは全く意識してないのです。
> 一般にコードの概要をつかむにはコメント文が有効のはずなんだけど、全く有効に
> 見えない気がする。
私のソースはこんなのばっかりなので、元々は公開する気も無かったんですがねぇ。(^^;
出来る範囲で改善するようにします。m(__)m
11150/11135 BQO00549 konno オリジナルの prime.bas のソース
( 1) 24/03/07 22:43 11135:konnoさんへのコメント コメント数:1
オリジナルの prime.bas のソースはこれだけです。
INPUT n
IF MOD(n,2)=0 THEN
IF n=2 THEN PRINT "素数" ELSE PRINT "合成数"
ELSE
FOR i=3 TO SQR(n) STEP 2
IF MOD(n,i)=0 THEN EXIT FOR
NEXT i
IF i<=SQR(n) THEN PRINT "合成数" ELSE PRINT "素数"
END IF
END
IF 〜 ELSE 〜 END IF をうまく使ってシンプルでエレガントですね。
TurboBasic で同じやり方はわからなかったので、自分なりに改造したのが以下
FOR i=2 TO n
IF i=2 THEN gosub PRINT i;:c=c+1 ' 2 素数
i2=i/2:i3=int(i/2):IF i2=i3 THEN goto EXIT2 ' 合成数
FOR j=3 TO SQR(i) STEP 2 ' 偶数をスキップ
i2=i/j:i3=int(i/j):IF i2=i3 THEN goto EXIT1 ' 合成数
NEXT j
EXIT1:
IF j>SQR(i) THEN gosub PRINT i;:c=c+1 ' 素数
EXIT2:
NEXT i:i=i-1
としきさんにループの抜け方が強引と言われたけど、うーむ・・・
IF MOD(n,i)=0 THEN EXIT FOR
ここは
i2=i/j:i3=int(i/j):IF i2=i3 THEN goto EXIT1 ' 合成数
↓
i2=i/j:i3=int(i/j):IF i2=i3 THEN i=i+1 ' 合成数
にすればよかったのかな。
つい、EXIT という構文に引っ張られたような・・・(^^;
11151/11048 CXB00940 としき Re^10: としきさんの msgview 完璧なツリー
( 1) 24/03/08 01:08 11148:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> > 要は、konnoさんのコードの場合、有効な情報が全くないのがイマイチ。
> うう、これは BASIC コードのことを言っているのですよね。
BASICもそうですが、先日お送りいただいたperlのコードも含めて、です。
> ということで、今はサブルーチンのタイトルや説明、各行のコメントを
> なるべく入れるようにやっている最中です。(^^;
うん、まぁ、最終的な完成品を作るにあたってそういうことは必要ですけどね。
私のような横着な人間はどうするかというと、プログラムを作る前に、日本語で
設計します。そして、その設計をそのままコードの中にコメントとして残しておく。
例えば、今回のkonnoさんのprime2.basを作ろうとするなら、私の書きそうな設計
は以下のような感じ。
初期設定
求める素数上限入力
メインルーチン(サンプルコードを最大限流用)
終了処理(キー入力待ち必須)
出力サブルーチン
ファイル出力
エラー終了ルーチン(自作の××からコピペ)
タイマールーチン(自作の○○からコピペ)
こんな感じで設計ができたら、あとは切った貼った、コピペできないところは仕方
ない作るか。
という風にするわけです。
そうすれば、わざわざコメントを書くということはなくなります。
その上、設計をじっと見つめて、例えば、出力部分はもうちょっと整理できそうだ、
とか、エラーのルーチンはそのままコピペだとイマイチかも、みたいなことも考え
付いたりするわけですよ。
そういえば昔、どこかに似たようなことも書いた気が、と思って検索したら。
nifty:FGALDC/MES/15/#19030
に似たようなことを書いていた。
そうか、ikubohさんではなくてEmmettさんのマクロで勉強したのか。
いろいろなことを書きましたが。
結論は、楽をしましょうよ、ということに尽きるわけで。
11152/11048 BQO00549 konno Re^11: としきさんの msgview 完璧なツリー
( 1) 24/03/09 01:38 11151:としきさんへのコメント コメント数:1
> BASICもそうですが、先日お送りいただいたperlのコードも含めて、です。
そうでした、直してもらったばかりなのに perl のことを忘れていました。m(__)m
> 私のような横着な人間はどうするかというと、プログラムを作る前に、日本語で
> 設計します。そして、その設計をそのままコードの中にコメントとして残しておく。
> 例えば、今回のkonnoさんのprime2.basを作ろうとするなら、私の書きそうな設計
> は以下のような感じ。
なるほど、これをそのまま各ルーチンのタイトルに使うのですね。
私は手を付けてからどうするか考える癖があるみたいで、
今すぐこのスタイルに切り替えるのは難しそうです。(^^;
でも参考になりました。やってみたいと思います。
> そういえば昔、どこかに似たようなことも書いた気が、と思って検索したら。
> nifty:FGALDC/MES/15/#19030
> に似たようなことを書いていた。
> そうか、ikubohさんではなくてEmmettさんのマクロで勉強したのか。
そうでしたか、実は私も「コメントの多いマクロ」で Emmettさんを思い出してました。(^^;
その Emmettさんの発言を見ると
> 》 僕は、マクロを書く時はとりあえずグローバルマクロからとにかく書き始めます。
> 》 僕は、アルゴリズムを最初にどこかにメモしておいて、それに従ってプログラム
> 》 を組んで行くということはやったことがありません。いつでもいきなり、グロー
> 》 バルの1行目から、じかに書き始めます。
私とおんなじですね。(^^;
それに対してとしきさんも
> あぁ、なるほど、やっと Emmett さんのマクロ作法がわかったような気がします。
> 基本的な考え方としては、私も Emmett さんとほとんど変わりません。
> とっても安心しました。
このように同意していますが、その後に
> でも、大きく異なるところは、私の場合、仮想プログラム言語というかメタ言語
> というか、まぁ日本語のようなもので書いているのです。で、大体まとまったら
> マクロに翻訳する、と。
こう書いていますね。やっぱりスタイルが違うと感じます。(^^;
もちろん、としきさんの方が正統派だと思います。
> いろいろなことを書きましたが。
> 結論は、楽をしましょうよ、ということに尽きるわけで。
楽をする、という意味では、としきさんのような正統派のやりかたが良いと思います。
それが出来ない私は、やっぱり楽をしようと思っていないのかもですね。(^^;
それよりも早く頭の中のアイデアをコードにしたいという欲求が強いのでしょう。(^^;
# そうしないとアイデアが消えてしまいそうだから。(^^;;
11153/11048 CXB00940 としき Re^12: としきさんの msgview 完璧なツリー
( 1) 24/03/09 11:17 11152:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
多分、最大というか基本的な違いはここ。
> それよりも早く頭の中のアイデアをコードにしたいという欲求が強いのでしょう。(^^;
> # そうしないとアイデアが消えてしまいそうだから。(^^;;
私はアイディアをコードではなく日本語で考えている、ということ。
だから、日本語でメモをしている。
逆に言うと、ナイスなコードを思いつく、ということはあんまりなさそうです。
あと、前述のEmmettさんとの対話の部分、読み直して、もしかしたら私に誤解が
あったかもしれないというのがkonnoさんの指摘で気がついた。
> > 》 僕は、アルゴリズムを最初にどこかにメモしておいて、それに従ってプログラム
> > 》 を組んで行くということはやったことがありません。いつでもいきなり、グロー
> > 》 バルの1行目から、じかに書き始めます。
>
> > あぁ、なるほど、やっと Emmett さんのマクロ作法がわかったような気がします。
> > 基本的な考え方としては、私も Emmett さんとほとんど変わりません。
> > とっても安心しました。
>
> このように同意していますが、その後に
このときの薄らぼんやりとした記憶では、私、サブルーチンから書き始めるのでは
なく、全体の大枠から書き始める、という意味でEmmettさんと同じだな、と感じた
ように覚えています。
確かにこの部分、解釈によってはいろいろと怪しいかもしれない。
11154/11048 BQO00549 konno Re^13: としきさんの msgview 完璧なツリー
( 1) 24/03/09 23:45 11153:としきさんへのコメント コメント数:1
> 私はアイディアをコードではなく日本語で考えている、ということ。
> だから、日本語でメモをしている。
> 逆に言うと、ナイスなコードを思いつく、ということはあんまりなさそうです。
うーむ、私もアイデアが浮かんだ時点では、コードではなく日本語な気もしますが
コード的な、パズルのピース的な漠然としたイメージなのかもしれませんね。
> このときの薄らぼんやりとした記憶では、私、サブルーチンから書き始めるのでは
> なく、全体の大枠から書き始める、という意味でEmmettさんと同じだな、と感じた
> ように覚えています。
> 確かにこの部分、解釈によってはいろいろと怪しいかもしれない。
普通、枝葉であるサブルーチンから書き始める人はいませんよね。(^^;
私も Emmettさんの書き込みを読み直したら、何か違う気がしてきました。
> 》 いつでもいきなり、グローバルの1行目から、じかに書き始めます。
ここ、私なら始めに類似したプログラムを探してそれを修正して使おうとします。
ゼロから書き始めるなんて面倒だと思うので私はほとんどやったことがないのですよ。
# それが改造人間の定めなのさ・・・・ ルルルー・・・
11155/11048 CXB00940 としき Re^14: プログラムの作り方
( 1) 24/03/10 13:59 11154:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
いいかげん、タイトルを変えるべきだということに遅まきながら気がつきました。
いまさら、という気も大いにしますが。
そして、たいそうな内容を書くわけでもない。
> ここ、私なら始めに類似したプログラムを探してそれを修正して使おうとします。
> ゼロから書き始めるなんて面倒だと思うので私はほとんどやったことがないのですよ。
類似したプログラムが見つからないとき、というのも私の場合はたまにある。
ん〜、最近はあんまりそういうこともありませんが。
例えば、野ざらし言#569 からのツリーで作ったマクロ。
こういう案件、konnoさんはあまり手を出さないということでしょうか。
私も最近はそういうことがなくなったということは、年をとったせいかも。
いかんなぁ。
11156/11135 CXB00940 としき Re: オリジナルの prime.bas のソース
( 1) 24/03/10 18:50 11150:konnoさんへのコメント コメント数:2
参照先:http://toshiki.la.coocan.jp/
> オリジナルの prime.bas のソースはこれだけです。
なるほど、MODって関数なんですね。
N88-BASICでは演算子なんですけどね。
> INPUT n
> IF MOD(n,2)=0 THEN
> IF n=2 THEN PRINT "素数" ELSE PRINT "合成数"
> ELSE
> FOR i=3 TO SQR(n) STEP 2
> IF MOD(n,i)=0 THEN EXIT FOR
> NEXT i
> IF i<=SQR(n) THEN PRINT "合成数" ELSE PRINT "素数"
> END IF
> END
これをそのままN88-BASICに移植すると、こんな感じかなぁ。
実行していないので、そのまま動くかどうかはわかりません。
100 INPUT N
110 IF N MOD 2=0 THEN 120 ELSE *ELSE1
120 IF N=2 THEN PRINT "素数" ELSE PRINT "合成数"
130 GOTO *ENDIF1
140 *ELSE1
150 I=3
160 WHILE (I<=SQR(N)) AND (N MOD I<>0)
170 I=I+2
180 WEND
190 IF I<=SQR(N) THEN PRINT "合成数" ELSE PRINT "素数"
200 *ENDIF1
210 END
解説すると
・MODは演算子に変更した。
・110行目のTHENの行番号は省略できたかもしれない。
つまり、NULLの行番号が許容されるのなら、その場合は単に次の行に制御が移る。
・ループの脱出条件が複数あるので、FORループからWHILEループに変更した。
> TurboBasic で同じやり方はわからなかったので、自分なりに改造したのが以下
TurboBasicって、MOD関数またはMOD演算子ってないんですか?
あと、NEXTの後ろの変数って省略できないんですか?
でもコンパイラ言語だからあんまり関係ないのか。
8ビットのBASICのころは、NEXTの後ろの変数を省略するとマイクロ秒の単位で速く
なると信じられていて、だから私も省略するのが癖になっているのですよ。
高速化といえば、最初のFORの直下のIF文。
これはループの中に入れておくのはもったいない。
だって、1回しか比較する必要がないものを何回も比較することになるわけだから。
> i=2:gosub PRINT i;:c=c+1 ' 2 素数
> FOR i=3 TO n
こんな感じで十分だと思う。
11157/11048 BQO00549 konno Re^15: プログラムの作り方
( 1) 24/03/11 00:19 11155:としきさんへのコメント
> いいかげん、タイトルを変えるべきだということに遅まきながら気がつきました。
私も途中で思ったのですが、まあいいかと。(^^;
> 類似したプログラムが見つからないとき、というのも私の場合はたまにある。
> ん〜、最近はあんまりそういうこともありませんが。
> 例えば、野ざらし言#569 からのツリーで作ったマクロ。
> こういう案件、konnoさんはあまり手を出さないということでしょうか。
そういう案件も多いと思います。その場合でも入出力など使えるルーチンは切り貼りで済まします。
そういえばテレビドラマ「ガリレオ」の教授は思いついたらいきなり数式を書きなぐっていましたね。
そういうやり方ができるのは、c.mosさんくらいではないかと。
> 私も最近はそういうことがなくなったということは、年をとったせいかも。
私も年を取って、昔のやり方でしか出来なくなったような気がします。
BASICのソースは普通大文字で書きますが、最近小文字の行を混在させてますよね。
そこは、自分で一から書いているよという自己主張なのかもしれません。(^^;
11158/11135 BQO00549 konno Re^2: オリジナルの prime.bas のソース
( 1) 24/03/11 00:45 11156:としきさんへのコメント コメント数:1
> なるほど、MODって関数なんですね。
> N88-BASICでは演算子なんですけどね。
あう、MOD は演算子でしたね、失礼しました。
> これをそのままN88-BASICに移植すると、こんな感じかなぁ。
> 実行していないので、そのまま動くかどうかはわかりません。
> TurboBasicって、MOD関数またはMOD演算子ってないんですか?
もちろんありますが、32767以上は駄目みたいです。
> あと、NEXTの後ろの変数って省略できないんですか?
> でもコンパイラ言語だからあんまり関係ないのか。
省略できると思います。指定した方がわかりやすいと思うので。
> 8ビットのBASICのころは、NEXTの後ろの変数を省略するとマイクロ秒の単位で速く
> なると信じられていて、だから私も省略するのが癖になっているのですよ。
コンパイラ言語ではあんまり関係ないのかもしれないなと思います。
> 高速化といえば、最初のFORの直下のIF文。
> これはループの中に入れておくのはもったいない。
> だって、1回しか比較する必要がないものを何回も比較することになるわけだから。
これはその通りですね、最初の FOR文はいらなかったですね。
うっかりしていました。(^^;
SOSU のソースから切り貼りしたのをそのまま残してしまったのかなぁ。(^^;
11159/11135 CXB00940 としき Re^3: オリジナルの prime.bas のソース
( 1) 24/03/12 02:16 11158:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> あう、MOD は演算子でしたね、失礼しました。
???
オリジナルの prime.bas では関数になっていますよね。
ということは、十進BASICでは関数である、ということだと思いますが?
もしかしたら演算子にもあるかもしれませんけどね。
> > TurboBasicって、MOD関数またはMOD演算子ってないんですか?
> もちろんありますが、32767以上は駄目みたいです。
N88-BASICのリファレンスでは、演算前に小数点以下は切り捨てられるとはあります
が、上限については記載がありません。試してみたいところではあります。
11160/11135 CXB00940 としき Re^5: TurboBasicで素数を表示カウントする PRIME2.EXE
( 1) 24/03/12 12:32 11149:konnoさんへのコメント コメント数:2
参照先:http://toshiki.la.coocan.jp/
> これですね、Prime Number が同じということでお察しください。(^^;
> 手抜きの残骸だったのかなんなのか、今はもうわからないです。(^^;
いや、konnoさんがわからないくらいですから、私にも察することはできません。
それはさておき。
マジでN88-BASICに移植することを考えています。
で、まだ逐語的な変換には手をつけていないのですが。
気になったのがここ。
if dsp=1 then print#1,"":gosub 1010
if n>2000 then gosub 1000 'output
dsp=1 かつ n>2000 のときは2回出力されるようなんですが、これって仕様的に
なんとなく妙な気がします。これで正しいのですよね?
あと、変数 j2 と j3 も、何をやっているのかよくわからない。
この2つを足し算しているところもあるし。
11161/11135 BQO00549 konno MOD と ¥ の有効範囲
( 1) 24/03/12 22:45 11159:としきさんへのコメント コメント数:1
> オリジナルの prime.bas では関数になっていますよね。
> ということは、十進BASICでは関数である、ということだと思いますが?
> もしかしたら演算子にもあるかもしれませんけどね。
あうう、キチンと読んでいませんでした。
てっきり私がまた間違った言い方をしてしまったのかと。(^^;
> > > TurboBasicって、MOD関数またはMOD演算子ってないんですか?
> > もちろんありますが、32767以上は駄目みたいです。
> N88-BASICのリファレンスでは、演算前に小数点以下は切り捨てられるとはあります
> が、上限については記載がありません。試してみたいところではあります。
十進BASICで関数を使っているのは、MOD に制限があるからかも。
思いついて TurboBasicでテストプログラムを作ってみました。
'tmod.bas
screen 0
print " input ";:input a '
OPEN "mod.dat" FOR append AS#1 'ファイル出力
print " a MOD i ","2bytes "," Froat "," a / i"
for i=2 to 5
bb=int((a/i-int(a/i))*i+.5) ' MOD 代替式
print a;"mod";i,a mod i,bb,a/i
print#1, a;"mod";i,a mod i,bb,a/i '
next
print " a \ i","2bytes "," Froat "," a / i"
for i=2 to 5
cc=int(a/i) ' \ 代替式
print a;" \ ";i,a \ i,cc,a/i '
print#1,a;" \ ";i,a \ i,cc,a/i '
next
PRINT#1,""
CLOSE#1
100 '入力待ち
print " push eny key ";
a$=input$(1)
if a$="" then 100
end
結果
a MOD/\ i 2bytes Froat a / i"
32767 mod 2 1 1 16383.5
32767 mod 3 1 1 10922.33333333333
32767 mod 4 3 3 8191.75
32767 mod 5 2 2 6553.4
32767 \ 2 16383 16383 16383.5
32767 \ 3 10922 10922 10922.33333333333
32767 \ 4 8191 8191 8191.75
32767 \ 5 6553 6553 6553.4
32768 mod 2 0 0 16384
32768 mod 3 -2 2 10922.66666666667
32768 mod 4 0 0 8192
32768 mod 5 -3 3 6553.6
32768 \ 2 -16384 16384 16384
32768 \ 3 -10922 10922 10922.66666666667
32768 \ 4 -8192 8192 8192
32768 \ 5 -6553 6553 6553.6
32769 mod 2 0 1 16384.5
32769 mod 3 -2 0 10923
32769 mod 4 0 1 8192.25
32769 mod 5 -3 4 6553.8
32769 \ 2 -16384 16384 16384.5
32769 \ 3 -10922 10923 10923
32769 \ 4 -8192 8192 8192.25
32769 \ 5 -6553 6553 6553.8
これを見るとやはり 32768 以上では MOD も ¥ も使えないようですね。
実は今 STIME のタイマーで計算がバグって困ってたんですが、これが原因だったようです。
テストプログラム作成は無駄ではなかった。(~~;
11162/11135 BQO00549 konno Re^6: TurboBasicで素数を表示カウントする PRIME2.EXE
( 1) 24/03/12 23:45 11160:としきさんへのコメント
> マジでN88-BASICに移植することを考えています。
> で、まだ逐語的な変換には手をつけていないのですが。
私も気になったので、NP2 でやってみました。(^^;
N88BASIC.EXE は画面がピンクになって動かないみたいです。(>_<)
BASIC.COM がコンパイラなんですね。無事コンパイルしたのを実行したら、
入力した数字が素数かどうかを表示するのですね。(^^;
> 気になったのがここ。
> if dsp=1 then print#1,"":gosub 1010
> if n>2000 then gosub 1000 'output
> dsp=1 かつ n>2000 のときは2回出力されるようなんですが、これって仕様的に
> なんとなく妙な気がします。これで正しいのですよね?
もちろんまずいです。(^^; いい加減なだけでした。
> あと、変数 j2 と j3 も、何をやっているのかよくわからない。
> この2つを足し算しているところもあるし。
これですね。
810 if i<j2 then return 'dsp2でカウント表示
j2=j2+j3
820 LOCATE 5,1:PRINT i; '
j2 は表示するまでのカウント数かな?
j3 はオプションの数字で、カウントがこの数字以上になったら次の数字ぶん表示しない
という感じですかね。ほとんど意味がないようですが。(^^;
11163/11135 CXB00940 としき Re^2: オリジナルの prime.bas のソース
( 1) 24/03/17 17:09 11156:としきさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
お彼岸の墓参りの相談で実家に顔を出してきました。
その折に、30分ほどですが、PC-98に触れて。
> これをそのままN88-BASICに移植すると、こんな感じかなぁ。
> 実行していないので、そのまま動くかどうかはわかりません。
動きました。
細かくはチェックしていませんが、概ね、一発完動。
一発完動教徒なら、このくらい当たり前、というかもしれませんけどね。
> ・110行目のTHENの行番号は省略できたかもしれない。
> つまり、NULLの行番号が許容されるのなら、その場合は単に次の行に制御が移る。
あ、ここが省略できるかは確認してこなかった。
次に行ったときには確認してこよう。といいつつ、忘れそうだけど。
次の週末、金曜日から土曜日にかけて実家に泊まることになったので、それまでには
prime2.basのN88-BASICへの移植を終わらせたいなぁ。
11164/11135 CXB00940 としき Re^6: TurboBasicで素数を表示カウントする PRIME2.EXE
( 1) 24/03/17 17:26 11160:としきさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> マジでN88-BASICに移植することを考えています。
> で、まだ逐語的な変換には手をつけていないのですが。
ぼちぼち、移植を始めています。
・コマンドラインオプションは取得できないので、プログラム冒頭で入力するように
した
・まず真っ先にやったのは、locateのxとyの総入れ替え
・N88-BASICでは、実数型も倍精度型も扱える上限は 1.7*10^38 で差がないため、
変数は全て単精度実数に変更
→実は覚えていなかったけど、FOR文のカウントに使うループ変数に倍精度型は
使えないのだとか。マニュアルに明記してあった
・私の趣味でファイル番号指定の「#1」の前には全て半角空白を入れた
(たぶん、文法的には不要だと思うけど覚えていない)
・#11160で私が指摘した謎の2つのif文はdsp=1のほうだけ残した
・ファイル出力の際に、ループ内でいちいちOPEN/CLOSEするのは非効率的だと思う
ので、最初で開いて最後に閉じるだけにした
今の所はそんな感じ。
とりあえず、机上デバッグでどこまでできるか。
忘れていることが多すぎるなぁ。
11165/11135 BQO00549 konno Re: MOD と ¥ の有効範囲
( 1) 24/03/18 00:36 11161:konnoさんへのコメント コメント数:1
MOD と \ の有効範囲テストを NP2 でやってみました。
結果は 32767 を超えると オーバーフローエラーになりました。
また、N88BASICでは行番号が必要で、タブは使えなかったので
以下のようにプログラムを修正しました。
10 'N88mod.bas
14 print " input ";
20 input a '
30 OPEN "mod.dat" FOR append AS#1 'ファイル出力
40 print " a MOD i ","2bytes "," Froat "," a / i"
50 for i=2 to 5
60 bb=int((a/i-int(a/i))*i+.5) ' MOD 代替式
70 print a;"mod";i,
72 if a>32767 then print "over! ", else print a mod i, '32767 over
74 print bb,a/i
80 print#1, a;"mod";i,
82 if a>32767 then print#1,"over! ", else print#1, a mod i, ' 32767 over
84 print#1, bb,a/i '
90 next i
100 print " a \ i","2bytes "," Froat "," a / i"
110 for i=2 to 5
120 cc=int(a/i) ' \ 代替式
130 print a;" \ ";i,
132 if a>32767 then print "over! ", else print a \ i, ' 32767 over
134 print cc,a/i '
140 print#1,a;" \ ";i,
142 if a>32767 then print#1,"over! ", else print#1, a \ i, ' 32767 over
144 print#1,cc,a/i '
150 next i
160 PRINT#1,""
170 CLOSE#1
180 '入力待ち
190 print " push eny key ";
200 a$=input$(1)
210 if a$="" then 180
220 end
エラーになるのと不正な結果になるのとどっちが良いかはともかく
MOD と \ の有効範囲は 普通は 32767 までのようですね。
だから素数のような桁数が多くなる計算は UBASIC などを使うのが良いのでしょうね。
11166/11135 CXB00940 としき Re^2: MOD と ¥ の有効範囲
( 1) 24/03/20 01:44 11165:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> また、N88BASICでは行番号が必要で、タブは使えなかったので
> 以下のようにプログラムを修正しました。
うわぁ、ものすごく違和感がある見た目のプログラムになるんだな。
最大の理由は、おそらく、行番号のあるBASICにもかかわらず、コードが小文字だと
いうところからくるものだと思います。
行番号の不要なBASICなら小文字のコードでも全く違和感は感じないんですけどね。
どうやら、完全に、行番号のあるBASICは大文字、という感性に毒されている模様。
あと、もしかしたら些細かもしれないけど、行番号が等間隔ではないところにも、
まぁまぁ違和感を感じる。これは、同じN88であっても、インタプリタ型と違って
コンパイラ型の場合、テキストエディタでソースを書くことになるわけですから、
行番号の振り直しには手間がかかりますので、ある程度は仕方ないか。
ちょっとここで、行番号に関する昔話でも。
日本では、8ビットパソコンの草創期から、BASICのリストでは、行番号は10から
始まって10番ごと、というのがデファクト。なぜ10番ごとかというと、コードの追加
をする場合、その間の番号が使えるから、ということのようです。これは、日本に
BASICがやってくる前から、そういうのが普通だったらしい。
ただ、コードを追加すると当然、それは10番ごとにはならない。
そこで、BASICインタプリタにはRENUMというコマンドが用意されました。
renumberの略で、要するに行番号を振りなおしてくれるわけです。
これはNECのBASICにもシャープのBASICにもあったので、おそらく、東芝のBASICにも
あったのではないかなぁ。そしてたぶん、どこのものもほとんど同じだと思いますが、
NECの場合はデフォルトで、新しく付け直した行番号の開始番号は10からで、間隔も
10ごとに付け直してくれました。
コンパイラの場合は当然、こういう便利な機能があるわけではありませんから、番号
の振り直しは自前で人間がやらなければならないので、いろいろと面倒。
その後、BASICでもループなどをきちんとインデントするのが当たり前の時代になる
と、ここで問題になったのが、行番号の桁数。せっかくインデントを整えても、
90から100とか、990から1000といった行番号の桁数が変わるところでインデントが
崩れてしまう。そこでどうするかというと、例えば990行までに収まらないプログラム
なら1000行からはじめればよい、ということになりました。この部分、私ならなにも
10番間隔にこだわらず5番間隔でもいいじゃないか、それこそ最終的な完成形はもう
これ以上追加削除をしないということを強調する意味で1番間隔でいいのではないか、
と思うのですが、どうも世の中の大勢は10番間隔が好きみたい。
あと、間隔はいくつでもいいのですが、プログラムの最初から最後まで等間隔は
守るべき、というのも世間の多数派のようです。というか、RENUMコマンドを使えば
必然的に等間隔になるわけです。ここで例えば、いろいろとコードを追加した際に
その部分を追加したということを目立たせるためにあえて残すべき、という流派の
人もいたらしいですが、これはその後、少数派になりました。なぜかというと、
当時のBASICの編集画面だと、最近のテキストエディタと違い、それが何行目かと
いうことが表示されないわけです。ここで、例えば200行に GOTO 800 とあれば、
もし10番ごとの等間隔なら、ジャンプの飛び先はプログラムリスト上で60行先に
なるわけで、プリントアウトされた紙で追いかけやすい、という実利的な理由が
あったわけです。
と、いうことで。
もしBASICのプログラムをインタプリタに読み込ます機会があったら、RENUMコマンド
をかけた結果を保存しておくべきでしょう。
11167/11135 BQO00549 konno Re^3: MOD と ¥ の有効範囲
( 1) 24/03/21 00:00 11166:としきさんへのコメント コメント数:1
> うわぁ、ものすごく違和感がある見た目のプログラムになるんだな。
> 最大の理由は、おそらく、行番号のあるBASICにもかかわらず、コードが小文字だと
> いうところからくるものだと思います。
なるほど、そう言われればそんな感じもしますが、私はもう気にしてなかったので。(^^;
> 行番号の不要なBASICなら小文字のコードでも全く違和感は感じないんですけどね。
> どうやら、完全に、行番号のあるBASICは大文字、という感性に毒されている模様。
私はbasic歴が長いので、他の言語が小文字なのに違和感を感じました。今は無いですね。
> そこで、BASICインタプリタにはRENUMというコマンドが用意されました。
> renumberの略で、要するに行番号を振りなおしてくれるわけです。
> これはNECのBASICにもシャープのBASICにもあったので、おそらく、東芝のBASICにも
> あったのではないかなぁ。そしてたぶん、どこのものもほとんど同じだと思いますが、
> NECの場合はデフォルトで、新しく付け直した行番号の開始番号は10からで、間隔も
> 10ごとに付け直してくれました。
TBasicインタプリタは、RENUM 開始行番号,旧行番号,増分 となっています。
開始行番号は、新しくつける先頭の行番号の数値を指定します。
旧行番号は、付け替える初めの行を指定します。
でも私は使ったおぼえが無いですね。試したことはあるかもですが。
私の場合、行番号を振り直すと逆に頭の中のソースのイメージが壊れて混乱してしまう
気がしたので使わなかったのかもですね。再印刷もなかなか出来なかったし。(^^;
> と、ここで問題になったのが、行番号の桁数。せっかくインデントを整えても、
> 90から100とか、990から1000といった行番号の桁数が変わるところでインデントが
> 崩れてしまう。そこでどうするかというと、例えば990行までに収まらないプログラム
> なら1000行からはじめればよい、ということになりました。
これ、私はインデントなどしてなかったので、全く気になりませんでしたね。(^^;
だから今回のテストプログラムも 10番から付けてしまったのです。(^^;
> 必然的に等間隔になるわけです。ここで例えば、いろいろとコードを追加した際に
> その部分を追加したということを目立たせるためにあえて残すべき、という流派の
> 人もいたらしいですが、これはその後、少数派になりました。
どうやら私は少数派のようですね。(^^;
> 当時のBASICの編集画面だと、最近のテキストエディタと違い、それが何行目かと
> いうことが表示されないわけです。ここで、例えば200行に GOTO 800 とあれば、
> もし10番ごとの等間隔なら、ジャンプの飛び先はプログラムリスト上で60行先に
> なるわけで、プリントアウトされた紙で追いかけやすい、という実利的な理由が
> あったわけです。
私がNCプログラムを書いていた当時は、紙にプログラムを手書きしてからタイプライタに打ち込む形でした。
それが面倒に感じたのでパソコンに直接打ち込むスタイルを私が始めたのです。
紙テープに出力、印刷する時は行番号を N001 の形に自動変換していたので
もしかしたら行番号は RENUM していたかもしれません。もう忘れてしまいました。
私にとっては行番号は飾りでした。
# 偉い人にはそれがわからんのですよ。
それで狭い画面で行番号を頼りに確認するのが煩わしくて、スクリーンエデイタを欲したのです。
当時スクリーンエデイタといえば、ワードマスターとか10万以上もするようなのしか無かったと思います。
それで、結局自作のBASICインタプリタ用スクリーンエデイタもどきを作ったのでした。
そのために買ったのが、パソピア7だったという。(^^;
それが J3100SL に変わったころ、PSE や VZエデイタが出てきたのでした。
> もしBASICのプログラムをインタプリタに読み込ます機会があったら、RENUMコマンド
> をかけた結果を保存しておくべきでしょう。
その機会があればやってみたいと思います。
NP2 では、BASIC.COM は動かないみたいですが、これがインタプリタなのですよね。
11168/11135 CXB00940 としき Re^4: MOD と ¥ の有効範囲
( 1) 24/03/21 11:14 11167:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> 私はbasic歴が長いので、他の言語が小文字なのに違和感を感じました。
私もBASIC歴はそれなりに長いのですがね。
複数言語に触れたというのが大きな違いでしょうか。
> TBasicインタプリタは、RENUM 開始行番号,旧行番号,増分 となっています。
これはN88-BASICでもN-BASICでも同じです。
> でも私は使ったおぼえが無いですね。試したことはあるかもですが。
ここは逆というか、私は使いまくりでした。
特に便利に使っていたのが、GOTOの飛び先の行番号が実在しないときにはエラーを
表示してくれる機能。行の追加・削除を頻繁に行う場合には、これは必須という
くらいに便利でした。
> 私の場合、行番号を振り直すと逆に頭の中のソースのイメージが壊れて混乱してしまう
> 気がしたので使わなかったのかもですね。再印刷もなかなか出来なかったし。(^^;
この辺はよく理解できない。ということは、私の場合はあまり行番号に依存しないで
ソースをイメージしていたのかな。つまり、私にとっては、行番号なんて単なる飾り
だった、とか。
#私は偉くないから。
> これ、私はインデントなどしてなかったので、全く気になりませんでしたね。(^^;
> だから今回のテストプログラムも 10番から付けてしまったのです。(^^;
ここは私にとって大きな違い。
BASICでもバグの入りにくいコードを書こうと思っていたのでインデントしまくり。
> どうやら私は少数派のようですね。(^^;
別に少数派だからといって恥じる必要はさらさらありませんけどね。
ただ、多数派の言い分としては、そちらのほうがバグ取りがしやすい、というもの。
実際、私の経験からも、多数派のほうが正しそうな気がする。
ということで、バグ取りに悩まされたくないので、私も行番号をそろえていました。
あくまでも、実利優先、ということで。
11169/11135 CXB00940 としき Re^3: オリジナルの prime.bas のソース
( 1) 24/03/22 23:02 11163:としきさんへのコメント
参照先:http://toshiki.la.coocan.jp/
宿直の際にものすごく多忙で。
1時間半ぐらいしか仮眠を取れなかったのですが、帰宅後すぐに実家から墓参り。
墓までの往路はいささか危なかったのですが、それでもおおむね安全運転。
墓掃除その他もろもろですっかり眠気は取れて、実家への復路はほぼ問題なし。
それはさておき、現在、実家です。
> > ・110行目のTHENの行番号は省略できたかもしれない。
> あ、ここが省略できるかは確認してこなかった。
省略できることを確認しました。
これでまた少しコードサイズが節減。
11170/11135 CXB00940 としき Re^7: TurboBasicで素数を表示カウントする PRIME2.EXE
( 1) 24/03/22 23:15 11164:としきさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> ぼちぼち、移植を始めています。
ん〜、なんとなく動いているっぽい。
といいつつ、特にファイル書き込みの部分はろくに動作確認をしていないのだけど。
・N88-BASICだと、デフォルトは白黒モードなので、COLORでの色表示がうまくない。
→おやくそくのCONSOLEでカラーモードにした。
・時間表示の部分、私の趣味で分と秒の間もコロンにした。
・エラー処理ルーチンの最後、CLSがあるとエラーで終わったことがわからなく
なりそうだったので、これは除去した。
明示的にkonnoさんのコードに手を加えたのはこんなところかな。
あとは、各行にきちんと行番号をつけてやれば完成。
自宅に戻ったらアップロードしたいな。
11171/11135 BQO00549 konno Re^5: MOD と ¥ の有効範囲
( 1) 24/03/24 00:08 11168:としきさんへのコメント
> 別に少数派だからといって恥じる必要はさらさらありませんけどね。
> ただ、多数派の言い分としては、そちらのほうがバグ取りがしやすい、というもの。
> 実際、私の経験からも、多数派のほうが正しそうな気がする。
> ということで、バグ取りに悩まされたくないので、私も行番号をそろえていました。
> あくまでも、実利優先、ということで。
考えてみたら行番号必須のBASICインタプリタはプログラム言語全体では少数派なんですよね。
行番号付きのBASICインタプリタは作ったその場ですぐ実行できる初心者向きのお手軽な言語だと思います。
だから今でも教育用には使われているのでしょう。
本格的なプログラム言語には行番号は無いので、ラベルでジャンプしますよね。VZマクロも。
ということで、N88BASICなどと共用する場合を除いて行番号は無くす方向で行きたいと思います。
インデントは読みやすくなるのでなるべく心がけるようにします。
11172/11135 CXB00940 としき Re^8: N88-BASICで素数を表示カウントする PRIME88.BAS
( 1) 24/03/24 15:59 11170:としきさんへのコメント コメント数:2
参照先:http://toshiki.la.coocan.jp/
> 自宅に戻ったらアップロードしたいな。
アップロードしました。
tp://toshiki.la.coocan.jp/prime88.zip
期間限定。そのうちに削除します。
> といいつつ、特にファイル書き込みの部分はろくに動作確認をしていないのだけど。
こんな短いコードなのに、全ての条件分岐を網羅するホワイトボックステストは
行っていない。面倒になっちゃって。あぁ、横着。
とはいえ、画面表示とファイル出力の、最低限のチェックはしたので、少なくとも
一部はPC-98のDOS BASICで動作確認済み。
GOTOとGOSUBのジャンプはほとんどラベル化したので、行番号はなくても論理構造は
理解可能なはず。konnoさんのお持ちのTurboBasicなら、例えばcols.defのようなもの
を使って全ての行番号を削除しても、もしかしたらコンパイル可能かも。
ラベルの文法が違うからダメ、かな。
あと、もしかしたらほんのちょっとだけ高速化するかもしれない技術を一つ、導入
してみました。
1360 IF INT(I/2)*2 = I THEN *EXIT2
1380 WHILE (J<SQR(I)) AND (INT(I/J)*J<>I)
ここ、多くの処理系では割り算よりも掛け算のほうが速いと聞いたことがあるので、
割り算を2回するのではなく掛け算と割り算の組み合わせに変更してみました。
これでどのくらい早くなるかは測定していないからわからない。
処理系によっては、むしろ遅くなったりして。
konnoさんオリジナルのロジックよりは、使う変数も少なくなっている分だけ速く
なってるかもしれないけど、こんなもん、最近のコンパイラなら最適化してくれる
でしょ、という範囲かもしれない。
あとはまぁ、PC-88などの8ビットマシンならDMAを停めるとか、ナノピコ秒単位で
速度を稼ぐためにインデントを全て削除してマルチステートメント化するとか、
他にもいろいろと思いつく技はいくつかありますけどね。そこまではしていません。
11173/11135 BQO00549 konno Re^9: N88-BASICで素数を表示カウントする PRIME88.BAS
( 1) 24/03/25 02:00 11172:としきさんへのコメント コメント数:3
> アップロードしました。
> tp://toshiki.la.coocan.jp/prime88.zip
早速落として NP2 で動かしてみました。
#11162 で
> BASIC.COM がコンパイラなんですね。
なんて書きましたが、正しくは BACICC.COM でした。
BASIC Compiler ということなのですね。(^^;
B.BAT
basicc %1.bas %1.exe %1.lib
%1.exe
これを見て間違いに気が付きました。(^^;
さて、実行してみてまず気が付いたのは、変数 MAX の表示が
1E+08
になっていました。浮動小数点の表示形式ですね。
1070 MAX=100000000#
えーと、定数の末尾に # を付けているのは倍精度指定なのですか?
変数 MAX は単精度のように思われます。
> > といいつつ、特にファイル書き込みの部分はろくに動作確認をしていないのだけど。
オプション指定 1 で ファイルがキチンと出来ました。
ただ、素数の個数が私のと違いますね。
p1000.DAT
Number.1000 0: 0' 0 Prime Number = 168
n1000.DAT N88
Number.1000 0: 0: 1 Prime Number = 169
どちらかがカウント数を間違っているかと思い、VZで比較したら
p1000.DAT
167
173
n1000.DAT N88
167
169 ※ この行が多い
173
169 は、13*13=169 なので、素数では無いと思います。
今日は眠いのでこれ以上の調査は明日以降ということで。(^^;
11174/11135 CXB00940 としき Re^10: N88-BASICで素数を表示カウントする PRIME88.BAS
( 1) 24/03/25 23:13 11173:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> えーと、定数の末尾に # を付けているのは倍精度指定なのですか?
> 変数 MAX は単精度のように思われます。
おっしゃるとおりです。
変数を全て単精度指定に変更するときに修正をもらしたようです。
ただ、こちらは大勢に影響がありませんが
> 169 は、13*13=169 なので、素数では無いと思います。
こっちは大問題ですね。仕様どおりの挙動をしないのですから。
倍精度から単精度に精度を落としたことが悪いのか、それとも割り算と掛け算の
誤差の問題か。
いつ調査できるかわかりませんが、解決は図りたいと思います。
11175/11135 BQO00549 konno PRIME88.BAS で 「169=素数?」問題
( 1) 24/03/26 20:11 11174:としきさんへのコメント コメント数:2
> > 169 は、13*13=169 なので、素数では無いと思います。
>
> こっちは大問題ですね。仕様どおりの挙動をしないのですから。
> 倍精度から単精度に精度を落としたことが悪いのか、それとも割り算と掛け算の
> 誤差の問題か。
私は当初 NP2 のCPUエミュレーション等のバグを疑いました。
それで、anex86 でも試したのですが、結果は同じ。98NEXT では固まってしまいました。
次に疑ったのが、BASICコンパイラが壊れていないか。
1988/08/24 00:00 61,440 BASICC.COM
中身が壊れているることもありうるので、98実機での結果が知りたいところですね。
条件を色々変えて試しても結果は変わらなかったのですが、ひとつだけ
N88P.BAS
100 INPUT N
110 IF N MOD 2=0 THEN 120 ELSE *ELSE1
120 IF N=2 THEN PRINT "素数" ELSE PRINT "合成数"
130 GOTO *ENDIF1
140 *ELSE1
150 I=3
160 WHILE (I<=SQR(N)) AND (N MOD I<>0)
170 I=I+2
180 WEND
190 IF I<=SQR(N) THEN PRINT "合成数" ELSE PRINT "素数"
200 *ENDIF1
202 input a
210 END
このプログラムでは、169 は「素数」と表示されます。
ところがオリジナルを若干修正した以下
PN88.BAS
100 'pn88.bas
110 defdbl a-z '倍精度指定
1000 INPUT n
1010 IF (n MOD 2)=0 THEN IF n=2 THEN PRINT "素数" ELSE PRINT "合成数"
1020 j!=sqr(n) 'ELSE
1030 FOR i!=3 TO SQR(n) STEP 2
1040 IF n MOD i!=0 THEN *EXIT1
1050 NEXT i!
1052 *EXIT1
1060 IF i!<=SQR(n) THEN PRINT "合成数";i!;j!
1062 IF i!>SQR(n) THEN PRINT "素数";i!;j!
1070 input a 'END IF
1080 END
このプログラムでは、169 は「合成数」と表示されます。
違いは、変数全体を倍精度にし、FOR 文の変数を単精度にしただけかな。
# うーん、これを反映させても改善しない。何故だー! (;_;)
11176/11135 BQO00549 konno Re^10: N88-BASICで素数を表示カウントする PRIME88.BAS
( 1) 24/03/27 00:26 11173:konnoさんへのコメント コメント数:2
> ここ、多くの処理系では割り算よりも掛け算のほうが速いと聞いたことがあるので、
> 割り算を2回するのではなく掛け算と割り算の組み合わせに変更してみました。
> これでどのくらい早くなるかは測定していないからわからない。
> 処理系によっては、むしろ遅くなったりして。
なるほど、そういうやり方もあるのですね。
このプログラムで 10000 指定の実行結果は
Number.10000 0: 0:30 Prime Number = 1233
このソースを私の FOR 文のに置き換えてみた結果は
Number.10000 0: 0: 8 Prime Number = 1233
実行時間が短縮されました。
コンパイラでは最適化でインタプリタと違う結果になるようです。
どこがどう効いたかわからないので、変更ソースを上げます。
1320 *START
1330 TM$=TIME$
1340 I=2:GOSUB *PRINT1
1350 FOR I=3 TO N '★
1360 ' IF INT(I/2)*2 = I THEN *EXIT2 '☆
1362 i2=i/2:i3=int(i/2):IF i2=i3 THEN goto *EXIT2 ' 合成数
1370 ' J=3 '☆
1380 ' WHILE (J<SQR(I)) AND (INT(I/J)*J<>I) '☆
1382 FOR J=3 TO int(SQR(I)) STEP 2 '★ 偶数をスキップ
1390 ' J=J+1 '☆
1392 I2=I/J:I3=INT(I/J):IF I2=I3 THEN GOTO *EXIT1 '★ 合成数
1400 ' WEND '☆
1402 NEXT J '★
1404 *EXIT1 '★
1406 ' if i=169 then print " 13 =";i;sqr(i);j:goto *exit2
1408 ' IF i=169 then if J=SQR(I) THEN *EXIT2
1410 IF SQR(I)<J THEN GOSUB *PRINT1
1420 *EXIT2
1430 NEXT I
1440 I=I-1
ちなみに、VGA版の結果は
Number.10000 0: 0' 1 Prime Number = 1229
結果の素数の数が 4 違いますね。
--- N88 ---
169 13*13
5041 71*71
6241 79*79
9409 97*97
10000 で 4 箇所 合成数が含まれています。
何が原因かわからないです。
11177/11135 BQO00549 konno Re: PRIME88.BAS で 「169=素数?」問題解決か
( 1) 24/03/27 22:56 11175:konnoさんへのコメント
不具合の原因がわかりました。
SQR() 関数の結果判定に問題が有ったようです。
PRIME98.BAS
1320 *START
1330 TM$=TIME$
1340 I=2:GOSUB *PRINT1
1350 FOR I=3 TO N '
1360 i2=i/2:i3=int(i/2):IF i2=i3 THEN *EXIT2 ' 合成数
1370 j2=int(SQR(I)) '
1380 FOR J=3 TO j2 STEP 2 ' 偶数をスキップ
1390 I2=I/J:I3=INT(I/J):IF I2=I3 THEN *EXIT2 ' 合成数
1400 NEXT J
1410 IF J>SQR(I)+.0001 THEN GOSUB *PRINT1 '★
1420 *EXIT2
1430 NEXT I
1440 I=I-1
このように、SQR() に +0.0001 を足したら問題が解消されました。
計算精度の問題か、最小桁が切り捨てられているのでしょうか。
いくつ足せばいいのか桁を変えて試してみました。
1410 IF J>SQR(I)+.000001 THEN GOSUB *PRINT1 ng
Number.10000 0: 0:29 Prime Number = 1233
169 5041 6241 9409 ng
1410 IF J>SQR(I)+.00001 THEN GOSUB *PRINT1 ng
Number.10000 0: 0:30 Prime Number = 1232
5041 6241 9409 ng
1410 IF J>SQR(I)+.0001 THEN GOSUB *PRINT1 ok
Number.100000 0: 2:29 Prime Number = 9592
どうも N88BASIC の問題のような気がしますが、実機でどうなるか知りたいですね。
11178/11135 CXB00940 としき Re^11: N88-BASICで素数を表示カウントする PRIME88.BAS
( 1) 24/03/28 00:43 11176:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
あ、これはまずい。
> このプログラムで 10000 指定の実行結果は
> Number.10000 0: 0:30 Prime Number = 1233
> このソースを私の FOR 文のに置き換えてみた結果は
> Number.10000 0: 0: 8 Prime Number = 1233
> 実行時間が短縮されました。
この差は大きすぎる。プログラムに間違いがあるから。
> 1382 FOR J=3 TO int(SQR(I)) STEP 2 '★ 偶数をスキップ
> 1390 ' J=J+1 '☆
ここのところ、STEP 2 なんだから、J=J+2 でなければならない。
単純にループ回数が2倍になってしまう。
ということで、おそらく、30秒は15秒ぐらいまで短縮できるはずだけど、それでも
やっぱり8秒までは縮まらないと思う。
SQR関数の精度のほうは、どうしようかな。
11179/11135 BQO00549 konno SQRの計算式
( 1) 24/03/30 15:58 11178:としきさんへのコメント コメント数:1
SQRの計算を自前で出来ないか検索してみました。
「本の虫」のサイトの「平方根のアルゴリズム 」
https://cpplover.blogspot.com/2010/11/blog-post_20.html
ここがわかりやすかったのでここから引用します。
-----------------------------------------------------------
ここで使うのは、バビロニア人の方法(Babylonian method)と呼ばれている、歴史あるアルゴリズムである。
この方法は、手動でも、プログラミングでも、非常に簡単に計算できる、大変便利で汎用的なアルゴリズムである。
しかも、速度もそれほど遅くない。
double sqrt( double s )
{
double x = s / 2.0 ; // Is there any better way to determine initial value?
double last_x = 0.0 ; // the value one before the last step
while ( x != last_x ) // until the difference is not significant
{ // apply Babylonian method step
last_x = x ;
x = (x + s / x) / 2.0 ;
}
return x ;
}
-----------------------------------------------------------
これを TurboBasic に置き換えたテストが
3000 ' SQR1.BAS
3010 'defdbl a-z
3020 screen 0
3030 cls
3040 input s
3050 x = s / 2.0 '; // Is there any better way to determine initial value?
3060 lastx = 0.0 '; // the value one before the last step
3070 ' while ( x != lastx ) '// until the difference is not significant
3080 'loop1:
3090 lastx = x
3100 x = (x + s / x) / 2.0
3110 if x <> lastx then 3080 'loop1
3120 print "SQR(";s;")=";x,lastx
3130 input a
3140 end
3020行をコメントにすれば N88BASIC でも動作します。
これをサブルーチンにして PRIME88.BAS に貼り付けて
1320 *START
1330 TM$=TIME$
1340 I=2:GOSUB *PRINT1
1350 FOR I=3 TO N
1360 IF INT(I/2)*2 = I THEN *EXIT2
1370 J=3
1375 s=I:gosub 3050:s=xx '★
1380 WHILE (J<s) AND (INT(I/J)*J<>I) '★
1390 J=J+1 '★★
1400 WEND
1410 IF J>s THEN GOSUB *PRINT1 '★
1420 *EXIT2
1430 NEXT I
1440 I=I-1
この結果は
Number.10000 0: 0:14 Prime Number = 1229
おお、素数が合ってるし、時間が半分になりました。
SQR()関数を2回実行していたのをサブルーチン1回にしたのが効いたみたいです。
さらに、★★ のところを
1390 J=J+2 '★★
このように +2 に変更した結果
Number.10000 0: 0: 9 Prime Number = 1229
おお、時間がさらに短縮して、FOR文のループとほぼ同じになりました。
ちなみに FOR文のソースにこのサブルーチンを組み込んだら
Number.10000 0: 0:11 Prime Number = 1229
2〜3秒遅くなりましたね。これが関数とサブルーチンの速度差と思われます。
思ったよりも差が無いなぁ、というのが感想です。(^^;
素数のネタはこの辺でしまいにしたいところですね。
11180/11135 CXB00940 としき Re: SQRの計算式
( 1) 24/03/30 23:41 11179:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> これを TurboBasic に置き換えたテストが
えと、whileのループをifのジャンプに変更したのはなぜでしょうか。
こちらのほうが速いのですか?
> 素数のネタはこの辺でしまいにしたいところですね。
そうですね。
明日、31日に実家へ行くので、時間が取れたら実機でいくつか試したいところ。
実は、父の命日が31日なんですよ。
ただ、日が近いということで、多くの場合、墓参りはお彼岸に集約されています。
天候だとか諸事情でお彼岸に墓参りできないときだけ命日に墓参り、と言う感じ
なのですが、まぁいろいろと存在しない事情をでっち上げて実家に顔を出すところ
まではアポイント済み。ただ、時間が取れるかどうかは別問題なんで。
11181/11135 CXB00940 としき Re^10: N88-BASICで素数を表示カウントする PRIME88.BAS
( 1) 24/03/31 14:09 11173:konnoさんへのコメント
参照先:http://toshiki.la.coocan.jp/
実家に来ています。
まず、先日アップしたあのプログラムをそのまま実行したのですが
> Number.1000 0: 0' 0 Prime Number = 168
うちのN88-BASICでは、素数の数が168になりました。
169は素数としてカウントされませんでした。
どうやらSQR関数、うちの環境のほうが精度が高いらしい。
ちなみに、ファイル出力ではなく画面表示で、所要時間は0秒〜1秒くらい。
あまり違いはないですね。
とりあえず時間切れ、続きは後ほど。
11182/11135 CXB00940 としき Re^11: N88-BASICで素数を表示カウントする PRIME88.BAS
( 1) 24/03/31 15:48 11176:konnoさんへのコメント
参照先:http://toshiki.la.coocan.jp/
続いて、先日上げたプログラムのまま、すなわち、SQR関数の部分もいじらず、
変数Jのカウントアップも1ずつのままで10000までの結果。
> Number.10000 0: 0' 1 Prime Number = 1229
素数の数は1229と出ました。やっぱりうちの環境では誤差がないみたい。
ちなみに、所要時間は、画面表示だと12秒、ファイル出力だと13秒。
これはいささか直感と記憶に反している。
記憶だと、画面表示のほうがスクロールアップに時間がとられるので遅くなったはず
なのですがね。ま、でも、誤差の範囲。
次、変数 J のカウントアップを J=J+2 としたら所要時間は7秒まで短縮。
やっぱりループ回数が2倍というのは大きかった模様。
素数の数は1229なので、計算誤差の問題もないですね。
ところで、うちのBASICインタープリタは1987年製のVer5.0というやつです。
konnoさんのところの版数とかはわかりますか?
11183/11135 CXB00940 としき Re^9: N88-BASICで素数を表示カウントする PRIME88.BAS
( 1) 24/03/31 16:08 11172:としきさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
実家での検証、最後。
> ここ、多くの処理系では割り算よりも掛け算のほうが速いと聞いたことがあるので、
> 割り算を2回するのではなく掛け算と割り算の組み合わせに変更してみました。
> これでどのくらい早くなるかは測定していないからわからない。
メインのループを
1350 FOR I=3 TO N
1360 IF INT(I/2)*2 = I THEN *EXIT2
1370 J=3:I2=I/J:I3=INT(I/J)
1380 WHILE J<SQR(I) AND I2<>I3
1390 J=J+2:I2=I/J:I3=INT(I/J)
1400 WEND
1410 IF J>SQR(I) THEN GOSUB *PRINT1
1420 *EXIT2
1430 NEXT I
こうやって、割り算2回で20000までの素数を求めたら21秒で2262個。
元のままの、割り算と掛け算だと17秒、2262個。
うん、やっぱりうちでは、誤差というには差が大きいくらい、掛け算のほうが早い
模様。
以上、レス元が分散して申し訳ありませんが、実家での検証3連発でした。
11184/11135 BQO00549 konno Re^2: SQRの計算式
( 1) 24/03/31 22:26 11180:としきさんへのコメント
> えと、whileのループをifのジャンプに変更したのはなぜでしょうか。
> こちらのほうが速いのですか?
私は while文をあまり使わないので、無意識に 慣れた IF文に変えてしまってました。(^^;
オリジナルのソースに wend を入れるだけでしたね。(^^;
#11179 で書きましたが
> ちなみに FOR文のソースにこのサブルーチンを組み込んだら
> Number.10000 0: 0:11 Prime Number = 1229
> 2〜3秒遅くなりましたね。これが関数とサブルーチンの速度差と思われます。
同じ条件では、while文の方が速いと思われます。
そこで、このサブルーチンの while と FOR で比較してみました。
FOR文 Number.100000 0: 2:51 Prime Number = 9592
WHILE文 Number.100000 0: 2:47 Prime Number = 9592
10万で4秒の差でした。思ったよりも差が小さかったですね。
SQR 1回あたり7〜10回程度のループで済んでいるから差が小さいのでしょう。
> なのですが、まぁいろいろと存在しない事情をでっち上げて実家に顔を出すところ
> まではアポイント済み。ただ、時間が取れるかどうかは別問題なんで。
お手間を取らせて申し訳ないですが、よろしくお願いします。
11185/11135 BQO00549 konno Re^10: N88-BASICで素数を表示カウントする PRIME88.BAS
( 1) 24/04/01 00:27 11183:としきさんへのコメント コメント数:2
ここにまとレスします。
> > Number.1000 0: 0' 0 Prime Number = 168
> うちのN88-BASICでは、素数の数が168になりました。
> 169は素数としてカウントされませんでした。
> どうやらSQR関数、うちの環境のほうが精度が高いらしい。
これは驚きです! ということは、98エミュの問題か、ファイルが壊れているかですね。
> ちなみに、所要時間は、画面表示だと12秒、ファイル出力だと13秒。
> これはいささか直感と記憶に反している。
TurboBasic でも同じような結果です。画面表示は遅いというのは思い込みなのでしょう。
> ところで、うちのBASICインタープリタは1987年製のVer5.0というやつです。
> konnoさんのところの版数とかはわかりますか?
88-BASIC(86) Compiler version 6.0
1988/08/24 00:00 61,440 BASICC.COM
うちで使用したコンパイラ版はこれですね。
> こうやって、割り算2回で20000までの素数を求めたら21秒で2262個。
> 元のままの、割り算と掛け算だと17秒、2262個。
> うん、やっぱりうちでは、誤差というには差が大きいくらい、掛け算のほうが早い
> 模様。
なるほど。やはり掛け算が速いのですね。
> 以上、レス元が分散して申し訳ありませんが、実家での検証3連発でした。
お忙しい中色々検証していただき、ありがたいです。
N88BASICの精度疑惑も晴れたので、98エミュの検証が必要そうですね。
11186/11135 BQO00549 konno T98-NEXT でN88BASIC検証
( 1) 24/04/02 00:16 11185:konnoさんへのコメント
以前N88BASICが動かなかったT98-NEXT で再挑戦しました。
コンパイラ版が動かなかったのはメモリ不足だったようです。
ATOK8がメインメモリに居座っていたので削除したら動きました。(^^;
ただし、BATのオプションが効かなくて、ソースファイル名を手打ちしました。(^^;
結果はほかのエミュと同じで駄目でした。
インタプリタも、実機ROMにチェックを入れたら動きました。
結果はやっぱり駄目でした。
98エミュは全滅です。
うーむ、このバージョンの N88BASIC に問題がある可能性があるのでしょうか。
11187/11135 CXB00940 としき Re^11: N88-BASICで素数を表示カウントする PRIME88.BAS
( 1) 24/04/03 16:20 11185:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> これは驚きです! ということは、98エミュの問題か、ファイルが壊れているか
エミュの問題、というのは考え易いところです。
が、ファイルの破壊となった場合、そんな精度に関係するところが絶妙に壊れる、
というのはなかなか考えにくい。
ただ、N88(86)では使っていない技術だとは思いますが、いくつかの処理系では、
関数の速度と精度向上のため、全てを計算で求めるのではなく、大きな定数表を
使う場合がある、と聞いたことはあります。とはいっても超巨大というほどの表
ではなく、引数のいくつかに分解して、それぞれの結果を足すとかかけるとかで
速度と精度を両立させます。
その場合は、その定数表の一部だけが間違っているとか精度が足りないことが発生
しうるわけです。でも、これって、三角関数とか対数関係の関数で使うワザだった
ような気がする。
平方根でも使うことがあるのかなぁ。
> 88-BASIC(86) Compiler version 6.0
> 1988/08/24 00:00 61,440 BASICC.COM
これ、頭のNが欠けているのは転記ミスですよね。
実は、私の記憶でも、88年のVer6が最終版、ということになっているからです。
そして私の手元には87年のVer5しかないわけですが、バージョンアップするかどうか
という判断に際して、どこが変わったかという情報がなくてバージョンアップを
しなかった、というおぼろげな記憶があります。
ところでkonnoさんのところでは、TurboBasicではなく、N88BASICのコンパイラと
インタプリタで同じ結果になります?
あと、インタプリタとコンパイラでバージョンは同じですか?
11188/11188 CXB00940 としき 「全部表示 会議室風」が何かおかしい
( 1) 24/04/03 17:29 コメント数:1
参照先:http://toshiki.la.coocan.jp/
こちらの掲示板での過去ログ表示で気がつきました。
[全部表示 会議室風]のリンクを押して表示される発言の中に、そのログのトップの
ツリーのルートの発言が含まれていないようです。
具体的には
過去ログ26では#10734
過去ログ25では#10632
過去ログ24では#10229
・・・
過去ログ2では#974
過去ログ1では#418
が表示されないようです。
ご確認をお願いします。
11189/11135 BQO00549 konno Re^12: N88-BASICで素数を表示カウントする PRIME88.BAS
( 1) 24/04/04 01:01 11187:としきさんへのコメント コメント数:1
> その場合は、その定数表の一部だけが間違っているとか精度が足りないことが発生
> しうるわけです。でも、これって、三角関数とか対数関係の関数で使うワザだった
> ような気がする。
> 平方根でも使うことがあるのかなぁ。
原因が分かったような気がします。
N88BASIC(86) では、FOR文が倍精度では動かないので単精度でやって NG だったのですが
1030 defdbl A-Z と変数を倍精度にし、FOR文の I だけ I! で単精度でやってみました。
1340 I=2:GOSUB *PRINT1
1342 i=3
1350 FOR I!=3 TO N
1360 IF INT(I/2)*2 = I THEN *EXIT2
1370 J=3
1380 WHILE (J<SQR(I)) AND (INT(I/J)*J<>I)
1390 J=J+1
1400 WEND
1410 IF J>SQR(I) THEN GOSUB *PRINT1
1420 *EXIT2
1422 i=i+1
1430 NEXT I!
1440 I=I-1
他は変えていませんが、このプログラムでは 169 が表示されず、正常になりました。
# 汚れていたのは SQR(I) だったんです。(By now shika)
変数 I が倍精度だと数値の比較が正常なのに、単精度だと 表示は整数でも内部の計算がズレる模様。
想像ですが、例えば比較計算は倍精度で、表示は単精度に丸められているとか。
> > 88-BASIC(86) Compiler version 6.0
> > 1988/08/24 00:00 61,440 BASICC.COM
> これ、頭のNが欠けているのは転記ミスですよね。
はい、そうです。失礼しました。m(__)m
> ところでkonnoさんのところでは、TurboBasicではなく、N88BASICのコンパイラと
> インタプリタで同じ結果になります?
同じ結果になります。上の実験はインタプリタではしてないですが。
> あと、インタプリタとコンパイラでバージョンは同じですか?
同じだと思います。起動メッセージが同じなので。
日付は少し違いますね。
11190/11188 BQO00549 konno Re: 「全部表示 会議室風」が何かおかしい
( 1) 24/04/04 01:07 11188:としきさんへのコメント コメント数:1
> こちらの掲示板での過去ログ表示で気がつきました。
> [全部表示 会議室風]のリンクを押して表示される発言の中に、そのログのトップの
> ツリーのルートの発言が含まれていないようです。
げげげ、・・・・・・
確認しました。しばしお待ちください。m(__)m
11191/11135 CXB00940 としき Re^13: N88-BASICで素数を表示カウントする PRIME88.BAS
( 1) 24/04/04 12:15 11189:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
「妙だな」というのは、どこぞの小学生のよく言うせりふですが、それはさておき。
#11164にも書きましたが、N88だと単精度でも倍精度でも上限は同じです。
また、演算速度が単精度の方が速いという理由から私は全て単精度でやっているの
ですが、konnoさんが倍精度を選ばれている理由は何ですか?
他のBASICだと上限が違うとかあるのでしょうか。
さて、私のコードでは全て単精度でやっています。なので、精度変換の問題は出ない
はず。実際、うちでは問題が出ていません。
でも、#11173では、同じコードで問題が出ているということです。
なので、これは精度変換の問題ではないと思われます。
> 他は変えていませんが、このプログラムでは 169 が表示されず、正常になりました。
このプログラムだと、単精度の I! と倍精度の I の両方でカウント処理が発生します。
倍精度の I だけ使って WHILE のループにしたほうがいいような気がします。
> 想像ですが、例えば比較計算は倍精度で、表示は単精度に丸められているとか。
N88のマニュアルでは、異なる型同士での演算の場合は高い精度のほうに合わせて
行われるとのこと。これは比較演算でも同じはず。
で、私の疑っていた、konnoさんのところのコンパイラとインタプリタのバージョン
違いという疑いは晴れたので、するとあとは、私のところのバージョンとkonnoさん
のところのバージョンが異なる、という問題は残ります。
とりあえず、出発点は#11173。同じコードなのに結果が異なる、ということ。
あ、重要な問題がある。
私がもしかしたら、アップしたのとは異なるコードを実行していた可能性。
実はこの可能性が一番高いかも。
11192/11135 CXB00940 としき Re: PRIME88.BAS で 「169=素数?」問題
( 1) 24/04/05 02:07 11175:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
自分で実験できないのにあれこれ言って申し訳ありません。
> 条件を色々変えて試しても結果は変わらなかったのですが、ひとつだけ
> N88P.BAS
> ところがオリジナルを若干修正した以下
> PN88.BAS
N88P.BASとPN88.BAS、konnoさん的には「若干修正」かもしれませんが、内部的には
もしかしたら大幅な修正かもしれません。
そこで結果を教えていただきたいのが、
> PN88.BAS
> 110 defdbl a-z '倍精度指定
ここを単精度指定にしたらどうなるか、ということ。
とても興味があります。
11193/11188 BQO00549 konno Re^2: 「全部表示 会議室風」が何かおかしい
( 1) 24/04/06 00:30 11190:konnoさんへのコメント コメント数:1
> > [全部表示 会議室風]のリンクを押して表示される発言の中に、そのログのトップの
> > ツリーのルートの発言が含まれていないようです。
> 確認しました。しばしお待ちください。m(__)m
ううう、3日間腐海暗闇の中で藻掻いていました。(;_;)
wforum.cgi を色々弄ってみましたがどうやってもルート発言が表示されません。(>_<)
仕方がないので過去ログの先頭に改行を追加してみたら表示されました。
うげぇ、今までの苦労は何だったんだ・・・・
唯の改行だとツリー表示にゴミが表示されるので、現行ログの形式でダミーを入れました。
0001<>00.00.00.00<>1097421569<>
番号 IPアドレス 書き込み時間(古ければスキップ?)
このように、書き込み時間が古ければ自動的にスキップしてくれるようです。
この処理をどこでやっているのかはわかりません。
色々弄った版はツリー表示がおかしくなったので、修正前のに戻したら直りました。
結局 cgi は弄らずに、過去ログ形式を変更することで解決しました。(-_-;) ヤレヤレダゼ
何かおかしなところに気が付いたら教えてください。m(__)m
11194/11135 BQO00549 konno Re^14: N88-BASICで素数表示の問題
( 1) 24/04/06 01:40 11191:としきさんへのコメント コメント数:1
> #11164にも書きましたが、N88だと単精度でも倍精度でも上限は同じです。
> また、演算速度が単精度の方が速いという理由から私は全て単精度でやっているの
> ですが、konnoさんが倍精度を選ばれている理由は何ですか?
N88 は FOR文のカウントに倍精度が使えない制限があるようです。
それで単精度でやったら問題が出たので、倍精度でやり直してみたという経緯です。
> さて、私のコードでは全て単精度でやっています。なので、精度変換の問題は出ない
> はず。実際、うちでは問題が出ていません。
> でも、#11173では、同じコードで問題が出ているということです。
> なので、これは精度変換の問題ではないと思われます。
私は N88BASIC の特定のバージョン(V6.0)の問題なのではないかと疑っています。
もちろん 98エミュの問題の可能性も排除できないので実機で確認したいのです。
> > 他は変えていませんが、このプログラムでは 169 が表示されず、正常になりました。
> このプログラムだと、単精度の I! と倍精度の I の両方でカウント処理が発生します。
> 倍精度の I だけ使って WHILE のループにしたほうがいいような気がします。
私は while の入れ子は特に間違えやすいので、FOR文でやりました。
結果は同じになると思います。
> N88のマニュアルでは、異なる型同士での演算の場合は高い精度のほうに合わせて
> 行われるとのこと。これは比較演算でも同じはず。
なるほど、それで謎の挙動がわかったような気がします。
比較の実験結果をあげてみます。
11195/11135 BQO00549 konno Re^2: PRIME88.BAS で 「169=素数?」問題
( 1) 24/04/06 02:05 11192:としきさんへのコメント コメント数:2
> > PN88.BAS
> > 110 defdbl a-z '倍精度指定
>
> ここを単精度指定にしたらどうなるか、ということ。
> とても興味があります。
丁度良いテストプログラムを作ったので上げます。
3000 ' SQR88.BAS
3010 'defdbl a-z
3012 defsng a-z
3020 'screen 0
3030 cls
3040 input s
3042 OPEN "SQR.dat" FOR OUTPUT AS #1
3046 cc=0
3050 x = s / 2.0 '; // Is there any better way to determine initial value?
3060 lastx = 0.0 '; // the value one before the last step
3070 'while ( x != lastx ) '// until the difference is not significant
3090 lastx = x
3100 x = (x + s / x) / 2.0
3112 cc=cc+1
3114 print x;lastx,cc
3116 print#1, x;lastx,cc
3110 if x < lastx then 3070
3120 print "SQR(";s;")=";x,lastx,cc
3122 print#1, "SQR(";s;")=";x,lastx,cc
3124 close
3130 input a
3140 end
このプログラムで、TurboBasic の結果は
単精度
43.25 84.5 1
23.57875633239746 43.25 2
15.37311267852783 23.57875633239746 3
13.18316555023193 15.37311267852783 4
13.00127220153808 13.18316555023193 5
13 13.00127220153808 6
13 13 7
SQR( 169 )= 13 13 7 回
倍精度
43.25 84.5 1
23.57875722543352 43.25 2
15.37311286945074 23.57875722543352 3
13.18316604902914 15.37311286945074 4
13.00127244856782 13.18316604902914 5
13.00000006226796 13.00127244856782 6
13 13.00000006226796 7
13 13 8
SQR( 169 )= 13 13 8 回
倍精度の方が収束するのに1回多く掛かっています。
どちらでも計算は倍精度でやっているのがわかります。
一方、N88BASIC の結果は
単精度
43.25 84.5 1
23.5788 43.25 2
15.3731 23.5788 3
13.1832 15.3731 4
13.0013 13.1832 5
13 13.0013 6
13 13 7
SQR( 169 )= 13 13 7 回
倍精度
43.25 84.5 1
23.57875722543353 43.25 2
15.37311286945074 23.57875722543353 3
13.18316604902914 15.37311286945074 4
13.00127244856782 13.18316604902914 5
13.00000006226796 13.00127244856782 6
13 13.00000006226796 7
13 13 8
13 13 9
SQR( 169 )= 13 13 9 回
おや、単精度の場合は SQR の計算も単精度なのか、それとも表示だけなのか?
倍精度では収束したのにさらにもう1回多く計算しています。???
この結果は、WHILE 文にしても同じでした。
そして、単精度の時だけ 169 が素数と誤判定しているのです。
このことから私は、「>」や「>=」などの比較式で単精度の時だけ誤差が出ていると疑ったのです。
V6.0に問題が有るかどうかは、実機で確認する以外にわからないと思います。
11196/11188 CXB00940 としき Re^3: 「全部表示 会議室風」が何かおかしい
( 1) 24/04/06 10:50 11193:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> 仕方がないので過去ログの先頭に改行を追加してみたら表示されました。
この現象から見ると、過去ログと現行ログでの分岐に問題がありそうですね。
まさかと思いますが、そもそも分岐していない、とか。
> この処理をどこでやっているのかはわかりません。
もともとこのルーチン、作ったのはkonnoさんですから。
作った本人がわからないようではどうしようもありません。
もう大丈夫だとは思いますが、不要なコメント、とかいう目くらましにやられて
いる、ということはないでしょうか。
とりあえず、今のところは問題ないような感じです。
11197/11135 CXB00940 としき Re^15: N88-BASICで素数表示の問題
( 1) 24/04/06 11:26 11194:konnoさんへのコメント
参照先:http://toshiki.la.coocan.jp/
> N88 は FOR文のカウントに倍精度が使えない制限があるようです。
そです。
これはマニュアルにも明記されている仕様です。
> それで単精度でやったら問題が出たので、倍精度でやり直してみたという経緯です。
なるほど、いきさつが理解できました。
> 私は N88BASIC の特定のバージョン(V6.0)の問題なのではないかと疑っています。
現時点では、私もこの線が濃厚だと思っております。
> 私は while の入れ子は特に間違えやすいので、FOR文でやりました。
BASICを極めたいのならWHILEは避けて通れません。
私もかなり錆付いてはいますが、まだkonnoさんより私のほうが、BASICに関しては
一日の長がありそうな感じ。
> 結果は同じになると思います。
いや、結果の問題ではなく速度の問題。
加算するのはループカウンタだけでいいでしょう、ということです。
11198/11135 CXB00940 としき Re^3: PRIME88.BAS で 「169=素数?」問題
( 1) 24/04/06 11:27 11195:konnoさんへのコメント
参照先:http://toshiki.la.coocan.jp/
> 3000 ' SQR88.BAS
これ、あとで私も検証してみます。最短で今日の午後。
> このプログラムで、TurboBasic の結果は
> どちらでも計算は倍精度でやっているのがわかります。
ダウト。
> 単精度
> 43.25 84.5 1
> 23.57875633239746 43.25 2
> 倍精度
> 43.25 84.5 1
> 23.57875722543352 43.25 2
もうここですでに値が異なります。
すなわち、表示だけ倍精度、という可能性が濃厚。
> おや、単精度の場合は SQR の計算も単精度なのか、それとも表示だけなのか?
N88の場合、仕様では、引数の型が結果の型、ということになっています。
このプログラムでは、2.0 という単精度型で割り算をしています。
ここを 2# としてみたら、もしかしたら違いが出てくる可能性があります。
11199/11135 CXB00940 としき Re^3: PRIME88.BAS で 「169=素数?」問題
( 1) 24/04/06 14:51 11195:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
実家に来ています。
うちの母、風邪気味だというのに買い物に行きたいのだとか。
母と同居しているうちの弟、免許すら持っていないので、その手の案件は私が対応。
ということで、まもなく連れ出されてしまいますが、その前に。
まず、うちのN88BASIC、コンパイラはありません。
タイムスタンプは以下。
N88BASIC EXE 161,280 87-10-30 0:00
N88BASIC LIB 178,176 86-08-14 13:51
ん〜、ライブラリのほう、もしかしたらバージョンが古いかも。
そして、この環境で
> 丁度良いテストプログラムを作ったので上げます。
> 3000 ' SQR88.BAS
このプログラムを load して list をみたら、
3050 X = S / 2! '; // Is there any better way to determine initial value?
3100 X = (X + S / X) / 2!
と、自動で変換されてしまっていました。
もしかしたらkonnoさんのところでも、この手の意図せざる自動変換が発生している
かもしれません。当然、コンパイラのほうでも。
一度、インタプリタのほうで list をたたいて、自動変換の有無を確認されたほうが
いいでしょう。
そして、読み込ませてすぐに run させたら、あれ?
konnoさんのところと実行結果が異なる。
何が異なるって、途中経過が一切表示されない。妙だな。
よくリストを見たら、結果表示がループの外に出ている。
こういうトリックはやめて欲しいけど、でも私も良くやるので人のことは言えない。
とりあえず、3110行の if 文を3123行に持ってきて、ここで時間切れ。
続きは帰宅後。
何時ぐらいになるかなぁ。
11200/11135 CXB00940 としき Re^4: PRIME88.BAS で 「169=素数?」問題
( 1) 24/04/06 23:09 11199:としきさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> 続きは帰宅後。
続きです。
> よくリストを見たら、結果表示がループの外に出ている。
> こういうトリックはやめて欲しいけど、でも私も良くやるので人のことは言えない。
違う。
結果表示が改行されず、同一行に上書きされているような感じ。
つまり、トリックは私が仕掛けた、ということで。
大変失礼しました。
そして、私が悪かったにもかかわらず
> とりあえず、3110行の if 文を3123行に持ってきて、ここで時間切れ。
こんなことをやったから、出力書式がめちゃくちゃ。
とりあえず、konnoさんと同じような書式にVzでそろえた結果です。
単精度2.0
43.25 84.5 1
23.5788 43.25 2
15.3731 23.5788 3
13.1832 15.3731 4
13.0013 13.1832 5
13 13.0013 6
13 13 7
SQR( 169 )= 13 13 7
倍精度2.0
43.25 84.5 1
23.57875722543353 43.25 2
15.37311286945074 23.57875722543353 3
13.18316604902914 15.37311286945074 4
13.00127244856782 13.18316604902914 5
13.00000006226796 13.00127244856782 6
13 13.00000006226796 7
13 13 8
13 13 9
SQR( 169 )= 13 13 9
念のため、2! のところを全て 2# にしてみたけど、結果は同じでした。
どうも、見たところ、結果は全て同じ。
収束したのに1回多くループを回っているところも同じ。
にもかかわらず、うちの環境では、169は素数にならない。
まだアップしたままのprime88.zipを再度落としてみて、ファイル比較して同じもので
あることも確認済み。そして、名前を変えて、新しく落としたほうを実行してみて
169が素数にならないことも確認済み。
何じゃこりゃ。
11201/11188 BQO00549 konno Re^4: 「全部表示 会議室風」が何かおかしい
( 1) 24/04/07 00:51 11196:としきさんへのコメント
> > 仕方がないので過去ログの先頭に改行を追加してみたら表示されました。
>
> この現象から見ると、過去ログと現行ログでの分岐に問題がありそうですね。
> まさかと思いますが、そもそも分岐していない、とか。
うう、そのまさかでした。(>_<)
open(IN,"$logfile") || &error("Open Error: $logfile");
$top = <IN>;
こうなっていたところを
# $top = <IN>;
$top = <IN> if ($in{'act'} ne "past");
こう変更したら今までの過去ログファイルのままでも正常になりました。
うう、これも試していたのに弄りすぎておかしくなっていたようです。(>_<)
アドバイスありがとうございました。m(__)m
11202/11135 CXB00940 としき Re^5: PRIME88.BAS で 「169=素数?」問題
( 1) 24/04/07 01:17 11200:としきさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
訂正、ではないような。
補足、かな。
> > よくリストを見たら、結果表示がループの外に出ている。
> > こういうトリックはやめて欲しいけど、でも私も良くやるので人のことは言えない。
>
> 違う。
> 結果表示が改行されず、同一行に上書きされているような感じ。
> つまり、トリックは私が仕掛けた、ということで。
結果表示が上書きのよう、というのはそのとおりなんですが。
結果表示がループの外、というトリックは、やっぱりkonnoさんだった。
#11195より
> 3070 'while ( x != lastx ) '// until the difference is not significant
> 3090 lastx = x
> 3100 x = (x + s / x) / 2.0
> 3112 cc=cc+1
> 3114 print x;lastx,cc
> 3116 print#1, x;lastx,cc
> 3110 if x < lastx then 3070
> 3120 print "SQR(";s;")=";x,lastx,cc
> 3122 print#1, "SQR(";s;")=";x,lastx,cc
これ、行番号順に並んでいないじゃないのよさ。
BASICの場合、行番号順に実行されるわけですから、実行時には
> 3070 'while ( x != lastx ) '// until the difference is not significant
> 3090 lastx = x
> 3100 x = (x + s / x) / 2.0
> 3110 if x < lastx then 3070
> 3112 cc=cc+1
> 3114 print x;lastx,cc
> 3116 print#1, x;lastx,cc
> 3120 print "SQR(";s;")=";x,lastx,cc
> 3122 print#1, "SQR(";s;")=";x,lastx,cc
となるわけでして。
まったくもう。
前にも書いたと思いますが、もうちょっと行番号の並びとかインデントに気を配って
プログラムを書いていただけないでしょうか。
バグが混入し易くなりますよ、と、繰り返しお伝えしていますよね。
こうやって、残り少ない人生を無駄にしてしまうわけですから。
でも、このプログラムだと、N88なら、ループ内での途中表示は全くないはず。
つまり、#11195の結果は出ないはず。
すると、あの結果はどうやって出したのだろう。
結果の出たあと、プログラムを書き換えてからアップした?
違う処理系での結果をN88での結果と間違えて書いた?
それはさておき。
ゆっくり入浴していたときにつらつらと思い出したこと。
大学時代の情報処理初級の授業で、丸め誤差と打切り誤差、桁落ち、情報落ちの
違い、なんてことをやったわけですよ。もはやほとんど覚えていませんがね。
そして、そういった誤差をなくすための方法として多倍長精度演算というのがある、
ということも思い出しました。こいつをやるとてきめんに遅くなるのですが、誤差も
非常に少なくなる。多倍長用のuBASICというのを知ったのは、確か私が大学を卒業
した直後ぐらいだったか。
多倍長っていうのは、例えば、1バイトに数字一桁しか格納しない、という方法。
実際の実装では、そんなことやっていたらメモリ効率が悪いので、1バイトに0から
99までの2桁の数字を格納する、なんていうのが多いかな。86のアセンブラにも
それようの命令があったんじゃないかな、BCD演算、というやつ。Z80にはあった
ような気がする。
そしてアセンブラにあるくらいだからBASICにもあるわけでして、もしかしたら上記
のuBASICがそうだったかもしれないけど、10進BASICという実装があったはず。
で、話を戻して、誤差。
> 3110 if x < lastx then 3070
こいつを
> 3110 if x < lastx then print "div=",lastx-x:goto 3070
とやってみたらどうでしょう。
1回多くループするところで、いったい何がおきているのか見えてくるかも。
11203/11135 BQO00549 konno Re^6: PRIME88.BAS で 「169=素数?」問題
( 1) 24/04/07 20:41 11202:としきさんへのコメント コメント数:1
まとレスで失礼します。
> ダウト。
> > 23.57875633239746 43.25 2
> > 23.57875722543352 43.25 2
> もうここですでに値が異なります。
> すなわち、表示だけ倍精度、という可能性が濃厚。
うう、眠くてよく見てませんでした。(>_<)
表示だけ倍精度、が正解のようですね。(^^;
> N88の場合、仕様では、引数の型が結果の型、ということになっています。
> このプログラムでは、2.0 という単精度型で割り算をしています。
> ここを 2# としてみたら、もしかしたら違いが出てくる可能性があります。
> このプログラムを load して list をみたら、
> 3050 X = S / 2! '; // Is there any better way to determine initial value?
> 3100 X = (X + S / X) / 2!
> と、自動で変換されてしまっていました。
なんと! インタプリタでは精度指定の無い定数は自動的に単精度になるのですね。
> もしかしたらkonnoさんのところでも、この手の意図せざる自動変換が発生している
> かもしれません。当然、コンパイラのほうでも。
> 一度、インタプリタのほうで list をたたいて、自動変換の有無を確認されたほうが
> いいでしょう。
T-98NEXT で確認しました。やはり自動変換されます。
> よくリストを見たら、結果表示がループの外に出ている。
> 結果表示が上書きのよう、というのはそのとおりなんですが。
> 結果表示がループの外、というトリックは、やっぱりkonnoさんだった。
げげ、他のソースからコピペして行番号を変えるのを忘れてました。m(__)m
申し訳ないです。m(__)m
> 前にも書いたと思いますが、もうちょっと行番号の並びとかインデントに気を配って
> プログラムを書いていただけないでしょうか。
> バグが混入し易くなりますよ、と、繰り返しお伝えしていますよね。
> こうやって、残り少ない人生を無駄にしてしまうわけですから。
インタプリタを弄るのはもう何十年ぶりなもので、うっかりやらかしてしまいました。m(__)m
気を付けます。m(__)m
> でも、このプログラムだと、N88なら、ループ内での途中表示は全くないはず。
> つまり、#11195の結果は出ないはず。
3110番を 3118 に変更すれば正常に出力されると思うのですが
私が何か勘違いしている?
> > 3110 if x < lastx then print "div=",lastx-x:goto 3070
> とやってみたらどうでしょう。
> 1回多くループするところで、いったい何がおきているのか見えてくるかも。
重複部分は以下のようになりました。
div 6.226795723485168D-08 13 13 8
div 2.220446049250313D-16 13 13 9
SQR( 169 )= 13 13 9
比較はほぼ間違いなく単精度でしょうね。(^^;
11204/11135 BQO00549 konno Re^7: PRIME88.BAS で 「169=素数?」問題
( 1) 24/04/08 01:46 11203:konnoさんへのコメント コメント数:1
> 重複部分は以下のようになりました。
> div 6.226795723485168D-08 13 13 8
> div 2.220446049250313D-16 13 13 9
これ間違っていました。m(__)m 正しい数値を各社で比較します。
----- 単精度 -----
N88BASIC
div= 1.27316E-03 13 13.0013 6
TurboBasic
div= 1.272201538085938E-003 13 13.00127220153808 6
T-BASIC
div= 1.272201538085938E-003 13 13.00127220153808 6
N88BASICは精度もいまいちな感じですね。
----- 倍精度 -----
N88BASIC
div= 1.272386299866479D-03 13.00000006226796 13.00127244856782 6
div= 6.226795723485168D-08 13 13.00000006226796 7
div= 2.220446049250313D-16 13 13 8
div= 0 13 13 9
TurboBasic
div= 1.272386299866923E-003 13.00000006226796 13.00127244856782 6
div= 6.226795790098552E-008 13 13.00000006226796 7
div= 0 13 13 8
T-BASIC
div= 1.272386299866479D-03 13.00000006226796 13.00127244856782 6
div= 6.226795745689628D-08 13 13.00000006226796 7
div= 0 13 13 8
全部違うと思ったら、6回目の N88 と T が同じ数値ですね。
これでなにかわかるでしょうか。
11205/11135 CXB00940 としき Re^8: PRIME88.BAS で 「169=素数?」問題
( 1) 24/04/08 12:28 11204:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
いろいろと見えてきたようです。
> N88BASICは精度もいまいちな感じですね。
私が仕様を知っているのはN88だけですが、N88に関していえば、まさに仕様どおり。
N88の単精度は、6桁までしか表示されないのですよ。
そして、計算されるのは7桁目まで。
他の処理系の単精度は16桁も表示されるのですね。
> ----- 倍精度 -----
> これでなにかわかるでしょうか。
いくつかわかることがあります。
まず、N88から。
前回の単なる出力結果だと、x も lastx も13で等しいのに次のループに回っている
のが不思議に思えました。でも実際には 2.220446049250313D-16 だけの差があった
わけであり、次のループに回っているのが正当でした。一方で、あまりにも差が
少なすぎたのでしょう、表示は13で打ち切られてしまっている。
ここ、私が前に書いたように print using を使えば、もしかしたら表示されていた
可能性はあります。
つぎ、TurboBasic。
N88やT-BASICだと、単精度指数の表記はEですが、倍精度指数はDを使っています。
でも、TurboBasicは、倍精度でもEで表示されている。
なんか違和感。これが仕様なんだろうなぁ。
ちなみにEは指数(exponent)の略といわれています。Dは倍(double)の略らしい。
なお、表記は同じでも値は異なっているので、計算そのものはきちんと倍精度で
行われている模様。
ところで、Wikipediaによると、指数表示でEを使うのは国際規格らしい。
実際、Excelとかでもそうなっているし。
もしかしたら倍精度でDを使うって、日本のどこかが始めたことかも。
NECとかシャープとか。
昔のMS-BASICでそうだったのかもしれないけど。
そして、T-BASICを含めて、細かい桁数の計算ではいくらかの精度差が発生すること
がわかります。
今回の話題の出発点の169が素数になってしまうという問題も、konnoさんのところの
エミュ環境のN88で起こっている話ですから、うちの実機のPC98だと、konnoさんの
ところのN88とは結果が異なる可能性がありそう。
ということで、今回の結果を出した検証プログラム、#11195に載っているものと
大体同じものだと思いますが、念のため、もう一度示してください。重要なのは表示
でして、同じような表示にしたいので表示部は必須。
なにとぞよろしくお願いします。
11206/11135 BQO00549 konno SQRの単精度と倍精度の表示検証ソース
( 1) 24/04/08 23:33 11205:としきさんへのコメント コメント数:1
> ということで、今回の結果を出した検証プログラム、#11195に載っているものと
> 大体同じものだと思いますが、念のため、もう一度示してください。重要なのは表示
> でして、同じような表示にしたいので表示部は必須。
DOSVAXJ3 の32ビット版をJ31モードにして TBasicインタプリタが起動できました。
結構互換性があるのね。
それで、ソースをリナンバーしてみました。
RENUM 3000
これで、3000 から始まる行番号にキチンと並べ替えられました。\(^^)/ ヤッタ-
ではそのソースを貼り付けます。
3000 ' SQR-3.BAS
3010 DEFDBL A-Z
3020 'defsng a-z
3030 'screen 0
3040 CLS
3050 INPUT S
3060 OPEN "SQR.dat" FOR OUTPUT AS #1
3070 CC=0
3080 X = S / 2! '; // Is there any better way to determine initial value?
3090 LASTX = 0! '; // the value one before the last step
3100 'while ( x != lastx ) '// until the difference is not significant
3110 LASTX = X
3120 X = (X + S / X) / 2!
3130 CC=CC+1
3140 PRINT "div=";LASTX-X, X,LASTX,CC
3150 PRINT#1,"div=";LASTX-X, X,LASTX,CC
3160 IF X < LASTX THEN 3100
3170 PRINT "SQR(";S;")=";X,LASTX,CC
3180 PRINT#1, "SQR(";S;")=";X,LASTX,CC
3190 CLOSE
3200 INPUT A
3210 END
このままで J31 と PC-98 で動くと思います。
11207/11135 CXB00940 としき Re: SQRの単精度と倍精度の表示検証ソース
( 1) 24/04/09 15:06 11206:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> このままで J31 と PC-98 で動くと思います。
ありがとうございます。
次に実家に行ったときに、このコードを走らせたいと思います。
これをこのまま、といいたいところですが、おそらく、ファイル出力のところ、
OUTPUTはAPPENDに変更させていただく予定。
あと、もともとの#11175に立ち返って。
> 条件を色々変えて試しても結果は変わらなかったのですが、ひとつだけ
> N88P.BAS
> ところがオリジナルを若干修正した以下
> PN88.BAS
#11192にも書きましたが、内部的には若干の修正ではない可能性があります。
なので、しつこくてもうしわけありませんが
> PN88.BAS
> 110 defdbl a-z '倍精度指定
> ここを単精度指定にしたらどうなるか、
この結果を教えてください。
よろしくお願いいたします。
11208/11135 BQO00549 konno Re^2: SQRの単精度と倍精度の表示検証ソース
( 1) 24/04/09 22:44 11207:としきさんへのコメント コメント数:1
> > 110 defdbl a-z '倍精度指定
> > ここを単精度指定にしたらどうなるか、
> この結果を教えてください。
> よろしくお願いいたします。
もちろん 169 が素数と表示されます。
元々単精度でそういう表示になるところから始まった話題ですから。
色々試していった結果結構ソースが変わってしまいましたが。(^^;
ところで、USING を使ってみたら違いが表示されました。
1000 'pn88.bas
1010 ' defdbl a-z '倍精度指定
1020 'defdbl n '倍精度指定
1030 OPEN "SQR.dat" FOR OUTPUT AS #1
1040 INPUT N
1050 IF (N/2 <> INT(N/2))=0 THEN IF N=2 THEN PRINT "素数" ELSE PRINT "合成数"
1060 J!=SQR(N) 'ELSE
1070 FOR I!=3 TO SQR(N) STEP 2
1080 IF N/I! = INT(N/I!) THEN 1100 '*EXIT1
1090 NEXT I!
1100 ' *EXIT1
1110 PRINT USING " .##################";I!-SQR(N) '.14
1120 PRINT#1, USING " .##################";I!-SQR(N) '.14
1130 IF I!<=SQR(N) THEN PRINT "合成数";I!;J!
1140 IF I!<=SQR(N) THEN PRINT#1, "合成数";I!;J!
1150 IF I!>SQR(N) THEN PRINT "素数";I!;J!
1160 IF I!>SQR(N) THEN PRINT#1, "素数";I!;J!
1170 INPUT A
1180 END
この結果は
.000001907350000000
素数 13 13
このように単精度の時
I!-SQR(N)
で誤差が表示されました。
倍精度ではゼロになりました。
98実機ではどうなるでしょうね。
11209/11135 CXB00940 としき Re^3: SQRの単精度と倍精度の表示検証ソース
( 1) 24/04/10 17:44 11208:konnoさんへのコメント コメント数:2
参照先:http://toshiki.la.coocan.jp/
> もちろん 169 が素数と表示されます。
ちょっと残念というか、当然と思えることがおきなければそれも手がかりになる
かな、と思っていたわけですよ。
それで、しつこくお尋ねしていた次第。
> ところで、USING を使ってみたら違いが表示されました。
やっぱりそうでしたか。
> 98実機ではどうなるでしょうね。
とりあえず、試したいことリスト。
すでに試し済みのものもあるかも。
#11208のpn88.bas、倍精度と単精度
#11175のPN88.BASでNを単精度にしただけのもの
そして、#11175のN88P.BASの改造版、以下。
N88P0410.BAS
100 INPUT N
110 IF N MOD 2=0 THEN ELSE *ELSE1
120 IF N=2 THEN PRINT "素数" ELSE PRINT "合成数"
130 GOTO *ENDIF1
140 *ELSE1
150 I=3
160 WHILE (I<=SQR(N)) AND (N MOD I<>0)
165 PRINT I,SQR(N)
170 I=I+2
180 WEND
190 IF I<=SQR(N) THEN PRINT "合成数" ELSE PRINT "素数"
200 *ENDIF1
210 END
これも、Nを単精度と倍精度にしたものの2つ。
今のところ、思いつくのはこのくらい。
あ、そうだ、konnoさんのコードだとプログラム終了のところに必ずinputがあるの
ですが、これ、コンパイラだとあったほうがいいのですか?
それとも他の事情?
いえ、うちのインタプリタだと、必ず最後に入力プロンプトの「?」がはいるのが
うざいというかうっとうしくて。
11210/11135 BQO00549 konno Re^4: SQRの単精度と倍精度の表示検証ソース
( 1) 24/04/10 21:56 11209:としきさんへのコメント コメント数:1
> そして、#11175のN88P.BASの改造版、以下。
> N88P0410.BAS
これ、実行してみました。NP2 では、169 は素数と表示されました。
> あ、そうだ、konnoさんのコードだとプログラム終了のところに必ずinputがあるの
> ですが、これ、コンパイラだとあったほうがいいのですか?
コンパイラでは終了すると画面が消えてしまい、表示の確認が出来ないのですよ。
インタプリタでは消えないんですが、ソース共通化のために入れています。
11211/11135 CXB00940 としき Re^5: SQRの単精度と倍精度の表示検証ソース
( 1) 24/04/10 23:25 11210:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> これ、実行してみました。NP2 では、169 は素数と表示されました。
あ〜、いやいや、そこではなくて。
いや、そこなのか?
#どっちだよ
ループの最後というか、誤判定されるわけですよね。
その、最後とそのもうひとつ前というか、単精度型と倍精度型でどうなっているのか
見たいな、ということです。
プログラム最後のinputについては了解しました。
やはり、環境によって、こういう差異が発生するものなのですね。
想像はできても、実際にお話を聞けたことがありがたいというか。
11212/11212 DGF01024 めざら DOSVAXJ3 JP240410 更新
( 1) 24/04/11 05:56 コメント数:2
参照先:http://mezala.la.coocan.jp/
DOSVAXJ3 が 240410版に更新されました。
以下更新内容です。
build JP240410 (2024/4/10)
・J-3100モードが動作していなかったのを修正しました。
・Linux, macOS でビルドできなくなっていたのを修正しました。
……ということなんで,われわれにはあまり関係ないかな(^^;
11213/11135 BQO00549 konno Re^6: SQRの単精度と倍精度の表示検証ソース
( 1) 24/04/11 20:13 11211:としきさんへのコメント
> ループの最後というか、誤判定されるわけですよね。
> その、最後とそのもうひとつ前というか、単精度型と倍精度型でどうなっているのか
> 見たいな、ということです。
実行結果(数値はVTDOSの結果を張り付けたが表示は同じ)
? 169
3 13
5 13
7 13
9 13
11 13
素数
NP2の結果は単精度型は「素数」、倍精度型は「合成数」と表示だけ違います。
110番の THEN ELSE はこれでいいんでしょうか。
まあ 2 の表示を省いたのだと思うけど。
> 110 IF N MOD 2=0 THEN ELSE *ELSE1
11214/11212 BQO00549 konno Re: DOSVAXJ3 JP240410 更新
( 1) 24/04/11 21:05 11212:めざらさんへのコメント
> DOSVAXJ3 が 240410版に更新されました。
更新されていたのですね、お知らせいただきありがとうございます。
> build JP240410 (2024/4/10)
> ・J-3100モードが動作していなかったのを修正しました。
> ・Linux, macOS でビルドできなくなっていたのを修正しました。
うげ、今ちょうど J31モードを使っている所なんですよね。
それで、3月15日に更新があったのは知っていたのですが、32ビット版は落としてなかった。OTL
ちなみに、3月15日の更新内容は
---------------------------------------------------------------
build JP240315 (2024/3/15)
J-3100 ビデオモード 64h (640×400 2色 文字 80×20)に対応しました。
MS-DOS/V 6.2 をイメージファイルからブートした場合に jkeyb.sys の /106 設定が有効にならず
英語キーボード配列になっていたのを修正しました。
[dosbox] kanjikey を追加しました。漢字キーを ALT+半角全角、半角全角、右 ALTに割り当てる事ができます。
int 21h ah=5ch に対応しました。Windows 3.1 用の MS-Office が起動可能になります。
内蔵 BIOS 割り込みのエントリアドレスを F000:C000 以降に変更しました。
---------------------------------------------------------------
> J-3100 ビデオモード 64h (640×400 2色 文字 80×20)に対応しました。
これは、20行表示モードが使えるということかと思って VZJ31の ^KL でやってみました。
が、白画面が真っ黒になって、縦400ドットが、480ドットに伸びました。
カーソルは動きますが、文字は全く表示されません。
もう一度 ^KL で元に戻りましたが、これは使えないようです。
CHEV 64 でも同じ結果です。
黒画面はどうも VGA ぽいですね。
うーん、私の設定か解釈が間違っているのでしょうか。軟式さんに聞いてみようかしら。
それはともかく、これがきっかけで J31 用のBASICコンパイラを試してみたら
なんと! 生成した実行ファイルが VTDOS で動くではないですか。\(^^)/ ヤッタ-
MS-DOS Player と同じく テキスト表示だけなら問題なく動作します。
この実行ファイル一つで、VTDOS、MS-DOS Player、DOSVAXJ3のVGA,J31モード全部動きます!!
> ……ということなんで,われわれにはあまり関係ないかな(^^;
関係ないどころか、埋もれていたお宝が完全復活しました!!
それだけではなく、今までのエミュの壁を突破できる切り札として蘇ったのです!!
これはめざらさんのおかげですね。ありがとうございます。
としきさんとの素数プログラムのやりとりも助けになっています。
軟式さんの J31モードのまめな更新のおかげで、古代の遺産が復活出来ました!
みなさまに感謝です。m(__)m
# 伝説巨神 出でよん 発動編(壮絶な戦いになりそうな悪寒)
11215/11135 CXB00940 としき Re^4: SQRの単精度と倍精度の表示検証ソース
( 1) 24/04/13 01:13 11209:としきさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> とりあえず、試したいことリスト。
試してきました。
> #11208のpn88.bas、倍精度と単精度
pn88単精度
.000000000000000000
合成数 13 13
pn88b倍精度
.000000000000000000
合成数 13 13
> #11175のPN88.BASでNを単精度にしただけのもの
合成数と出ました。
> そして、#11175のN88P.BASの改造版、以下。
単精度でも倍精度でも同じ、
3 13
5 13
7 13
9 13
11 13
合成数
と出ました。単精度でも倍精度でも同じです。
うむ、興味深いぞ。
> 190 IF I<=SQR(N) THEN PRINT "合成数" ELSE PRINT "素数"
Iも13、SQR(N)も13なのだから、合成数と表示されるのが正当。
そして実際、うちでは想定どおり動いています。
ところが、konnoさんのところでは、単精度型ではこの比較式が成り立たず、ELSEに
落ちてしまっている。そして、倍精度型ではきちんと動いている。
なんか、エミュの挙動がおかしいとしか思えない。
前にも書きましたが、N88BASICの仕様では、関数の結果は引数と同じ型になることに
なっています。つまり、Nが単精度ならSQR(N)の結果も単精度のはず。だから、小数点
以下の細かいところの値が出てくることがおかしい。
もしかしたら、次のような簡単なプログラムでも、実機とエミュで差が出たりして。
10 A#=1.23456789#
20 B!=A#
30 PRINT A#,B!
これ、実はN88のマニュアルに載っているサンプルです。
そして、仕様上のこの実行結果は
RUN
1.23456789 1.23457
となるべきなのだそうです。
もしエミュでこうならないとしたら、それはどこかがおかしい。
エミュの作者に調査を依頼してもいいかも。
追伸
#11213
> 110番の THEN ELSE はこれでいいんでしょうか。
> 110 IF N MOD 2=0 THEN ELSE *ELSE1
N88BASICでは、言語仕様として、THEN節に空文を許します。
つまり、THEN のときは、何もせずに、次の行に進むことになります。
これ、#11169で触れているとおりです。
11216/11135 BQO00549 konno Re^5: SQRの単精度と倍精度の表示検証ソース
( 1) 24/04/13 22:03 11215:としきさんへのコメント コメント数:1
> これ、実はN88のマニュアルに載っているサンプルです。
> そして、仕様上のこの実行結果は
>
> 1.23456789 1.23457
>
> となるべきなのだそうです。
NP2でやってみた結果です。
1.23456789 1.23457
表示は全く同じですね。やっぱり表示と内部の数値がズレているのかなぁ。
他のエミュの結果は全て以下の数値でした。
1.23456789 1.234568
98エミュの表示が上の数値で内部的には下の数値だとしたら、計算が合わないのも合点ですね。
でも何故こうなるのかがわからないので、とっても気になります。
> もしエミュでこうならないとしたら、それはどこかがおかしい。
> エミュの作者に調査を依頼してもいいかも。
表示は全く同じなので、おかしくないということですね。(違う!)
> N88BASICでは、言語仕様として、THEN節に空文を許します。
> つまり、THEN のときは、何もせずに、次の行に進むことになります。
> これ、#11169で触れているとおりです。
なるほど、つまり想定どうりということですね。
11217/11212 BQO00549 konno DOSVAXJ3 JP240410 20行表示がおかしい?
( 1) 24/04/13 23:28 11212:めざらさんへのコメント
> それで、3月15日に更新があったのは知っていたのですが、32ビット版は落としてなかった。OTL
実は寝室のPCでダウンロードしていました。(^^;
ダウンロードだけして寝落ちしてそのまま忘れていたようです。(^^;;
ということで
> build JP240410 (2024/4/10)
> ・J-3100モードが動作していなかったのを修正しました。
これがどういうことかと疑問だったので確認してみました。
・・・J31モードにすると、起動中に固まってしまいました、(>_<)
そういうことでしたか・・・
> > J-3100 ビデオモード 64h (640×400 2色 文字 80×20)に対応しました。
> これは、20行表示モードが使えるということかと思って VZJ31の ^KL でやってみました。
> が、白画面が真っ黒になって、縦400ドットが、480ドットに伸びました。
> カーソルは動きますが、文字は全く表示されません。
> もう一度 ^KL で元に戻りましたが、これは使えないようです。
> CHEV 64 でも同じ結果です。
これ、CHEJ 64 だとモードが変わりました。
CHEV コマンドに反映されていないみたいです。デジャブのような。(^^;
D:\NC>chev 64
V - Video mode information R1.0 (C)ChaN,1993
Current Video Mode = 74h
Screen Size = 80x25
Character Height = 16
VRAM Mode = A/N
VRAM Address = B800:0000 (Real VRAM)
それで、CHEJ コマンドを試したら
D:\NC>chej 64
CHEJ.EXE <MultiMode CHEV> ver 6.10 by Natrium.
J-3100(DCGA)、日本語環境に切り替えました。
現在のビデオモードは 64h です。
V - Video mode information R1.0 (C)ChaN,1993
Current Video Mode = 64h
Screen Size = 80x20
Character Height = 20
VRAM Mode = A/N
VRAM Address = B800:0000 (Real VRAM)
おお、画面モードが 20行に変わりました。
それで、VZJ31 の編集画面を見ると
行数は 25行のまま、アンダーラインカーソルも追随します。
点滅カーソルは 20行になったようで、下に行くほどズレます。
うーむ、これは VZが対応できていないのかしら?
やっぱり軟式さんに聞いてみようかな。
11218/11135 CXB00940 としき Re^6: SQRの単精度と倍精度の表示検証ソース
( 1) 24/04/14 12:14 11216:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> NP2でやってみた結果です。
> 他のエミュの結果は全て以下の数値でした。
> 表示は全く同じなので、おかしくないということですね。(違う!)
NP2と他のエミュで差が出る、というところは一つの突破口かも。
少なくともNP2以外のエミュは仕様どおりではないということで、バグ報告は可能
だと思います。おそらく、四捨五入するときの桁数を誤っていると想定されます。
仕様上は、有効桁7桁、出力のときは7桁目が四捨五入されて6桁で表示、という
ことになっているのですから。
なので、以後は、NP2と実機の差異をどうするか。
どうも、本来は7桁以上は格納してはいけないものを7桁以上格納している、その上
7桁以上で比較してはいけないものを7桁以上で比較している、というように見える
わけですよ。
print usingを使う以外に、何かいい方法はあるかなぁ。
実際、この程度の小数の誤差がどの程度影響するかはわかりませんがね。
でも、もしかしたら、昔からゲームなんかでも使われている可能性はあるわけで。
konnoさんは、例えばバルーンパンチなんてゲームを覚えておられませんかね。
シーソーに乗った人が交互にジャンプして上のほうで動いている風船を割っていく、
というゲームです。
このゲームで飛んでいる人間は、まるで重力で引かれるような感じで頂点に向かって
減速して、また落下するときは加速するわけです。このゲームに限らず、まるで重力
に引かれたような動きをする、だとか、慣性が働いているようになかなか加速しない
上に速度が乗ったらすぐには止まれない、といった動きをするようなゲームでは、
もしもそれなりに理論的なアルゴリズムを使うならば、物体の位置決定に二次関数を
使う必要があるわけです。実際に使っているアルゴリズムがどこまで理論的に正しい
ものになっているかはわかりませんけどね。
そして、二次関数を解くためにはSQR関数が必要。
あるいは、ゲームによっては三角関数を使っているものもあるかもしれない。
そして、画面のXとYの座標は当然整数。
ときどき、当たり判定がバグっているゲームというのが話題になることがありますが、
あれっていうのはもしかしたら、小数と整数の比較の際の誤差の問題かも。そして、
実機だと正常に動いていたのにエミュだとおかしい、というゲームなどがあった場合、
それこそこのような小数の誤差の可能性は高いかも。
もちろん、倍精度を使えば誤差は少なくなりますが、リアルタイムの計算の場合、
倍精度だとやっぱり重くなるので、たいていは単精度を使うでしょうし。
11219/11135 BQO00549 konno Re^7: SQRの単精度と倍精度の表示検証ソース
( 1) 24/04/15 01:15 11218:としきさんへのコメント コメント数:1
> NP2と他のエミュで差が出る、というところは一つの突破口かも。
> 少なくともNP2以外のエミュは仕様どおりではないということで、バグ報告は可能
> だと思います。おそらく、四捨五入するときの桁数を誤っていると想定されます。
> 仕様上は、有効桁7桁、出力のときは7桁目が四捨五入されて6桁で表示、という
> ことになっているのですから。
もしかしたら誤解させてしまったかもしれません。
他のエミュとは、98エミュ以外の、J31とかDOS/V系のエミュのことです。
今回 NP2以外の98エミュは確認していません。同じ結果になると思ったので。
ということで、ANEX86 や T98-NEXT のN88コンパイラ、インタプリタでも確認しました。
結果は NP2と 表示は全く同じでした。
> どうも、本来は7桁以上は格納してはいけないものを7桁以上格納している、その上
> 7桁以上で比較してはいけないものを7桁以上で比較している、というように見える
> わけですよ。
これが実際どうなのかはわかりませんが、BASICのルーツは MSのGW-BASICだと思います。
T-BASICなどは漢字処理を覗けば恐らくほとんどそのままの互換性だと思っているのですが
NECのN88BASICは、あちこち変えているようですが、単精度の精度もわざと落としているように見えます。
その辺がエミュでの誤動作の原因になっているのではないかと愚考します。
> konnoさんは、例えばバルーンパンチなんてゲームを覚えておられませんかね。
> シーソーに乗った人が交互にジャンプして上のほうで動いている風船を割っていく、
> というゲームです。
私はこの手のゲームはあまりやっていないので覚えていません。
> ときどき、当たり判定がバグっているゲームというのが話題になることがありますが、
> あれっていうのはもしかしたら、小数と整数の比較の際の誤差の問題かも。そして、
> 実機だと正常に動いていたのにエミュだとおかしい、というゲームなどがあった場合、
> それこそこのような小数の誤差の可能性は高いかも。
今回のことを踏まえるとそう考えられますね。
> もちろん、倍精度を使えば誤差は少なくなりますが、リアルタイムの計算の場合、
> 倍精度だとやっぱり重くなるので、たいていは単精度を使うでしょうし。
N88BASICは8ビット時代の互換性重視ではないかと思いますが、8ビットの貧弱なCPUで
ゲームの速度を上げるためにわざと単精度の桁を落としたのではないかと思います。
そして、16ビット版になっても互換性のためにそこを変えることが出来なかったのかも。
11220/11135 CXB00940 としき Re^8: SQRの単精度と倍精度の表示検証ソース
( 1) 24/04/15 13:56 11219:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> もしかしたら誤解させてしまったかもしれません。
> 他のエミュとは、98エミュ以外の、J31とかDOS/V系のエミュのことです。
はい、誤解しました。
続報をいただいたことで、誤解は氷解しました。
> NECのN88BASICは、あちこち変えているようですが、
うん、まぁ、その前のN-BASICからの互換性というのがありますからね。
そちらのほうでいろいろと変えていたところはあるかもしれません。
> 単精度の精度もわざと落としているように見えます。
こちらについてはどうなんだろう。
そうではないというわけではなく、根拠不足というか、これまでのところでは、私
にはそう思えるだけの挙動はないような気がしています。
ということで、ちょっと調べてみました。
まず、単精度は4バイトであらわす実数、倍精度は8バイトであらわす実数。
これは、調べた範囲では、どこも同じみたい。80年代の8ビットパソコンのBASIC
でも、21世紀の64ビットパソコンのCコンパイラでもおおむね一緒。
ところが、倍精度のほうが、最近の国際規格とN88BASICで異なるみたい。
#11164に書いたように、N88BASICでは倍精度の扱える上限は 1.7*10^38 ですが、
最近の規格では 1.8*10^308 まで扱えるらしい。
一方で単精度の方は最近の規格でも 1.7*10^38 で同じ。
内部表現についても、仮数部23ビット、指数部8ビット、符号1ビットという部分
に変化はない。
でも、だからN88の単精度では精度を落としていないかというといささか怪しいと
いうか断言はできない。
なにかというと、十進数との変換部分。
#11135にも書きましたが、仕様としては有効桁7桁、出力のときは7桁目が四捨五入
されて6桁で表示、となっているわけですよ。でも、他の処理系では例えば、有効桁
7桁で表示も7桁、となっているかもしれない。もしそうであれば少なくとも見かけ
の精度は落ちているわけです。あるいは、他の処理系では、7桁目で四捨五入では
なく切り捨て表示となっているかもしれないし。
ただ、あまりにも他のマシンと差があるようであれば、当時、大騒ぎになっている
のではないかなぁ。あの時代、ネットはなくてもパソコン雑誌はあったし、8ビット
のころはともかく16ビットの時代はパソコン通信もあったし。
ということで、とりあえず現時点では根拠不足としてkonnoさんのご意見に賛同は
しないでおきます。
#つまり、何かあればすぐに意見は変わる
ただ、エミュという意味では、よく言われる「バグまで再現した」というものが評価
が高いわけで、現状、実機と差異が出るエミュは、完成度としてはもう一歩、という
のが現実的な評価だと思われます。
11221/11135 BQO00549 konno Re^9: SQRの単精度と倍精度の表示検証ソース
( 1) 24/04/16 00:04 11220:としきさんへのコメント コメント数:1
> 続報をいただいたことで、誤解は氷解しました。
紛らわしい表現で誤解させてしまい申し訳ないです。
とりあえずホッとしました。
> > 単精度の精度もわざと落としているように見えます。
考えてみたら、これは表示だけなのかもしれませんね。
N88BASICは、インタプリタもコンパイラも中間コードの LIB を使用しているように見えます。
ということは、そのバイナリコードは BIOS.ROM の中なのではないですか。
私の手持ちのNP2の BIOS.ROMは、実機のものではなく、互換BIOS かもしれません。
その互換BIOSを作る時、N88BASICの仕様に忠実に作るために、#11215 の
> 10 A#=1.23456789#
> 20 B!=A#
> 30 PRINT A#,B!
>
> これ、実はN88のマニュアルに載っているサンプルです。
> そして、仕様上のこの実行結果は
>
> RUN
> 1.23456789 1.23457
>
> となるべきなのだそうです。
この結果を忠実に再現するために、わざと内部数値まで桁落ちさせたのではないかと疑い始めました。
つまり、問題なのは、互換BIOS.ROM なのかもしれないと思うようになりました。
これは、実機を持たない人たちにとって無くてはならない非常にありがたい福音ですが
互換BIOS を作ったのは、著作権の問題回避の為なので、バイナリレベルで違うものでなければならないわけです。
もしかしたら、この部分がそのための直せない生贄だったりして。あくまで妄想ですが。
> ただ、エミュという意味では、よく言われる「バグまで再現した」というものが評価
> が高いわけで、現状、実機と差異が出るエミュは、完成度としてはもう一歩、という
> のが現実的な評価だと思われます。
NP2は、細部の再現性にこだわったエミュという評価があるようなのですが
先のサンプルプログラムの結果は忠実に再現していますね。(^^;
11222/11135 CXB00940 としき Re^10: SQRの単精度と倍精度の表示検証ソース
( 1) 24/04/16 12:22 11221:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
> ということは、そのバイナリコードは BIOS.ROM の中なのではないですか。
確かに .LIB のファイルのサイズが小さ目というところから、実際に LIB がやって
いることは ROM の中身の呼び出しのみ、という可能性は高そうです。
> この結果を忠実に再現するために、
ある意味、この結果「だけ」を忠実に再現している、という感じ。
もし「実機を忠実に再現」するのであれば、169は合成数と表示される必要がある。
この点がなされない限り、実機に対するエミュとしての完成度は今一歩、という
ところで終わってしまいそうです。
もっとも世の中には、既知のバグどころか未知のバグまで再現したエミュレータと
いうものもある模様。実機で新たなバグが発見されてから、エミュレータでも同じ
バグが発現した、なんて話もあるようで、とても不思議。こういうのが、いわゆる
「完璧なエミュレータ」というやつでしょう。なぜ作れるんだろう。
> 互換BIOS を作ったのは、著作権の問題回避の為なので、
これはそのとおりだと思いますが、その一方で、実数のバイナリ表現というものは
ある意味で規格化されているわけです。つまり、実数演算とかバイナリと十進数の
変換とかの部分は世の中にいくらでもサンプルコードとかライブラリとかのフリーで
使えるものが存在しているわけで、そしてそういうものを使えば少なくとも著作権の
問題は回避できるはず。さらに、その手のコードって世界中の人が見ているわけです
から、精度を落とす方向にいじることは少ないのではないかなぁ。というか、わざと
精度を落とす、なんてことに時間をかけるくらいならとっととリリースしてくれよ、
という気もする。
もちろん、そういうものを使わずに1からコードを書いていたら、十分な精度を確保
できていなくても不思議はないけど。
あ、でも、ありうるかな。
倍精度のほうが現在のありふれたものとは内部表現が異なっているようだから、そちら
のほうに合わせて、ということはあるかも。
実は私、実数演算についてはちょっとだけやかましい。
#2066とか#10367にも書いたけど、大昔、8ビットマシンの時代、実数演算のマシン語
ルーチンを書いてハンドアセンブルしていたもので。
といっても四則演算だけですけどね。
11223/11135 BQO00549 konno Re^11: SQRの単精度と倍精度の表示検証ソース
( 1) 24/04/16 23:58 11222:としきさんへのコメント コメント数:1
> もっとも世の中には、既知のバグどころか未知のバグまで再現したエミュレータと
> いうものもある模様。実機で新たなバグが発見されてから、エミュレータでも同じ
> バグが発現した、なんて話もあるようで、とても不思議。こういうのが、いわゆる
> 「完璧なエミュレータ」というやつでしょう。なぜ作れるんだろう。
それはきっと、リバーs^ ・・・ いや、なんでもないです。(^^;
> 実は私、実数演算についてはちょっとだけやかましい。
> #2066とか#10367にも書いたけど、大昔、8ビットマシンの時代、実数演算のマシン語
> ルーチンを書いてハンドアセンブルしていたもので。
> といっても四則演算だけですけどね。
鶴亀算みたいなものでしたっけ? 結構面倒くさいんですよね。
丁度 DANNYさんの浮動小数演算ライブラリを目にしていたので見てみました。
ASMは1531行ありましたね。
バイナリは恐らく2千バイトくらいになるのかなぁ。
J3100用BASICコンパイラの続報も書かなくてはいけないのでこの辺で。
11224/11135 CXB00940 としき Re^12: SQRの単精度と倍精度の表示検証ソース
( 1) 24/04/17 02:14 11223:konnoさんへのコメント コメント数:1
参照先:http://toshiki.la.coocan.jp/
konnoさん、なんか他のものを連想している。
> 鶴亀算みたいなものでしたっけ? 結構面倒くさいんですよね。
鶴亀算は整数演算です。
何だろう、何と勘違いしたんだろう。おいらにはわからない。
11225/11135 BQO00549 konno Re^13: SQRの単精度と倍精度の表示検証ソース
( 1) 24/04/17 23:21 11224:としきさんへのコメント
> 鶴亀算は整数演算です。
> 何だろう、何と勘違いしたんだろう。おいらにはわからない。
あう、多分整数演算の事だと思います。(>_<)
私は算数も数学も苦手というか、数字の計算や記憶が全くダメなんですね。
だからパソコンにやらせようと思うのです。(^^;