お酒好きのおしりトラブル対策とは

「1/2+1/3と引数を渡して、5/6という返り値を得る」という汎用のライブラリってありますでしょうか?

現状では1/2+1/3=0.5+0.33333333=0.833333333と計算
 ↓
continued fractions(http://mathforum.org/library/drmath/view/51886.h …)
の手法で分数に変換してます。

しかし、近似解であり厳密解でないため、収束条件をかえると違う値を返してきます。

「MathematicaやMapleというalgebra softwareをC#から呼び出す」と簡単に実装できるのですが
単に分数計算するためだけなのに○十万円するのはちょっと、。。

で、
(1)商用であってもいいんだけど、できれば1万円以下
(2).netから呼べる。
(3)分数の厳密解を返す
みたいなものをご存知のかたがおられましたらよろしくご教示ください。

よろしくお願いします。

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

A 回答 (5件)

若干ずれた回答かもしれませんが、外部から他の数式処理システム呼び出してもよく、市販の数式処理ソフトが高価な事が問題なのであれば、Maximaのようなフリーのものを使うというのはダメでしょうか?


私はMaximaしか使ったことありませんし、外部から呼び出したことはないので、連携のしやすさなどはちょっとわからないのですが、フリーの数式処理ソフトは結構あるみたいですよ。
http://ja.wikipedia.org/wiki/%E6%95%B0%E5%BC%8F% …

この回答への補足

みなさんご回答ありがとうございました。

「Maximaにお伺いをたてる→答えをもらう」方式で解決させました。


後学のために記すと、
1.SocketServerを作って、任意のポート(m_PortNum)をlistenする。
2.1.のあと、maxima.bat -s m_PortNumとすると、MaximaがClientになってSocketServerに自動接続する(IPアドレスをどのように処理and/or指定するのかは不明だが、ローカルPC同士なので127.0.0.1で決め打ち?)
3.ServerとMaxima間でtalk開始。


MaximaがMathematicaやMapleに劣らない強力なツールであることも分かりました。

補足日時:2011/10/07 10:45
    • good
    • 0
この回答へのお礼

ありがとうございます。

Maximaには十分ポテンシャルがあるようですね。

ただ.netとの連携がMathematicaやMapleほどではないようです。

Googleすると http://www.math.utexas.edu/pipermail/maxima/2009 …
という記事をみつけました。

ややダサい連携方式のようにも思えますが、この方法とNo2さんご指摘のRuby方式と
両者を比較して実現可能性が高いもので作りこみたいと思います。

お礼日時:2011/10/04 15:01

C#なら、分子と分母を持ったクラスに定義して、演算子をオーバーロードして分数計算するようにすれば、そんなに難しいことでは無いと思うのですが。



例えば、class rとして定義。
コンストラクタとして
r(int 分子, int 分母)
r(int 分子) // 分母=1
とすれば

> {(5.5+25/15)÷73.7+12/15}-152 }
→ ( r(5,10) + r(25) / r(15) ) / r(737,10) + r(12)/r(15) - r(152) )

でいいはずです。
整数の桁を考えなければ、そんなに難しいことじゃないですよ。
    • good
    • 0

「式を (文字列かなにかで) 与えたら計算してくれる」というのと「(単に) 計算する」というのとでは難易度が違うのでねぇ.



後者は, 例えば Gnu MP のラッパーがあるみたいなのでそれでなんとかできないかな. 前者も, たぶん (構文解釈として) 調べればあるんじゃないかなぁ.
    • good
    • 0

rubyという言語はrationalという型(クラス)をもっています。


これは、分数を計算するための型です。
---------------------------------
a = Rational(1,2)
b = Rational(1,3)
c = a + b
p c
-------------------------
上記はrubyのコードですが
a = 1/2
b = 1/3
c = a+ b
cの内容を表示
を行なっています。
上記を実行すると
5/6が結果として得られます。
rubyのこの機能を使用すればよいかと思います。

尚、C#から直接呼び出したい場合は、
マイクロソフトからironruby(.NETで動作するruby互換のスクリプトエンジン)
が提供されています。
以下のURLを参照ください。
ironruby
http://ironruby.net/

Rational クラス
http://www.ruby-lang.org/ja/old-man/html/Rationa …

ruby本家
http://www.ruby-lang.org/ja/

C#からironrubyを呼び出す方法
http://www.m-tea.info/2009/12/c-ironruby-1.html
    • good
    • 0
