課題:基数変換

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら

課題:基数変換

#1

投稿記事 by » 15年前

はじめまして。
以下のことで困っています。
[1] 質問文
 [1.1] 課題で、基数変換のプログラムを作っています。
    整数部と小数部に分け、それぞれ2進数から20進数まで、最大12桁表示するというものを目指していま    す。
 [1.2] 以下が自作のソースコードです。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

int power(int dx, int no)
{
int tmp=1;

while(no-- > 0)
tmp*=dx;
return(tmp);
}

int main(void)
{
char in1[50]; //基数変換する数(整数部)//
char in2[50]; //基数変換する数(小数部)//
int a=0;
int b=0;
int base1; //基数//
int base2=10;
int i;
int n; //変換後の桁数//
int p1[50];
int p2[50];
int q1[50];
int q2[50];
char out1[12]; //基数変換後の数(整数部)//
char out2[12]; //基数変換後の数(小数部)//

printf("基数変換する数の整数部を入力してください:");
scanf("%c", &in1[50]);
printf("基数変換する数の小数部を入力してください:");
scanf("%c", &in2[50]);
printf("基数を入力してください(2-20):");
scanf("%d", &base1);
printf("変換後の桁数を入力してください(1-12):");
scanf("%d", &n);

//10進数への変換//
for(i=n-1; i=0; i--){
//整数部分//
switch(in1){
case '0' : p1=0; break;
case '1' : p1=1; break;
case '2' : p1=2; break;
case '3' : p1=3; break;
case '4' : p1=4; break;
case '5' : p1=5; break;
case '6' : p1=6; break;
case '7' : p1=7; break;
case '8' : p1=8; break;
case '9' : p1[i]=9; break;
case 'A' : p1[i]=10; break;
case 'B' : p1[i]=11; break;
case 'C' : p1[i]=12; break;
case 'D' : p1[i]=13; break;
case 'E' : p1[i]=14; break;
case 'F' : p1[i]=15; break;
case 'G' : p1[i]=16; break;
case 'H' : p1[i]=17; break;
case 'I' : p1[i]=18; break;
case 'J' : p1[i]=19; break;
}

a+=p1[i]*power(base2, i);

//小数部分//
switch(in2[i]){
case '0' : p2[i]=0; break;
case '1' : p2[i]=1; break;
case '2' : p2[i]=2; break;
case '3' : p2[i]=3; break;
case '4' : p2[i]=4; break;
case '5' : p2[i]=5; break;
case '6' : p2[i]=6; break;
case '7' : p2[i]=7; break;
case '8' : p2[i]=8; break;
case '9' : p2[i]=9; break;
case 'A' : p2[i]=10; break;
case 'B' : p2[i]=11; break;
case 'C' : p2[i]=12; break;
case 'D' : p2[i]=13; break;
case 'E' : p2[i]=14; break;
case 'F' : p2[i]=15; break;
case 'G' : p2[i]=16; break;
case 'H' : p2[i]=17; break;
case 'I' : p2[i]=18; break;
case 'J' : p2[i]=19; break;
}

b+=p2[i]/power(base2, i);
}

//n進数への変換//
for(i=0; i<n; i++){
//整数部分//
q1[i]=a%base1;

switch(q1[i]){
case 0 : out1[i]='0'; break;
case 1 : out1[i]='1'; break;
case 2 : out1[i]='2'; break;
case 3 : out1[i]='3'; break;
case 4 : out1[i]='4'; break;
case 5 : out1[i]='5'; break;
case 6 : out1[i]='6'; break;
case 7 : out1[i]='7'; break;
case 8 : out1[i]='8'; break;
case 9 : out1[i]='9'; break;
case 10 : out1[i]='A'; break;
case 11 : out1[i]='B'; break;
case 12 : out1[i]='C'; break;
case 13 : out1[i]='B'; break;
case 14 : out1[i]='E'; break;
case 15 : out1[i]='F'; break;
case 16 : out1[i]='G'; break;
case 17 : out1[i]='H'; break;
case 18 : out1[i]='I'; break;
case 19 : out1[i]='J'; break;
}

//小数部分//
q2[i]=b*base1;

switch(q2[i]){
case 0 : out2[i]='0'; break;
case 1 : out2[i]='1'; break;
case 2 : out2[i]='2'; break;
case 3 : out2[i]='3'; break;
case 4 : out2[i]='4'; break;
case 5 : out2[i]='5'; break;
case 6 : out2[i]='6'; break;
case 7 : out2[i]='7'; break;
case 8 : out2[i]='8'; break;
case 9 : out2[i]='9'; break;
case 10 : out2[i]='A'; break;
case 11 : out2[i]='B'; break;
case 12 : out2[i]='C'; break;
case 13 : out2[i]='B'; break;
case 14 : out2[i]='E'; break;
case 15 : out2[i]='F'; break;
case 16 : out2[i]='G'; break;
case 17 : out2[i]='H'; break;
case 18 : out2[i]='I'; break;
case 19 : out2[i]='J'; break;
}
}

printf("整数部:%c", &out1[12]);
printf("小数部:0.%c", &out2[12]);

return(0);
}
 [1.3] デバッグでエラー・警告は出ないのですが、
    エラー:Debug Error
