グッドデザイン賞を受賞したウォーターサーバー >>

論理加算と算術加算ってなんですか?

wikiでしらべたんですが専用ページがないんですね
検索もしてみましたがどうやらしっていてあたりまえのような扱いになっていて説明がありません
caslの勉強をはじめたのですが論理加算と算術加算とは何か教えてください

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

A 回答 (2件)

例えば、


0110+0101
の演算の場合、

論理演算:
0110+0101
→偽真真偽 OR 偽真偽真
→偽真真真
→0111

算術演算:
0110+0101
→6 + 5 (十進数)
→11 (十進数)
→1011

だとか。


> 論理加算と算術加算とは何か教えてください

算術加算は小学校なんかで習う足し算。

論理加算は、通常は論理和の事です。

Wikipedia - 論理演算
http://ja.wikipedia.org/wiki/%E8%AB%96%E7%90%86% …
    • good
    • 1

論理加算と算術加算の違いは、データを符号無しとみなすか、符号付きとみなすかという点で異なっています。



◆違いの説明
 ・論理加算
  数値を符号無し数値(0~65535)として加算します。
 ・算術加算
  数値を符号付きの数値(-32768~32767)として加算します。

◆詳細な説明
 数値を見ただけ(データのビットの並び)では、論理加算と論理演算は
 同じ結果になります。
 結果が異なるのは、フラグレジスタのOF(OverFlow Flag)です。
 尚、フラグレジスタのSF(Sign Flag)はどちらの演算でも同じになり
 ます。

 極端な例として、0xFFFFに同じ数値0xFFFFを加算してみます。
 (0xはC言語で16進数の表記に使われているものです。)
  ○論理加算
    論理加算では0xFFFFは65535とみなされます。よって、
    0xFFFF(=65535)と0xFFFF(=65535)の論理加算結果は
    0x1FFFE(=131070)と16ビットの表現範囲を越えてしま
    い(オーバーフローとなり)ますので、実際の演算結果
    は 0xFFFE(=65534) となります。この場合、フラグ
    レジスタのOFは1にセットされます。

  ○算術加算
    算術加算では0xFFFFは-1とみなされます。よって、
    0xFFFF(=-1)と0xFFFF(=-1)の算術加算結果は
    0xFFFE(-2)となります。演算結果にはオーバーフロー
    はありませんので、フラグレジスタのOFは0になります。

 ちなみに、フラグレジスタのSFはどちらも1にセットされます。
 (それは、演算結果が0xFFFFで、bit15が1になっているからです。)
 論理加算の場合は符号無し演算なので、上の計算でSFが1になるのは
 納得しにくいところですが、情報処理推進機構(IPA)に問い合せたと
 ころそれは「仕様通り」だそうです。

論理加算(論理減算)・算術加算(算術減算)については、情報処理推進
機構の公開資料
 「試験で使用する情報処理用語・プログラム言語など Ver1.0」
の3頁を参照してください。

http://www.jitec.jp/1_00topic/topic_20081027_han …

また、実際の動作はCASLⅡシミュレータで確認することができます。
CASLⅡシミュレータは次のWEBを参照してください。

http://www.jitec.ipa.go.jp/1_20casl2/casl2dl_001 …

- 以上 -
    • good
    • 4

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

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

このQ&Aを見た人はこんなQ&Aも見ています

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

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

Qコンピューターで2進法が採用されている理由を教えてください

 2進法がコンピューターで使われているのはなぜですか?