この回答へのお礼

ご教示ありがとうございます!!

当方.net専従で、rubyは食わず嫌いしてたのですが、いい機会と考えてあたってみます。

お礼日時:2011/10/04 14:49

(b/a)+(d/c)=(ad+bc)/acですね。



そこで、分母と分子をメンバーとして持つような構造体を

typedef struct {
int bunbo;
int bunshi;
} bunsuu;

のように定義して、

bunsuu f(bunsuu x, bunsuu y);

というプロトタイプを持つ関数を書けばよいのではないでしょうか。

そういう話ではなくて、別のことをおっしゃっていますか?
    • good
    • 0
この回答へのお礼

早々の解答ありがとうございます。

>そういう話ではなくて、別のことをおっしゃっていますか?
質問文がやや誤解させるもので申し訳ございません。

構造型を定義して、自前で通分・約分する関数を作って、演算オペレータを解釈して、{}()の優先順位を判断して...は正しい方向性かと思います。

しかし、たとえば{(5.5+25/15)÷73.7+12/15}-152みたいな式を与えて、
分数での厳密解を得るものは難しくて、私には作れそうもありません。

で、{(5.5+25/15)÷73.7+12/15}を与えると答え=○○/△△を返す汎用ライブラリがあれば..
ということであります。

既述したように○十万円する数式処理システムは、一発で解答を出す由でありますが
如何せん庶民には手が届きません~~

お礼日時:2011/10/03 21:26

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

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

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

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

Q分数の足し算をさせるプログラムが分かりません。どなたか分かりませんか?

分数の足し算をさせるプログラムが分かりません。

C言語の問題で分数の足し算までは一応できるんですが、答えがでたときに整数で出すやり方と約分して表す方法が分かりません。
どなたか知恵を貸してくれませんか?

ユーザから4つの整数を入力し、はじめに入力された2個の整数と後に入力された2個の整数を分数と考え、その分数の和を表示するプログラムを作成せよ。
例えば、「3」「4」「5」「6」と入力されたときは、3/4 + 5/6を計算する。
そのプログラム内では分数の和を計算する関数を作成する。
さらに、
約分を行う関数を 再帰呼び出しを利用して作成する。
void yakubun(int *a1, int *a2)

例えば、以下の場合1/2と表示される。
int i=10,j=20;
yakubun(&i,&j);
printf(“%d / %d”, i, j);

ちなみにここまでできました↓

#include<stdio.h>
void bunsu_tasizan(int a1,int a2,int b1,int b2, int *c1,int *c2 )
{
*c1=(a1*b2)+(b1*a2);
*c2=(a2*b2);
}

int main()
{
int x1,x2,y1,y2,z1,z2;

printf("整数を入力してください");
scanf("%d",&x1);
scanf("%d",&x2);
scanf("%d",&y1);
scanf("%d",&y2);

if(x2==0||y2==0||x2==0&&y2==0)
printf("0以外を入力してください");
else{
bunsu_tasizan(x1,x2,y1,y2,&z1,&z2);

printf("%d/%d",z1,z2);}

return (0);
}

分数の足し算をさせるプログラムが分かりません。

C言語の問題で分数の足し算までは一応できるんですが、答えがでたときに整数で出すやり方と約分して表す方法が分かりません。
どなたか知恵を貸してくれませんか?

ユーザから4つの整数を入力し、はじめに入力された2個の整数と後に入力された2個の整数を分数と考え、その分数の和を表示するプログラムを作成せよ。
例えば、「3」「4」「5」「6」と入力されたときは、3/4 + 5/6を計算する。
そのプログラム内では分数の和を計算する関数を作成する。
...続きを読む

Aベストアンサー

#4 です.

> 再帰はどのように使えばいいのでしょうか?

#4 に挙げた URL の英語版には,再帰版と非再帰 (繰り返し) 版の
擬似コードがあります.

Euclidean algorithm (Wikipedia)
http://en.wikipedia.org/wiki/Euclidean_algorithm
→ Using recursion (再帰版擬似コード)
→ Using iteration (繰り返し版擬似コード)

Cで書けば,

// mとnの最大公約数 (GCD) を求める.
unsigned gcd(unsigned m, unsigned n)
{
 return (n == 0) ? m : gcd(n, m % n);
}

たったこんだけ.

Q分数を表示するプログラム(長文です)