Run-Time Check Failure #2
Stack around the variable 'in1' was corrupted

        ここで再試行を選択すると、以下のメッセージが出ます。
例外unknown software exception(0x8000003)がアプリケーションの0x7c94120eで発生しまし        た
    
    また、入力値(小数部)in2と基数が同じ行に表示される
       肝心の変換後の値が出ない
    というトラブルも起こっています。
 [1.4] とりあえず、明日までの課題なので、早急に1.3の事項について解決したいです。
[2] 環境  
 [2.1] OS : Windows XP
 [2.2] コンパイラ名 : VC++(Visual Studio2005)
[3] その他
 ・プログラミング全般に関して初心者です。

よろしくお願いいたします。

Re:課題:基数変換

#2

投稿記事 by » 15年前

内容に不備がありましたので、捕捉します。
すみません。

課題の内容はn進数からm進数への変換です。
最初に文字列(n進数)で入力してから
10進数へ(一旦)変換し、それから指定した基数(m進数)へ変換します。

また、字下げしようとして、変なスペースが文章中に入っていました。
本当にすみません。

toyo

Re:課題:基数変換

#3

投稿記事 by toyo » 15年前

とりあえず
printf("基数変換する数の整数部を入力してください:");
scanf("%c", &in1[50]);
が間違っています
in1配列は0-49までの50個なのでin1[50]が範囲外となります
scanf("%c", &in1[0]);
のようにすればエラーは出ませんがこれでは1文字だけしか入力されないのでやりたいこととは違うはずです
実際にやりたいことは0~Jの英数文字列を読み込むのだと思いますが文字列の読み込みは%cではなく%sです
scanf("%s", in1);
で読み込めるはずです(in2についても同様)
とりあえずここまでやってみてください

Re:課題:基数変換

#4

投稿記事 by » 15年前

エラーは解決しました。
ありがとうございます。

Re:課題:基数変換

#5

投稿記事 by » 15年前

とんでもない間違いを見つけたので、訂正します。

base1 変換する基数
base2=10 10進数に直すとき用の基数


base1  入力した値の基数
base2  出力する値の基数
本当に申し訳ありませんでした。

まだ、出力が
整数値:000000フフフフフフフフフフ小数部:0.000000フフフフフフフフフフフフフフフフフフフフフ00000フフフフフフフフフフ
のようになってしまっています。
どなたかご教授いただければ嬉しいです。

box

Re:課題:基数変換

#6

投稿記事 by box » 15年前

> for(i=n-1; i=0; i--){

このfor文の意味を日本語で説明してください。

DVDM

D3DCOLOR型で定義した変数のアルファ値のみを変更するには

#7

投稿記事 by DVDM » 15年前

D3DCOLOR(unsigned long) 型で定義した変数のアルファ値のみを変更する方法が解らないです。

<d3d9types.h>に記述されていた D3DCOLOR_ARGB マクロには

#define D3DCOLOR_ARGB(a,r,g,b) \
  ((D3DCOLOR)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff)))

このように記述されていて、先頭から8ビット毎に区切られ、ARGB という情報になっているようです。


