Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

剰余について

11 views
Skip to first unread message

Hiroyuki Satoh

unread,
Mar 13, 1998, 3:00:00 AM3/13/98
to

(FAQでありましたら御勘弁ください。)

割り算(除算)で、答えを「商」と「余り」という形式で表す場合、
「余り」の定義とは何でしょうか?
文献や数学に長けた人々の見解を集約したところ、

-------------------------------------------------------------------
代数学の除法定理によれば、

整数 A, B があり、B > 0 の場合、これに対して
A = ( B * q ) + r
0 <= r < B
であるような整数 q, r がただ一組存在する。
q を A を B で割った「商」、r を「余り」という。

とあります。
ここから「余り(r)は0及び自然数である」という前提が推論されます。

-------------------------------------------------------------------
数学上のモジュロ関数の考え方では、

剰余を求める関数を、mod( A, B ) 但し、A が被除数、B が
除数とするとき、mod( A, B )は、B と同符号をとり、その絶対
値は B の絶対値より小さい。
  つまり、商を Q とすると、A = B * Q + mod( A, B ) を満足し
なければならない。
これにより、例えば -5 / 2 の 商は -3,余りは 1 となる。

-------------------------------------------------------------------
また、
「余り」という言語表現を自然に考えれば、「余り」にマイ
ナスはない。つまり常にプラスである。

という感覚的なところに理由を置く説もあります。

-------------------------------------------------------------------

これらに共通なのは、マイナスの剰余は存在しないという点です。

さて、ここからがコンピュータ言語の算術演算子や算術関数について
の話です。
例えばC言語では、

signed int nA, nB, nQuot, nRem;
nQuot = nA / nB;
nRem = nA % nB; とする場合、

nA = -5, nB = +2 では、 nQuotは -2, nRemは -1 となり、
nA = +5, nB = -2 では、 nQuotは -2, nRemは +1 となります。

他にもVisualBasic, Pascal, JAVA でも結果は同様です。

ANSIによる定義では、「剰余は商と同符号をとる」とありますし、
Microsoft固有仕様としては 「モジュロ演算子 % の剰余式の結果は、
必ず第1オペランドと同じ符号となる」とあります。

どちらにしてもこれらは、数学上の考え方とは異なるようです。

コンピュータ言語で、「これが仕様」と決められ、広く認知されて
いる以上、それを否定するつもりは全くありません。

私が知りたいのは「算術」演算子/関数によって導かれる結果を、
「なぜ数学上の概念と違う仕様に決めたのか?」という事です。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
「余り」について上記以外の定義や説があるのかも知れません。
これらについて、明快な解答をお持ちの方がいたら御教授願います。


# 手元にあるバージョンのjparl では、
# -5 / +2 は -2, -5 % +2 は +1
# +5 / -2 は -2, +5 % -2 は +5 になっちゃいます。
# これは話になりませんね。制限仕様?バグ?

--
佐藤 弘幸 (Hiroyuki Satoh)
E-mail address : h-s...@tkb.att.ne.jp


MAEDA Atusi

unread,
Mar 13, 1998, 3:00:00 AM3/13/98
to

h-s...@rd.njk.co.jp (Hiroyuki Satoh) writes:

> 整数 A, B があり、B > 0 の場合、これに対して
> A = ( B * q ) + r
> 0 <= r < B
> であるような整数 q, r がただ一組存在する。
> q を A を B で割った「商」、r を「余り」という。

上の定義はBが正の時しか使えませんよね。Bが負の場合も考慮した場合、
A/Bを整数値に丸める方法として以下の4通りが一般的です。

(1) 0に向かって丸める(truncate)。
すなわち、『商』とは、A/Bより絶対値が大きくない整数の中でもっとも
A/Bに近いものと定義する。
(2) 正の無限大に向かって丸める(ceiling)。
商とはA/Bより小さくない整数の中でもっともA/Bに近いものと定義する。
(3) 負の無限大に向かって丸める(floor)。
商とはA/Bより大きくない整数の中でもっともA/Bに近いものと定義する。
(4) もっとも近い整数に丸める(round)。
商とはすべての整数の中でもっともA/Bに近いものと定義する。
(ちょうど2つの整数の中間にある時は、偶数を選ぶ)。

この4つに応じてそれぞれ『余り』が定義できます。

> どちらにしてもこれらは、数学上の考え方とは異なるようです。

数学的には上の4つのどれが「正しい」ともいえないと思います。佐藤さんが
示した除法定理も、「除数は正」という範囲でしか成り立ちませんよね。この
範囲以外だと上を満たすq, rは存在しませんから。

ceilingやfloorは数学で良く使いますよね。統計学ではroundを使わないと困
る事も多いでしょう。また、「整数部と小数部」なんていう言い方をした時は、
truncateが整数部を求める演算に相当するでしょう。

> コンピュータ言語で、「これが仕様」と決められ、広く認知されて
> いる以上、それを否定するつもりは全くありません。
>
> 私が知りたいのは「算術」演算子/関数によって導かれる結果を、
> 「なぜ数学上の概念と違う仕様に決めたのか?」という事です。
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

プログラミング言語では、演算子としてこれらのうち1つしか用意していない
言語が多いですね。「除数または被除数のいずれかが負の時、剰余の符号は不
定(あるいは処理系依存)」としている言語もあります。