(整数値)aの値と(整数値)bの値をキーボードから入力して、そこから、a/bという分数を作るプログラムを書きたいと思います。(符号や約分も考えた形にする)
僕は、ヒントを参考に以下のようなプログラムを書いたのですが、ある条件の下では、正しく動きません。
・aの値が負の場合
・aもbも負の値の場合 など・・・
#include <stdio.h>
#include <math.h>
int main ( void )
{
int a,b;
int k,min,sign;
printf("a=?");scanf("%d",&a);
printf("b=?");scanf("%d",&b);
if (a*b<0) sign = -1;
elsesign = 1;
a = sign*a ; b = sign*b;
if (abs(a)>abs(b)) min = b;
else min = abs(a);
for ( k=2 ; k<=min ; k++){
if (min%k == 0){
a = a/k;
b = b/k;
}
}
printf("a/b = %d",a);
if (b != 1)
printf("/%d\n",b);
else printf("\n");
return 0;
}
これをどのように修正すれば、正確な答えが出るのでしょうか?
教えてください。

(整数値)aの値と(整数値)bの値をキーボードから入力して、そこから、a/bという分数を作るプログラムを書きたいと思います。(符号や約分も考えた形にする)
僕は、ヒントを参考に以下のようなプログラムを書いたのですが、ある条件の下では、正しく動きません。
・aの値が負の場合
・aもbも負の値の場合 など・・・
#include <stdio.h>
#include <math.h>
int main ( void )
{
int a,b;
int k,min,sign;
printf("a=?");scanf("%d",&a);
printf("b=?");scanf("%d",&b);
if (a*b<0) sign = -1;
elsesi...続きを読む

Aベストアンサー

★アドバイス
・まずは算数からアドバイスします。
 - - ⇒+
 - + ⇒-
 + - ⇒-
 + + ⇒+
 ですよね。
・だから入力された a、b の符号から分数全体の sign を処理します。
 その後に a、b の2つの値を強制的に絶対値にします。→abs()関数で。
・あとは 2 から順に a、b のどちらかの小さい数まで約分を行います。
 このときに a、b の両方が割り切れるかをチェックします。
 両方が割り切れたときに割り算を行います。
・約分まで終わったら分数の形で表示して処理終了です。
 それではサンプルを載せますので見比べて下さい。

サンプル:
#include <stdio.h>
#include <stdlib.h>

int main( void )
{
 int a, b, k, min, sign;
 
 // a、b を入力
 printf( "a=?" ); scanf( "%d", &a );
 printf( "b=?" ); scanf( "%d", &b );
 
 // 3項演算子で符号を判定
 sign = (((a * b) < 0) ? -1 : +1);
 
 // 強制的に絶対値に変換
 a = abs( a );
 b = abs( b );
 min = ((a < b) ? a : b);
 
 // 約分
 for ( k = 2 ; k <= min ; k++ ){
  if ( !(a % k) && !(b & k) ){ ←a、bのが両方割り切れるか判定
   a /= k;
   b /= k;
  }
 }
 // 表示
 if ( b == 1 ){
  printf( "a/b = %+d\n", (sign * a) );
 }
 else{
  printf( "a/b = %+d/%d\n", (sign * a), b );
 }
 return 0;
}

最後に:
・分数全体の符号は表示する部分で掛け算すれば楽です。
 あと a、b のどちらか一方が 0 だった場合の処理を追加してみて下さい。
 回答者 No.4 さんの『do { … } while ( !(a | b) );』のやり方で入力を繰り返すのが
 一番スマートかなと思います。
 以上。

参考URL:http://www9.plala.or.jp/sgwr-t/c/sec14.html

★アドバイス
・まずは算数からアドバイスします。
 - - ⇒+
 - + ⇒-
 + - ⇒-
 + + ⇒+
 ですよね。
・だから入力された a、b の符号から分数全体の sign を処理します。
 その後に a、b の2つの値を強制的に絶対値にします。→abs()関数で。
・あとは 2 から順に a、b のどちらかの小さい数まで約分を行います。
 このときに a、b の両方が割り切れるかをチェックします。
 両方が割り切れたときに割り算を行います。
・約分まで終わったら分数の形で表示して処理終了です。
...続きを読む

Q2つ分数の四則演算を行うプログラム

<要求事項>
分数は、 例)1|3 のように表す。
1.分母がゼロの時はエラーとする。
2.除算において、除数がゼロの入力エラーに対しては、再入力するように促す。
3.以下範囲の整数(分子、分母にかかわらず)に対して、正しく計算できるようにする。
  -2147483648 ~ 2147483647