D3DCOLOR 型の変数を仮に Color とし、
下記のように記述するとアルファ値は変わったのですが、ついでに色も変わってしまいました。
Color = ( (Color&0x0FFF) | (設定したいアルファ値<<24) );

(Color&0x0FFF) これで RGB の情報を抜き出そうとしています。
その抜き出した値とシフトしたアルファ値とを OR 演算すれば
アルファ値が変わるだろうと思ってこのような記述になってます。



どのようにビット演算を行えばアルファ値のみを変更できるのでしょうか。
もし宜しければアドバイスお願い致します。


OS:XP
コンパイラ:Visual C++ 2008 Express Edition(編集箇所)
ライブラリ:DirectX SDK (October 2006) 画像

シエル

Re:D3DCOLOR型で定義した変数のアルファ値のみを変更するには

#8

投稿記事 by シエル » 15年前

私もDirectXを猛勉強中ですので、間違っているかもしれませんが、
D3DCOLOR型の情報は下記のように左からFF二つでアルファ値、以降は二つずつで
赤、緑、青の値を表していると思います。

  A R G B
0xFFFFFFFF

ですので、赤色にアルファ値を足したい場合は、

0x00FF0000 | (設定したいアルファ値<<24)

とすれば、いけるような気がします。

まだ勉強中なので完全に間違っているかもしれませんが、よろしくお願いします。 画像

御津凪

Re:D3DCOLOR型で定義した変数のアルファ値のみを変更するには

#9

投稿記事 by 御津凪 » 15年前

> Color = ( (Color&0x0FFF) | (設定したいアルファ値<<24) );

では下位12ビット分しか保持できていません。
単純なマスク値の間違いです。

D3DCOLOR型は各色の表現範囲は 0 ~ 255 (0x00 ~ 0xff) なので、0 ~ 23 ビットを保持するようにマスクをかける必要があります。

シエルさんの色要素と各ビットとの対応は正しいので正解ですよ。
ただし、色要素の順序が正反対のフォーマット(BGRA)や、アルファ要素のないフォーマット(XRGB)もありますので注意です。


ちなみに関係ない話ですが、
DirectX には float 版の D3DCOLORVALUE型があり、こちらは 0.0f ~ 1.0f の(上限・下限を超えた場合は丸められる)範囲で表現します。
(DX9 ではマテリアルやライトなどの構造体で、DX10以降は全般的に使用されています)

また、 C++ では D3DCOLOR を継承した D3DXCOLOR 構造体があるので、
こちらを使ってみるのもいいかと思います。

DVDM

Re:D3DCOLOR型で定義した変数のアルファ値のみを変更するには

#10

投稿記事 by DVDM » 15年前

>>シエルさん
[color=gray>> 0x00FF0000 | (設定したいアルファ値<<24)
> とすれば、いけるような気がします。 [/color]
unsigned long がいつの間にか16ビットになっていたようですね;
ありがとうございます!
その方法でばっちり直りました!

シエルさんも DirectX 使いですか~。
覚えることが沢山あって大変ですがお互い頑張りましょう~



>>御津凪さん
[color=gray>>下位12ビット分しか保持できていません。[/color]
確かに仰るとおりです…。

[color=gray>> D3DCOLORVALUE型・D3DXCOLOR 構造体[/color]
以前制作していた STG では D3DXCOLOR 構造体を使用していましたが
D3DCOLOR の方も気になっていたので練習も兼ねて今回のプロジェクトではこちらを選びました。

また、D3DCOLORVALUE 型も気になっていたのですが、
やはり0~255の方が馴染み深かったので D3DCOLOR の方を選びました。


[color=gray>> 色要素の順序が正反対のフォーマット(BGRA)や、
> アルファ要素のないフォーマット(XRGB)もありますので注意です。 [/color]
RGBA や XRGB は聞いたことありますけど BGRA は始めて聞きました。
今の所は ARGB というフォーマットが変わることはないと思うので
こういうのもあるんだなと覚えておきます!


シエルさん・御津凪さん、御回答ありがとうございました!

閉鎖

“C言語何でも質問掲示板” へ戻る