実際にtruncateを採用している処理系が多いのは、おそらくそれがコンピュー
タで処理する上でもっとも楽だからでしょう。floorやceilingは商の正負によっ
てアルゴリズムを変えなければいけませんし、roundもtruncateより手間がか
かります。

ちなみに、Common Lispではtruncate, floor, ceiling, roundという4つの丸
め方が用意されています。剰余にはfloorの剰余を返すmodと、truncateの剰余
を返すremの2とおりがあります。SchemeというLispの方言にもmoduloと
remainderという2つの剰余関数があります。Fortranの組み込み関数やCのライ
ブラリ関数では、浮動小数点数を整数値に丸めるときにtruncateする関数
(aint)とroundする関数(anint)の2つが用意されています。

> # 手元にあるバージョンのjparl では、
> # -5 / +2 は -2, -5 % +2 は +1
> # +5 / -2 は -2, +5 % -2 は +5 になっちゃいます。
> # これは話になりませんね。制限仕様?バグ?

Perlにはちゃんとした仕様がない(仕様 = 実装)ので推測するしかありません
が、除数・被除数のどちらかが負だと剰余はまったく不定なのかも。つまり、
除法定理が成り立つ範囲でしか使ってはいけないとか???

前田敦司

Hiroyuki Satoh

unread,
Mar 16, 1998, 3:00:00 AM3/16/98
to

In article <pypiupi...@tp560e.sowa.is.uec.ac.jp>, ma...@is.uec.ac.jp says...

> 数学的には上の4つのどれが「正しい」ともいえないと思います。佐藤さんが
> 示した除法定理も、「除数は正」という範囲でしか成り立ちませんよね。この
> 範囲以外だと上を満たすq, rは存在しませんから。

> ceilingやfloorは数学で良く使いますよね。統計学ではroundを使わないと困
> る事も多いでしょう。また、「整数部と小数部」なんていう言い方をした時は、
> truncateが整数部を求める演算に相当するでしょう。

なるほど、やはり剰余については方式的な定義が複数存在するという事な
訳ですね。
言語処理系の仕様は、それらの中で最も演算がシンプルになるtruncateを
採用した。
という事ですね。


> Perlにはちゃんとした仕様がない(仕様 = 実装)ので推測するしかありません
> が、除数・被除数のどちらかが負だと剰余はまったく不定なのかも。つまり、
> 除法定理が成り立つ範囲でしか使ってはいけないとか???

そのようですね。
こういうのがあるから言語間移植って一筋縄にいかないんです。

御教授ありがとうございました。

--
佐藤 弘幸 (Hiroyuki Satoh)

E-mail address for private : h-s...@tkb.att.ne.jp


Kaoru MAEDA

unread,
Mar 16, 1998, 3:00:00 AM3/16/98
to

前田@リコーです。

> h-s...@rd.njk.co.jp (Hiroyuki Satoh) writes:
>> # 手元にあるバージョンのjparl では、
>> # -5 / +2 は -2, -5 % +2 は +1
>> # +5 / -2 は -2, +5 % -2 は +5 になっちゃいます。
>> # これは話になりませんね。制限仕様?バグ?

>>>>> In article <pypiupi...@tp560e.sowa.is.uec.ac.jp>,
>>>>> MAEDA Atusi <ma...@is.uec.ac.jp> writes:

> Perlにはちゃんとした仕様がない(仕様 = 実装)ので推測するしかありません
> が、除数・被除数のどちらかが負だと剰余はまったく不定なのかも。つまり、
> 除法定理が成り立つ範囲でしか使ってはいけないとか???

Perl5.004で規定?された(regulateされた)ようです。

man perlopより:
| Binary "%" computes the modulus of two numbers. Given
| integer operands $a and $b: If $b is positive, then $a % $b
| is $a minus the largest multiple of $b that is not greater
| than $a. If $b is negative, then $a % $b is $a minus the
| smallest multiple of $b that is not less than $a (i.e. the
| result will be less than or equal to zero).

arith.tより:
|try 1, 13 % 4 == 1;
|try 2, -13 % 4 == 3;
|try 3, 13 % -4 == -3;
|try 4, -13 % -4 == -1;

------------------------------- MadCat LRM15 □/ ̄\□ LRM15
前田 薫 ma...@src.ricoh.co.jp 75t 175km/h LG+ o"| |"o AFC100
(株)リコー ソフトウェア研究所 HeatSink 14 Sm+ .=X ̄X=. Sm+
------------------------------- Armor 2025 _|_ _|_

MAEDA Atusi

unread,
Mar 16, 1998, 3:00:00 AM3/16/98
to

ma...@src.ricoh.co.jp (Kaoru MAEDA) writes:

> Perl5.004で規定?された(regulateされた)ようです。
>
> man perlopより:
> | Binary "%" computes the modulus of two numbers. Given
> | integer operands $a and $b: If $b is positive, then $a % $b
> | is $a minus the largest multiple of $b that is not greater
> | than $a. If $b is negative, then $a % $b is $a minus the
> | smallest multiple of $b that is not less than $a (i.e. the
> | result will be less than or equal to zero).

なるほど。floorの余りを採用したんですね。佐藤さんが最初におっしゃった
mathematically correctな剰余ですね。

たしかに、Perl 5.004ではそういう値を返しますね。Perl 5.003だと、除数
($b)が負の時はむちゃくちゃ^^;。マニュアル見ても

| Binary "%" computes the modulus of the two numbers.

と書いてあるだけだし。

前田敦司

0 new messages