Aベストアンサー

 
  初期の真空管で造った電子計算機では、二進法ではなく、十進法などを使っていたものでがありました。しかし、二進法が非常に有利で便利なので、二進法を使うようになったのです。
 
  理由:

  1)信号が、1と0だけでよい。十進法だと、信号が十個必要で、どの数かを判断する回路が必要になる。しかし、二進法だと、信号があるか、ないかの区別だけで非常に簡単である。
 
  2)これはコンピュータの心臓のCPUの設計に関係することですが、基本的には、CPUはレジスターという一種の計算機・勘定装置を使っています。これはたいへん原理は簡単なもので、簡単な計算を行います。このレジスターで、二進法を使うと非常に簡単に足し算とかができるし、また引き算、かけ算なども、少し工夫すると計算できるのです。
 
  例えば、111は二進法表現で7ですが、これにまた7を足し算するのは、
  111+111で、1+1=0(繰り上がり1) 1+0=1 0+1=1 0+0=0 という四つの計算規則だけでどんな数字でも、桁上がりだけ工夫すると計算できるのです。また引き算やかけ算も簡単に行えます。
 
  3)あるいは、フリップ・フロップ回路という面白く単純で、しかし重要な計算回路があるのですが、これは二進法での回路なのです。 

  4)コンピュータは大きな記憶装置を使うのです。この記憶装置は、あるかないか、つまり、1か0で記録すると、非常に簡単なのです。記録も速いし、読みとりも速いのです。
 
  こう言った理由で、二進法つまり1と0の信号で、コンピュータのなかでは計算や記録や記憶を処理しているのです。これを、5進法だとか、10進法にすると、たいへん複雑になるのです。
 
  人間はしかし二進法ではどんな数がすぐ分かりませんから、入力する時は十進法で、途中で二進法に変え、また、出力する時も、二進法だったのを、人間に分かるように十進法にしているのです。
 

 
  初期の真空管で造った電子計算機では、二進法ではなく、十進法などを使っていたものでがありました。しかし、二進法が非常に有利で便利なので、二進法を使うようになったのです。
 
  理由:

  1)信号が、1と0だけでよい。十進法だと、信号が十個必要で、どの数かを判断する回路が必要になる。しかし、二進法だと、信号があるか、ないかの区別だけで非常に簡単である。
 
  2)これはコンピュータの心臓のCPUの設計に関係することですが、基本的には、CPUはレジスターという一...続きを読む

Qfgetsなどのときのstdinのバッファを消すには?

こんにちは,今C(C++でない)を使用しています。
たとえば,
char str[20]
fgets(str,sizeof(str),stdin)
としたときに20字以上を打つと,stdinのバッファに20字以上の分が残ったままになります。

C++などでは
fflush(stdin)で,うまくいきますが,普通のCでは対応がされていないみたいでうまくいきません。

よろしくお願いします。

Aベストアンサー

あ,テキスト入力だからこんな大掛かりなことしなくてもいいんだ.
末尾に'\n'が出るまで掃出せばいいんですよね.

fgets(str, sizeof(str), stdin);
if ( str[strlen(str)-1] != '\n' ){
while( getchar() != '\n' );
}

でいいんだ.失礼しました.

Qprintf による16進表示について

C言語初心者です。

今作っているプログラムで、データを16進形式で表示しようとしています。
大体このような感じです。

/*入力時*/
char buf[5]={0x4e,0x94,0xa0,0x2b,0x78}

/*出力時*/
for (i = 0; i < 5; i++) {
printf("0x%02x\n",buf[i])
}

実際には入力後にある処理によってbufは更新されるのですが、printfの出力結果として、

0xffffff4e
0x94
0xffffffa0
0x2b
0x78

というように、'ffffff'が付加したものがいくつか出力されてしまいます。
これはどういった意味を持つのでしょうか?

なんか初心者ならではの漠然とした質問ですいません。。。

Aベストアンサー

出力は、
0x4e
0xffffff94
0xffffffa0
0x2b
0x78
ではありませんか?
char が符号付(-128~127)のため、0x80~0xffは負の数とみなされます。printfの引数になる時に 符号付charは符号付intに変換されますが、このCコンパイラの場合は、int が4バイトcharが1バイトのため、上位3バイトに負の数を示すffffffが入ります。
char x=255;
printf("%d\n",x);
だと255でなく、-1が表示されます。

対応としては、
unsingned char buf[5]={0x4e,0x94,0xa0,0x2b,0x78}
;
とするか、
printf("0x%02x\n",buf[i]&0xff);
にするかどちらかですね。

Qprintf で二進表示を行いたい。

すみません。教えていただきたいことがあります。
printf で普通のintの値をフォーマット指定子を使用して二進表示をしたかったのですが見当たりませんでした。
どうにかintの内容を二進で確認したいのですが、どのようにすれば良いですか?
宜しくお願いします。

Aベストアンサー