4.計算結果については,分母が1の時には分子のみ表示。分数がの時には0のみを表示。最終計算結果は既約分数にする。分数が負数の場合、-を分数の前に表示。

#include <stdio.h>
#include <math.h>

int main(void)
{
int b,d; /* 分母*/
int a,c; /* 分子*/
int sign,sign2,sign3,sign4;
int yakusu,yakusu2,yakusu3,yakusu4; /* 最大公約数*/

printf("分母= ");
scanf("%d",&b);

printf("分子= ");
scanf("%d",&a);

if(b==0){
printf("分母が0です。入力が誤っています。\n"); /*分母が0ならエラーとする*/
return 0;
}
if (a==0){
printf("分数1= 0\n"); /*分子が0のとき*/
}
else{
printf("分数1=%d|%d\n",a,b); /*一つ目の分数*/
}
printf("\n");

printf("分母= ");
scanf("%d",&d);

printf("分子= ");
scanf("%d",&c);

if(d==0){
printf("分母が0です。入力が誤っています。\n"); /*分母が0ならエラーとする*/
return 0;
}
if (c==0){
printf("分数2= 0\n"); /*分子が0のとき*/
}
else{
printf("分数2=%d|%d\n",c,d); /*二つ目の分数*/
}
printf("\n");

/* 足し算:a|b + c|d = (a*d + b*c) | (b*d) */
printf("足し算:%d|%d + %d|%d\n",a,b,c,d);

yakusu = gcd(abs(a*d + b*c),abs(b*d)); /*最大公約数を求める*/
sign = (a*d + b*c)/abs(a*d + b*c) * (b*d/abs(b*d));

if(sign * abs(a*d + b*c)/yakusu == 0){ /*分子が0となる時*/
printf("0\n");
}
if (abs(b*d)/ yakusu!= 1){
printf("既約分数は %d|%d\n" ,sign * abs(a*d + b*c)/yakusu , abs(b*d)/yakusu );
}
else{
printf("既約分数は %d\n" ,sign * abs(a*d + b*c)/yakusu ); /*分母が1の場合*/
}

printf("\n");

/* 引き算:a|b - c|d = (a*d - b*c) | (b*d) */
printf("引き算:%d|%d - %d|%d\n",a,b,c,d);

yakusu2 = gcd(abs(a*d - b*c),abs(b*d)); /*最大公約数を求める*/
sign2 = (a*d - b*c)/abs(a*d - b*c) * (b*d/abs(b*d));

if(sign2 * abs(a*d - b*c)/yakusu2 == 0){ /*分子が0となる時*/
printf("0\n");
}
if (abs(b*d)/ yakusu2!= 1){
printf("既約分数は %d|%d\n" ,sign2 * abs(a*d - b*c)/yakusu2 , abs(b*d)/yakusu2 );
}
else{
printf("既約分数は %d\n" ,sign2 * abs(a*d - b*c)/yakusu2 );
}

printf("\n");

/* 掛け算:a|b * c|d = (a*c) | (b*d) */
printf("掛け算:%d|%d * %d|%d\n",a,b,c,d);

yakusu3 = gcd(abs(a*c),abs(b*d)); /*最大公約数を求める*/
sign3 = (a*c)/abs(a*c) * (b*d/abs(b*d));

if(sign3 * abs(a*c)/yakusu3 == 0){ /*分子が0となる時*/
printf("0\n");
}
if (abs(b*d)/ yakusu3!= 1){
printf("既約分数は %d|%d\n" ,sign3 * abs(a*c)/yakusu3 , abs(b*d)/yakusu3 );
}
else{
printf("既約分数は %d\n" ,sign3 * abs(a*c)/yakusu3 ); /*分母が1の場合*/
}

printf("\n");

/* 割り算:a|b / c|d = (a*d) | (b*c) */
printf("割り算:%d|%d / %d|%d\n",a,b,c,d);

yakusu4 = gcd(abs(a*d),abs(b*c)); /*最大公約数を求める*/
sign4 = (a*d)/abs(a*d) * (b*c/abs(b*c));

if(sign4 * abs(a*d)/yakusu4 == 0){ /*分子が0となる時*/
printf("0\n");
}
if (abs(b*c)/ yakusu4!= 1){
printf("既約分数は %d|%d\n" ,sign4 * abs(a*d)/yakusu4 , abs(b*c)/yakusu4 );
}
else{
printf("既約分数は %d\n" ,sign4 * abs(a*d)/yakusu4 );/*分母が1の場合*/
}
return 0;
}
int gcd(int x,int y){
/* ユークリッド互除法*/
int z;
if( (x <= 0) || (y <= 0) ){
return -1;
}
z = x % y;
while (z != 0){
x = y;
y = z;
z = x % y;
}
return y;
}

