ジメジメする梅雨のお悩み、一挙解決! >>

秀丸マクロ、プログラム初心者です。
秀丸マクロでunsigned _int64(20桁)の数値文字列の引き算をしたいのですが、うまくいきません。
秀丸で扱えるのがint(10桁)のため、文字列を単純に数値変換して計算ががきません。
20桁の文字列を2桁、9桁、9桁の3ブロックに分けて、unsigned _int64のロールオーバーや桁上がり(ブック上がり)を考慮しながらブロックごとに引き算をし、文字列に戻しているのですが、計算結果が期待通りになりません。
秀丸でのよい方法、または秀丸ではなくとも、上記と同じことをしているソースなどあれば教えていただけると幸いです。

ちなみに職場環境でインストール制限等がありできれば秀丸がよいのです。

このQ&Aに関連する最新のQ&A

A 回答 (1件)

・10桁と書いてありますが、表現できるのは符号付き32bitの範囲なので、99...9まで全て使えるわけではありません。


・比較的簡単な手段は、配列を使って1桁1要素にして、小学校の筆算の要領でやることだと思います。
・その他、なにがどううまくいかなかったのかが不明なので、回答できません
    • good
    • 1
この回答へのお礼

kmeeさん
返信ありがとうございます。
方法論としてよいやり方、極力スマートなやり方ががないかと思っていました。
でもようやく3ブロックに分けた計算で正しく計算ができました。

>配列を使って1桁1要素にして、小学校の筆算の要領・・・
なるほどですね。
ロールオーバーしていたら最大値からの引き算を加えればよいのですね。
スマートにできそうですね。
作りなおそうかな。。。。
ありがとうございました。

お礼日時:2012/01/05 21:54

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q16ビットCPUで32ビットの計算方法

16ビットのCPUを持つシーケンサ(PLC )で32ビットの四則演算(加算、減算、乗算、除算)をさせたいのですが、命令語にダブルワードを処理できるものがないので、演算がオーバーフローした情報から何かしら自分でプログラムを組まなければなりません。
16ビットのレジスタを使った32ビット演算の考え方を教えてください。

Aベストアンサー

普通は、ダブルワードなんて有りません。

そのCPUのアセンブリ言語での16bitの和、差の演算で、キャリー、ボローは出ませんか?
そうであれば、まず、32bitの数値を上位16bitと下位16bitに分けます。で、自分が、紙に書いて演算するように、演算するようにプログラムを組みます。

たとえば、あなたは、足し算、引き算をするときにどうしていますか?
下位の桁から1桁ずつ計算していませんか?

和であれば、下位同士を足します。そのときに繰り上がりがあったら上位同士を足す時に繰り上がりも足しますよね?
(でも、ふつうのCPUなら、キャリーフラグも足す足し算命令があるハズなんですけどねぇ。)
自分が紙に数値を書いて演算する様に、計算をプログラムして下さい。
ただ、その数字の扱いが10進数ヒトケタではなく、16bitでまとめて考えるだけです。
引き算も一緒ね。本当は、引き算は、反転して一を引いた数(補数)にして、足し算にしちゃうんだけど、それは理解できるようなら、やってください。

かけ算は、スピードを考えないので有れば、その回数だけ足し算を繰り返します。ホントは、bit演算と、シフトと足し算なんですけど、まぁ、単純に足し算で良いでしょう。

わり算は、引き算の回数を数えましょう。そのときに、これもシフトを上手く使えば速度を稼げます。

ということで、自分で紙に書いて、実際に演算をしてから、プログラムを作成してください。
あえて、これ以上は教えません。

#実は私はプログラマさんじゃない(^^;)んで、これ以上は無理です。

普通は、ダブルワードなんて有りません。

そのCPUのアセンブリ言語での16bitの和、差の演算で、キャリー、ボローは出ませんか?
そうであれば、まず、32bitの数値を上位16bitと下位16bitに分けます。で、自分が、紙に書いて演算するように、演算するようにプログラムを組みます。

たとえば、あなたは、足し算、引き算をするときにどうしていますか?
下位の桁から1桁ずつ計算していませんか?

和であれば、下位同士を足します。そのときに繰り上がりがあったら上位同士を足す時に繰り上がりも足します...続きを読む

Q除算を使わずに10で割りたい。

加算、減算、シフト、論理演算、ループ、等を使って
除算を使わずに10で割る方法は無いものでしょうか?
また、近似値を求めてから誤差を修正する方法でも構いません。

ただし、ループで10を引き続けてカウントする方法は除外させてください。

言語はCでお願いします。

Aベストアンサー

ANo.15 は「引き戻し法」ですね。いわゆる普通の「割り算の筆算」をそのまま2進数ベースで実装したものです。
(10進の割り算の場合は、各桁で「1倍~9倍のどこまで引けるか」を計算しますが、2進数なので、「引ける(その桁は1)か引けない(その桁は0)か」の2択の判定になります。

それをもうちょっと進めた(計算量を減らした)方法に「引き放し法」というのもあります。「引けるかどうか」チェックしてから「引く」のは二度手間なので、「引いてしまってから、結果によって次の処理を変える(負になったら、次のステップでは足すようにする)」というものです。

でも、この手の処理は「CPUの内部でハードウェアで実装されている」機能ですから、それをソフトウェアで実装するのは遅いだけでメリットはありません。
多倍長演算が例に挙げられてますけど、多倍長の2進数で実装する場合でも、
個々の演算は通常の加減乗除の組合せで実装するのが普通です。
例えば、32bitCPUで256bitの数値演算をしたいのであれば、
「4294967296進数で8桁の数値」を扱うようにすればいいんです。

簡単な例ですが、以下、64bitの数値を16bit×4桁と考えて10で割るコードです。除数の方も多倍長になるとやることは格段に複雑になりますが、演算の基本方針は同じです。


#include <stdio.h>
int main(int argc, char *argv[])
{
union {
unsigned long long ulonglong;
unsigned short ushort[4];
} x, y;
unsigned int div, mod;

x.ulonglong = 9876543210LL;
printf("%lld = %d * (1<<48) + %d * (1<<32) + %d * (1<<16) + %d\n", x.ulonglong, x.ushort[3], x.ushort[2], x.ushort[1], x.ushort[0]);
/* x86 CPUは Little Endian なので、ushort[3]が上位でushort[0]が下位 */

div = x.ushort[3] / 10;
mod = x.ushort[3] % 10;
y.ushort[3] = div;

div = (mod * 65536 + x.ushort[2]) / 10;
mod = (mod * 65536 + x.ushort[2]) % 10;
y.ushort[2] = div;

div = (mod * 65536 + x.ushort[1]) / 10;
mod = (mod * 65536 + x.ushort[1]) % 10;
y.ushort[1] = div;

div = (mod * 65536 + x.ushort[0]) / 10;
mod = (mod * 65536 + x.ushort[0]) % 10;
y.ushort[0] = div;

printf("%lld / 10 = %lld mod %d\n", x.ulonglong, y.ulonglong, mod);

}

ANo.15 は「引き戻し法」ですね。いわゆる普通の「割り算の筆算」をそのまま2進数ベースで実装したものです。
(10進の割り算の場合は、各桁で「1倍~9倍のどこまで引けるか」を計算しますが、2進数なので、「引ける(その桁は1)か引けない(その桁は0)か」の2択の判定になります。

それをもうちょっと進めた(計算量を減らした)方法に「引き放し法」というのもあります。「引けるかどうか」チェックしてから「引く」のは二度手間なので、「引いてしまってから、結果によって次の処理を変える(負になったら、次の...続きを読む


人気Q&Aランキング

おすすめ情報