★2進整数を表示する関数を自作すればよい。
・作り方は簡単で、最上位ビットから順に『0』と『1』を調べていき、ビットが
 立っていれば『putchar('1');』にして、ビットが OFF なら『putchar('0');』
 にすれば良いでしょう。
・下にサンプルを載せますので使いやすいように改良して下さい。

サンプル:
unsigned int bit = (1 << (sizeof(int) * 8 - 1));
int value = 12345; ←これが表示したい int 型の整数値です。

printf( "value の 2進表記は " );

for ( ; bit != 0 ; bit >>= 1 ){
 if ( value & bit ){
  putchar('1');
 }
 else{
  putchar('0');
 }
}
printf( " です。\n" );

最後に:
・1バイトが 8 ビットの環境が前提です。→まぁ、普通は 8 ビットですが…。
・上記のサンプルを関数などにすれば使いやすくなります。→print_bin()など
・以上。おわり。

★2進整数を表示する関数を自作すればよい。
・作り方は簡単で、最上位ビットから順に『0』と『1』を調べていき、ビットが
 立っていれば『putchar('1');』にして、ビットが OFF なら『putchar('0');』
 にすれば良いでしょう。
・下にサンプルを載せますので使いやすいように改良して下さい。

サンプル:
unsigned int bit = (1 << (sizeof(int) * 8 - 1));
int value = 12345; ←これが表示したい int 型の整数値です。

printf( "value の 2進表記は " );

