C言語関係掲示板

過去ログ

No.1143 −1664を16ビットの2の補数表現で表すプログラムを作りたい!

[戻る] [ホームページ]
No.14560

ー1664を16ビットの2の補数表現で表すプログラムを作りたい!
投稿者---アホあほ太郎(2004/06/11 02:18:10)


ー1664を16ビットの2の補数表現で表すプログラムを作りたいのですが、さっぱりわかりません。



No.14561

Re:ー1664を16ビットの2の補数表現で表すプログラムを作りたい!
投稿者---あかま(2004/06/11 03:12:22)


>ー1664を16ビットの2の補数表現で表すプログラムを作りたいのですが、さっぱりわかりません。
ほとんどの計算機では2の補数表現で表されていますから、適当に作ったプログラムで表題を満たしています。
あとは-1664を16bitの変数にでも代入するだけでしょう。

int a = -1664;




No.14571

Re:ー1664を16ビットの2の補数表現で表すプログラムを作りたい!
投稿者---NykR(2004/06/11 18:02:46)


>ほとんどの計算機では2の補数表現で表されていますから、

符号なし整数なら2の補数になることが保証されています。
#include <stdio.h>

typedef unsigned long long ullong;

#define BIT_1(num)  ((ullong)(num) & 1)
#define BIT_2(num)  ((BIT_1((num)>>1)<<4)+BIT_1(num))
#define BIT_4(num)  ((BIT_2((num)>>2)<<8)+BIT_2(num))
#define BIT_8(num)  ((BIT_4((num)>>4)<<16)+BIT_4(num))
#define BIT_16(num) ((BIT_8((num)>>8)<<32)+BIT_8(num))

int main(void)
{
    printf("%016llx\n", BIT_16(-1664U));

    return 0;
}



No.14572

Re:ー1664を16ビットの2の補数表現で表すプログラムを作りたい!
投稿者---かずま(2004/06/11 19:23:29)


#define B1(n)   ((n) & 1)
#define B2(n)   B1((n)>>1), B1(n)
#define B4(n)   B2((n)>>2), B2(n)
#define B8(n)   B4((n)>>4), B4(n)
#define B16(n)  B8((n)>>8), B8(n)

    printf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d\n", B16(-1664u));

unsigned long long の使えない処理系でも大丈夫。



No.14573

Re:ー1664を16ビットの2の補数表現で表すプログラムを作りたい!
投稿者---YuO(2004/06/11 20:59:22)


>符号なし整数なら2の補数になることが保証されています。

え〜っと,それはどこに記述があるのでしょうか?

-1664Uは単項演算子-と整数定数1664Uに区切られます。
つまり,-1664Uとは-1664に他ならないことになります。


ややこしいことを考えず,素直に1の補数をとる演算子~を使って,
unsigned short twosComplement (unsigned short n)
{
    return (~n + 1) & 0xFFFF;
}
でよいと思いますが。



No.14575

Re:ー1664を16ビットの2の補数表現で表すプログラムを作りたい!
投稿者---かずま(2004/06/11 22:13:52)


>>符号なし整数なら2の補数になることが保証されています。
>
> え〜っと,それはどこに記述があるのでしょうか?

「6.2.5 型」のところに「符号無しオペランドを含む計算は、決してオーバー
フローしない。すなわち、結果を符号無し整数で表現できないときは、その型
で表現しうる最大値より 1だけ大きい数を法とする剰余を結果とする。」と
あります。


> -1664Uは単項演算子-と整数定数1664Uに区切られます。
> つまり,-1664Uとは-1664に他ならないことになります。

分かりやすくするために、int を 8ビットとします。

   5 の 2進表現           0 0000101
  -5 の 2の補数表現       1 1111011
  -5 の 1の補数表現       1 1111010
  -5 の符号と絶対値表現   1 0000101
     (負数の表現については、「6.2.6.2 整数型」参照)

5u に単項-演算子 を適用すると、0 - 5u の計算をするものと考えて、結果は
11111011 ですから、符号付き整数の 2の補数表現と一致します。

しかし、処理系が 2の補数表現を採用していない場合、-5u と -5 は表現が
異なることになります。

「6.5.3.3 単項算術演算子」の単項-演算子の説明はちょっと不十分ですね。
~演算子のように符号無し整数についての説明をつければいいのにと思います。



No.14582

Re:ー1664を16ビットの2の補数表現で表すプログラムを作りたい!
投稿者---NykR(2004/06/12 12:14:30)


> 「6.5.3.3 単項算術演算子」の単項-演算子の説明はちょっと不十分ですね。
> ~演算子のように符号無し整数についての説明をつければいいのにと思います。

K&R A7.4.5 単項のマイナス演算子
には、説明がありますね。

「符号なし量の符号反転は、格上げされた値の最大の値から格上げされた値を引き、1を加えることによって求められる。しかし負のゼロはゼロである。結果の型は格上げされた被演算数の型となる。」

このことは規格では、直接書かれていないので、あちこち読まないとわかりません。ですが、No.14571の発言はK&Rのこの記述が念頭にあったので、それほどややこしいことは考えていないのです。

16進数で表示したときに元の値の2進数表示になるような変換をする、というのはややこしい考え方かもしれませんが。
これの影響かもしれません。