>>大学の課題です。現在の状態は上記の通りです。このプログラムだと、答えの既約分数が0になると表示できなかったり、桁が大きい数で計算しようとすると値がおかしくなってしまいます。
どなたかプログラム改良にご助力願えないでしょうか?

<要求事項>
分数は、 例)1|3 のように表す。
1.分母がゼロの時はエラーとする。
2.除算において、除数がゼロの入力エラーに対しては、再入力するように促す。
3.以下範囲の整数(分子、分母にかかわらず)に対して、正しく計算できるようにする。
  -2147483648 ~ 2147483647

4.計算結果については,分母が1の時には分子のみ表示。分数がの時には0のみを表示。最終計算結果は既約分数にする。分数が負数の場合、-を分数の前に表示。

#include <stdio.h>
#include <math.h>

int ma...続きを読む

Aベストアンサー

No.2です
>オーバーフローというものは良く分からないのですが、アドバイスを踏まえて色々やってみます。

オーバーフローの概念だけ簡単に。
例えば、0~99までが入る変数型「sample」があったとします(ここでわかりやすく10進数でいきます)

sample a, b, c;
a = 99;
b = 99;
c = 0;
c = a * b;

という計算を行った場合、cの値はいくつになるでしょうか?
単純に「a * b」を計算すると「99 * 99 = 9801」となります。
しかし、sample型で扱うるの「0~99」です。
そのため100以上の値は「c」に格納することができず桁あふれ(オーバーフロー)が発生してしまいます。
このため、桁あふれ分はcに格納することができず「c = a * b」の結果「c」には桁あふれで残った(sample型に格納できる)分「1」が入ることになります。

注:あくまで概念の説明です。

Q既約分数の表示プログラム

(1)キーボードから,分子,分母に相当する整数2つを入力し,その既約分数を表示せよ。
(2)分母が1の時には,分子のみを表示する。
(3)分子と分母の符号が異なるときにのみ,-符号を表示する。
(4)分母がゼロの入力エラーに対しては、再入力するように促す。
(5)分子と分母の最大公約数も求めて表示する。
(6)また、正しく計算できる最大規約分数を示せ。

#include <stdio.h>
int main(void)
{
int a,b,i=1,x,y,z;

printf("分子=");/*分子の入力*/
scanf("%d",&a);

printf("分母=");/*分母の入力*/
scanf("%d",&b);

if(b==0)
{
printf("分母が0です。入力が誤っています。\n");
return 0;
}

if(b==1)
{
printf("既約分数は %d\n",a);
return 0;
}

while((i<=a)&&(i<=b))
{
if((a%i==0)&&(b%i==0))
{
x=i;i=i+1; /*xを上書きしていく*/
}
else
{
i=i+1;
}
}
printf("分子と分母の最大公約数=%d より\n",x);

y=a/x;
z=b/x;

printf("既約分数は %d/%d\n",y,z);

return 0;
}

大学の課題で出されたものです。(1)(2)(4)(5)はできたのですが、(3)と(6)の部分のやり方がいまいちよくわからなかったので質問しました。
どなたかご教授お願いできないでしょうか・・・。

(1)キーボードから,分子,分母に相当する整数2つを入力し,その既約分数を表示せよ。
(2)分母が1の時には,分子のみを表示する。
(3)分子と分母の符号が異なるときにのみ,-符号を表示する。
(4)分母がゼロの入力エラーに対しては、再入力するように促す。
(5)分子と分母の最大公約数も求めて表示する。
(6)また、正しく計算できる最大規約分数を示せ。

#include <stdio.h>
int main(void)
{
int a,b,i=1,x,y,z;

printf("分子=");/*分子の入力*/
scanf("%d",&a);

printf("分母=");/*分母の...続きを読む

Aベストアンサー

/*
暗に結構コード書いて下さい、って丸投げする質問者ってのも多いんだけど, 質問者さんはそうじゃないみたいで安心した。
きっとこんなコードも読めるんじゃないかな?
*/

#include <stdio.h>
#include <math.h>

/*
abs(x)はxの絶対値を返す関数で,math.hに定義されているんだよ。
もしこれがなくても自分で作れると思う。
*/

int main(void){

int denominator; /* 分母の絶対値 */
int numerator; /* 分子の絶対値 */

int sign;
int gcdofthetwo;

printf("denominator = ");
scanf("%d",&denominator);

printf("numerator = ");
scanf("%d",&numerator);

if(denominator==0){
printf("error : denominator should not be 0. program will exit.\n");
return 0;
}
if (numerator==0){
printf("0");
return 0;
}

gcdofthetwo = gcd(abs(numerator),abs(denominator));

/*
numerator * denominatorがオーバーフローするかも、っていうのが怖いから
(numerator * denominator) / (abs(numerator) * abs(denominator))
って書かずにそれぞれ分割しているんだ
*/

sign = (numerator / abs(numerator)) * (denominator / abs(denominator));

/* 前回のコードで忘れてた最大公約数*/

printf ("gcd:%d\n", gcdofthetwo);
if (abs(denominator) / gcdofthetwo != 1){
printf("answer:%d / %d\n" ,sign * abs(numerator) / gcdofthetwo , abs(denominator) / gcdofthetwo );
}else{
printf("answer:%d\n" ,sign * abs(numerator) / gcdofthetwo );
}
}

int gcd(int a,int b){
/* ユークリッド互除法 */
int retval;
if( (a <= 0) || (b <= 0) ){
return -1;
}

retval = a % b;
while (retval != 0){
a = b;
b = retval;
retval = a % b;
}

return b;

}

/*
暗に結構コード書いて下さい、って丸投げする質問者ってのも多いんだけど, 質問者さんはそうじゃないみたいで安心した。
きっとこんなコードも読めるんじゃないかな?
*/

#include <stdio.h>
#include <math.h>

/*
abs(x)はxの絶対値を返す関数で,math.hに定義されているんだよ。
もしこれがなくても自分で作れると思う。
*/

int main(void){

int denominator; /* 分母の絶対値 */
int numerator; /* 分子の絶対値 */

int sign;
int gcdofthetwo;

printf("denominator = ");
s...続きを読む

Q階乗のプログラム!!

階乗を求めるプログラムを作りたいのですが、どうも上手くいきません・・・。下のプログラムを作ってみたのですが、エラーになってしまいます。どなたか教えてください、お願いします!!

#include <stdio.h>

void main(void)
{
int i,j;
long a=1;

for (i=1; i<=10; i++){
for(j=1 ;j <=i; j++){
a=a*j;
}

printf("%3d %ld \n",i,a);
}
}

Aベストアンサー

これって 1~10までの階乗を出力するってプログラムですよね?
実際に階乗の計算を行ってるのは2つ目のforループで行っていると
思いますが、その前にaを初期化してない為に前に計算した階乗の値が
残ってしまってるからじゃないかと思います。

for (i=1; i<=10; i++){
 a = 1; //←初期化
 for(j=1 ;j <=i; j++){
  a=a*j;
 }
 printf("%3d %ld \n",i,a);
}

もしくは...
int num = 10; //求める階乗数
int a,i;
for(i=1,a=1;i<=num;i++,a=a*i) printf("%3d %ld \n",i,a);

こんな感じになると思います。

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
になります。

Q「割り算」 と 「分数の掛け算」

double型の変数にある値が代入されていて、
その数を半分にしようとしました。
演算部分を /2 としたらエラーが出てしまいました。
いろいろ試した結果、*0.5とすれば
ちゃんと計算されるようなのですが、
どうしてこのようなことが起こるのか、よくわかりません。
どなたか、ご教授ください。よろしくお願いします。

Aベストアンサー

>#define c 1
と言うことで、c は int の定数と判断されます

>double b;
で、格納する変数は double になっているのですが、

>b = c / 2;
の右辺を見ると、
定数のintである1を、定数のintである2で割っているため、この文の結果はintになってしまいます。
本来なら0.5となるべきところですが、/ の両辺が int の場合は、結果を int で返しますので、0.5 の実数部分の0が結果となるわけです。
これを右辺の b に代入するときに 暗黙の型変換にてdouble として入れているのですが、すでに切り捨てられてしまった小数部分は帰ってこないわけですね。

2.0 とするとうまくいくのは、
/ のどちらかが double の場合は、片方の int を暗黙に double に変換して double の結果を返すからですね。

演算式の、型変換について、もう一度ヘルプ等で調べて見てください。

Q2の累乗を計算するプログラムを作ったのですが・・・

C言語を用いて、2の累乗(2,4,8,16・・・)を
計算して表示するプログラムを

#include<stdio.h>
void main(void)
{
int i,s;
s=1;
for(i=1; i<=15; i++)
{
s=s*2;
printf("i=%2d s=%7d\n",s);
}
}

と打ち込んで実行したのですが、結果が

i= 1 s= 2
i= 2 s= 4
i= 3 s= 8
i= 4 s= 16
i= 5 s= 32
i= 6 s= 64
i= 7 s= 128
i= 8 s= 256
i= 9 s= 512
i=10 s= 1024
i=11 s= 2048
i=12 s= 4096
i=13 s= 8192
i=14 s= 16384
i=15 s= -32768

のように、2の15乗だけが負になってしまいました。
最初のintをdoubleやfloatに直して実行すればよいのかとも考えたのですが、
実行すると答えがすべて0になってしまい上手くいきませんでした。
どの部分がおかしいのでしょうか・・・;

C言語を用いて、2の累乗(2,4,8,16・・・)を
計算して表示するプログラムを

#include<stdio.h>
void main(void)
{
int i,s;
s=1;
for(i=1; i<=15; i++)
{
s=s*2;
printf("i=%2d s=%7d\n",s);
}
}

と打ち込んで実行したのですが、結果が

i= 1 s= 2
i= 2 s= 4
i= 3 s= 8
i= 4 s= 16
i= 5 s= 32
i= 6 s= 64
i= 7 s= 128
i= 8 s= 256
i= 9 s= 512
i=10 s= 1024
i=11 s= 2048
i=12 s= 4096
i=13 s= 8192
i=14 s= 16384
i=1...続きを読む

Aベストアンサー

No2です。

追記ですが、printfの変換指定子は型にあわせたものを使わなければ正しく表示されません。
long であれば %ld にしてください。

参考URL:http://ja.wikipedia.org/wiki/Printf

QC#にて別クラスの関数を使いたい

C#にて、別クラスの関数を使用する方法を教えてほしいです。

下記のような、構造体を受け取るメソッドを作りました。

*****************************
private struct MyPoint
{
public int x;
public int y;
}

private void proc1(MyPoint pt)
{
MessageBox.Show("座標:" ; pt.x + "," + pt.y + "実行結果");
}

private void button1_Click(object sender ,System.EventArgs e)
{

MyPoint pt;
pt.x = 10;
pt.y = 20;
proc(pt);
}
*****************************

別のフォームのクラスから、proc1を呼び出したいのですが、やり方がわかりません。
どうか、教えてください。

Aベストアンサー

同じ定義をしたとしても別の名前空間に書いた構造体は同一とはみなされません。

呼び出し先クラスでの構造体を private では無く、public で宣言して下さい。

呼び出し元では、

MyClass.MyPoint pt;

のようにして実体を作ります。

QC言語:2つの複素数(分数)の四則演算

下記のプログラムを組んでみて、発展として分数の形で複素数の四則演算のプログラムを作りたいのですが、どうにもややこしく、困っています。
よろしければ御指導よろしくお願いします。

/*
複素数を表す構造体
2つの複素数の四則演算
*/

#include <stdio.h>
#include <stdlib.h>

typedef struct {
double real; /* 実数部分 */
double imag; /* 虚数部分 */
}COMPLEX;

/* 二つの複素数の和を返す */
COMPLEX comp_add(COMPLEX x, COMPLEX y)
{
COMPLEX tmp;

tmp.real = x.real + y.real; /* 実数部分の和 */
tmp.imag = x.imag + y.imag; /* 虚数部分の和 */

return (tmp);
}

/* 二つの複素数の差を返す */
COMPLEX comp_sub(COMPLEX x, COMPLEX y)
{
COMPLEX tmp;

tmp.real = x.real - y.real; /* 実数部分の差 */
tmp.imag = x.imag - y.imag; /* 虚数部分の差 */

return (tmp);
}


/* 二つの複素数の積を返す */
COMPLEX comp_mul(COMPLEX x, COMPLEX y)
{
COMPLEX tmp;

tmp.real = (x.real * y.real) - (x.imag * y.imag);
tmp.imag = (x.real * y.imag) + (y.real * x.imag);

return (tmp);
}

/* 二つの複素数の商を返す */
COMPLEX comp_div(COMPLEX x, COMPLEX y)
{
COMPLEX tmp;

tmp.real =(x.real*y.real+x.imag*y.imag)/(y.real*y.real+y.imag*y.imag);
tmp.imag = (x.imag*y.real-x.real*y.imag)/(y.real*y.real+y.imag*y.imag);
return (tmp);
}

int main( int argc, char **argv )
{
COMPLEX a, b, c;

a.real = strtod( argv[1], NULL );
a.imag = strtod( argv[2], NULL );
b.real = strtod( argv[3], NULL );
b.imag = strtod( argv[4], NULL );

c = comp_add(a, b); /* 複素数の和を c に代入 */

printf( "(%f+j%f)*(%f+j%f)=(%3.1lf+j%3.1lf)\n",
a.real,a.imag,b.real,b.imag,c.real,c.imag );

c = comp_sub(a, b); /* 複素数の差を c に代入 */

printf( "(%f+j%f)*(%f+j%f)=(%3.1lf+j%3.1lf)\n",
a.real,a.imag,b.real,b.imag,c.real,c.imag );

c = comp_mul(a, b); /* 複素数の積を c に代入 */

printf( "(%f+j%f)+(%f+j%f)=(%3.1lf+j%3.1lf)\n",
a.real,a.imag,b.real,b.imag,c.real,c.imag );

c = comp_div(a, b); /* 複素数の商を c に代入 */

printf( "(%f+j%f)+(%f+j%f)=(%3.1lf+j%3.1lf)\n",
a.real,a.imag,b.real,b.imag,c.real,c.imag );

return( 0 );
}

下記のプログラムを組んでみて、発展として分数の形で複素数の四則演算のプログラムを作りたいのですが、どうにもややこしく、困っています。
よろしければ御指導よろしくお願いします。

/*
複素数を表す構造体
2つの複素数の四則演算
*/

#include <stdio.h>
#include <stdlib.h>

typedef struct {
double real; /* 実数部分 */
double imag; /* 虚数部分 */
}COMPLEX;

/* 二つの複素数の和を返す */
COMPLEX comp_add(COMPLEX x, COMPLEX y)
{
COMPLEX tmp;

tmp.real = x.real ...続きを読む

Aベストアンサー

分数でのプログラムができているのなら……



実数部と虚数部がそれぞれ分数になれば良いのですよね?

なら、

typedef struct {
int denominator;
int numerator;
}FRACTION;

typedef struct {
FRACTION real; /* 実数部分 */
FRACTION imag; /* 虚数部分 */
}COMPLEX;

で、

COMPLEX comp_add(COMPLEX x, COMPLEX y)
{
COMPLEX tmp;

tmp.real = x.real + y.real; /* 実数部分の和 */
tmp.imag = x.imag + y.imag; /* 虚数部分の和 */

return (tmp);
}



frac_add( FRACTION x, FRACTION y )


COMPLEX comp_add(COMPLEX x, COMPLEX y)
{
COMPLEX tmp;

tmp.real = frac_add(x.real, y.real); /* 実数部分の和 */
tmp.imag = frac_add(x.imag, y.imag); /* 虚数部分の和 */

return (tmp);
}

でできあがり。
他の演算も同じ(ごめん、未確認)

分数でのプログラムができているのなら……



実数部と虚数部がそれぞれ分数になれば良いのですよね?

なら、

typedef struct {
int denominator;
int numerator;
}FRACTION;

typedef struct {
FRACTION real; /* 実数部分 */
FRACTION imag; /* 虚数部分 */
}COMPLEX;

で、

COMPLEX comp_add(COMPLEX x, COMPLEX y)
{
COMPLEX tmp;

tmp.real = x.real + y.real; /* 実数部分の和 */
tmp.imag = x.imag + y.imag; /* 虚数部分の和 */

return (tmp);
}



frac_add( FRACTION x, FRACTION y )


COMPLEX ...続きを読む


人気Q&Aランキング

おすすめ情報