for ( ; bit != 0 ; bit >>= 1 ){
 if...続きを読む

Q複数桁10進数の*桁目だけを抽出したい

タイトルがすべてと言えてしまうのですが、
例えば、int宣言された"4287"(この値は変動します)という数値があったとして、1桁目の"7"だけを別の変数へ引き抜きたいのですが、その場合にはANDによるマスク処理による演算で処理可能なのでしょうか?
また、他に良い方法などありましたら教えていただけますでしょうか?

Aベストアンサー

★10進数ですので AND は使えませんね。
・簡単なサンプルを載せますので読み取って下さい。

サンプル1:
int value = 4287;
int a[ 4 ];

a[0] = (value % 10); value /= 10; // 1桁目を取り出す
a[1] = (value % 10); value /= 10; // 2桁目を取り出す
a[2] = (value % 10); value /= 10; // 3桁目を取り出す
a[3] = (value % 10); value /= 10; // 4桁目を取り出す

サンプル2:
int value = 4287;
int a;

a = (value % 10);
value -= a;

value → 4280
a → 7
になります。

Qnor回路だけでand,or,nand回路を作成したいのですが

タイトルの通り、nor回路だけでand,or,nand回路を作成したいのですが、or回路はnor回路を二つ並べて作成することができたのですが、andとnandの回路を作ることができません。教えてもらえないでしょうか。

Aベストアンサー

ANDを二重否定して、ドモルガンで変形させていくと良いです。
NOT回路は、NOR回路の入力をつないで一つにしてしまえば出来ます。
ANDが出来れば、NOTをつないでNANDに。

QCASLIIのADDAとADDLの演算

次の問題があっているのかわかりません。

次のCASLIIプログラムの実行後のレジスタ(GR1,FR)とメモリ(AA,BB,CC番地)
の内容を16進表示および符号付き10進表示せよ。

PGM START
LD GR1,AA
ADDA GR1,BB
ST GR1,CC
RET
AA DC 32767
BB DC 1
CC DS 1
END

32767をGR1に入れて、1加算する。
だからGR1 = 32768
と思ったのですが、先生の書いた答えは
-32768
でした。

PGM START
LD GR1,AA
ADDL GR1,BB
ST GR1,CC
RET
AA DC #7FFF
BB DC 1
CC DS 1
END

#7FFFに1加算するので
GR1=#8000
だと思います。


また自分で書いた板書に

Arithmetic[ -32768, 32767](#8000,#7FFF)
Logical[0,65535](#0000,#FFFF)

とありました。
板書をとったのがだいぶ前なのでこれの意味をよく覚えていないのですが、
ADDA命令のときに扱える値の範囲は-32768,~32767
ADDL命令のときに扱える値の範囲は0~65535
ということなのでしょうか。

その場合、先ほどの問題のADDAの問題で
32767 + 1 をしたら範囲を超えてしまいます。
このような場合どうなるのでしょうか?
ADDLの場合も範囲を超えてしまったらどうなるのですか?

よろしくお願いします。

次の問題があっているのかわかりません。

次のCASLIIプログラムの実行後のレジスタ(GR1,FR)とメモリ(AA,BB,CC番地)
の内容を16進表示および符号付き10進表示せよ。

PGM START
LD GR1,AA
ADDA GR1,BB
ST GR1,CC
RET
AA DC 32767
BB DC 1
CC DS 1
END

32767をGR1に入れて、1加算する。
だからGR1 = 32768
と思ったのですが、先生の書いた答えは
-32768
でした。

PGM START
LD GR1,AA
A...続きを読む

Aベストアンサー

> 32767をGR1に入れて、1加算する。
> だからGR1 = 32768
> と思ったのですが、先生の書いた答えは
> -32768

#8000 を絶対値 (Logical) で見れば 32768, 2の補数表現 (Arithmetical) で見れば -32768 というだけです。
CASLII では加算命令がそれぞれ ADDL, ADDA と別々に用意されていますが、実際やってることは FR レジスタの動きを除けば全く同じで、その計算結果を絶対値と見るか負数と見るかはプログラマの都合次第です。

ですから答に符号付きdecimalでと求められたら -32768 ということです。

> その場合、先ほどの問題のADDAの問題で
> 32767 + 1 をしたら範囲を超えてしまいます。
> このような場合どうなるのでしょうか?

FR レジスタの Overflow Flag を各々確認してみてください。どちらも GR1 は #8000 ですが OF は ADDA でだけ 1 になります。

> ADDLの場合も範囲を超えてしまったらどうなるのですか?

OF が 1 になる境界が違いますが同様です。逆に #7FFF+1 したときは 0 のまま
ちなみ同じことは SUBL, SUBA にも言えます

> 32767をGR1に入れて、1加算する。
> だからGR1 = 32768
> と思ったのですが、先生の書いた答えは
> -32768

#8000 を絶対値 (Logical) で見れば 32768, 2の補数表現 (Arithmetical) で見れば -32768 というだけです。
CASLII では加算命令がそれぞれ ADDL, ADDA と別々に用意されていますが、実際やってることは FR レジスタの動きを除けば全く同じで、その計算結果を絶対値と見るか負数と見るかはプログラマの都合次第です。

ですから答に符号付きdecimalでと求められたら -32768 ということです。

> その場...続きを読む

Q ポインタを使って関数の値のやり取り

c言語の問題なのですが、2つの異なる1次元配列の積をseki関数を使って計算してもうひとつの配列に入れてmain関数で表示するのですが、うまく走りません原因がわかる人がいた教えてください。
作った実行文は、
#include<stdio.h>
int seki(int *pa,int *pb,int *pc);
main(){
int a[]={5,2,3,5,3,2,4,8,9,9,7},b[]={4,3,8,4,6,2,8,9,1,6,4},c[11]={0};
int i,*pa,*pb,*pc;

pa=&a;
pb=&b;
pc=&c;

seki(pa,pb,pc);
for(i=0;i<11;i++)
printf("%d,",*(pc+i));

}
int seki(int *pa,int *pb,int *pc){
int j;
for(j=0;j<11;j++)
*(pc+j)=*(pa+j) * *(pb+j);
}
こんな表示が出てきます。
toi2.c: In function `main':
toi2.c:7: warning: assignment from incompatible pointer type
toi2.c:8: warning: assignment from incompatible pointer type
toi2.c:9: warning: assignment from incompatible pointer type
たぶんmain関数内で書いたseki関数の引数の型に問題があると思うのですが。

c言語の問題なのですが、2つの異なる1次元配列の積をseki関数を使って計算してもうひとつの配列に入れてmain関数で表示するのですが、うまく走りません原因がわかる人がいた教えてください。
作った実行文は、
#include<stdio.h>
int seki(int *pa,int *pb,int *pc);
main(){
int a[]={5,2,3,5,3,2,4,8,9,9,7},b[]={4,3,8,4,6,2,8,9,1,6,4},c[11]={0};
int i,*pa,*pb,*pc;

pa=&a;
pb=&b;
pc=&c;

seki(pa,pb,pc);
for(i=0;i<11;i++)
printf("%d,",*(pc+i));

}
int seki(int *pa,int *pb,i...続きを読む

Aベストアンサー

質問の下に書かれているコンパイルエラーと思われる表示から
そのエラーの原因が読み取ることが出来ます。
ここでの原因は、プログラム中次の3行がエラーであると指摘されています。
7行目:pa=&a;
8行目:pb=&b;
9行目:pc=&c;
それぞれ、どういう状況かというと、
エラーをそのまま訳せば
『ポインタとしての割り当て方がおかしいですよ』
という風に捉えられます。
まず、整数型配列として宣言してあるaという変数があります。
これは、これ自身がポインタであるので
&aという表記では、『ポインタ変数aのポインタ』ということになり、
純粋なポインタ変数paには代入する事ができません。
よって、上のエラーを解消するには、
pa = a;
とすればよいでしょう。
(8,9行目も同様)

Qint型からchar型への変換

タイトル通り、int型からchar型への変換の仕方がわかりません!><
どうしたらいいのでしょうか?

Aベストアンサー

#include <stdio.h>


char buf[5];
int no;

no = 10;
sprintf(buf, "%d", no);

QC言語のポインターに関する警告

line[100]で
「1」が格納されていたら「a」
「2」が格納されていたら「b」
「3」が格納されていたら「c」
とout[100]に代入する関数を作りたいのですが
コンパイルすると関数の部分で
warning: assignment makes integer from pointer without a cast
という警告がでます。
ポインターは使っていないのですが、ポインターに関する警告が出ているようで困っています。
どこが悪いのかまったくわからなくて作業が完全に止まってしまいました。
解決法をおしえてください。お願いします。

/*宣言*/
int=i; /*main関数内のfor文で使用*/
char line[100], out[100];
void change(int);

/*関数*/
void change(int i)
  {
   if(line[i]=='1'){
    out[10]="a\0"
   }if(line[i]=='2'){
    out[10]="b\0";
   }if(line[i]=='3'){
    out[10]="c\0"
}
}

line[100]で
「1」が格納されていたら「a」
「2」が格納されていたら「b」
「3」が格納されていたら「c」
とout[100]に代入する関数を作りたいのですが
コンパイルすると関数の部分で
warning: assignment makes integer from pointer without a cast
という警告がでます。
ポインターは使っていないのですが、ポインターに関する警告が出ているようで困っています。
どこが悪いのかまったくわからなくて作業が完全に止まってしまいました。
解決法をおしえてください。お願いします。

/*宣言*/
int...続きを読む

Aベストアンサー

>    out[10]="a\0"
>    out[10]="b\0";
>    out[10]="c\0"

"a\0"や"b\0"や"c\0"は「charへのポインタ」ですよ。

out[10]は「char」ですから「記憶域が小さい整数(つまり、charに)に、ポインタを代入すると、値が失われるぞ」と警告が出ます。

void change(int i)
  {
   if(line[i]=='1'){
    out[10]='a';
   }if(line[i]=='2'){
    out[10]='b';
   }if(line[i]=='3'){
    out[10]='c';
}
}
または
void change(int i)
  {
   if(line[i]=='1'){
    out[10]=0x61; /* aのASCIIコード */
   }if(line[i]=='2'){
    out[10]=0x62; /* bのASCIIコード */
   }if(line[i]=='3'){
    out[10]=0x63; /* cのASCIIコード */
}
}
と書きましょう。

>    out[10]="a\0"
>    out[10]="b\0";
>    out[10]="c\0"

"a\0"や"b\0"や"c\0"は「charへのポインタ」ですよ。

out[10]は「char」ですから「記憶域が小さい整数(つまり、charに)に、ポインタを代入すると、値が失われるぞ」と警告が出ます。

void change(int i)
  {
   if(line[i]=='1'){
    out[10]='a';
   }if(line[i]=='2'){
    out[10]='b';
   }if(line[i]=='3'){
    out[10]='c';
}
}
または
void change(int i)
  {
   if(l...続きを読む


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング