アプリ版:「スタンプのみでお礼する」機能のリリースについて

C言語を使っているのですが、32ビット版のgccでコンパイルして実行できるファイルが、64ビット版のgccだと違う結果が出てきます。どちらのgccでも使える汎用性のあるファイルは書けないのでしょうか?
因みにstdio.h、math.h、stdlib.hのライブラリを使っていて、倍精度(double)と整数(int)を使っています。配列は宣言時に「*a」とでも宣言して、mallocで作っています。
漠然とした質問ですがよろしくお願いします。

A 回答 (10件)

ごめ、ソースみてわかる世界じゃないや(笑


むしろ、書いた人すごいなぁ。

LinuxならGDBが動くはずなので
地道にトレースして値のおかしくなる場所を特定して
その結果から推測するしかないですね。

google検索したら日本語マニュアルあったのでぺたり
GDB マニュアル
http://flex.ee.uec.ac.jp/texi/gdb-j/gdb-j_toc.html
    • good
    • 0

「doubleのフォーマットが32bit版と64bit版で違う」ってことは当然あってもいいけど, 今どき普通はハードウェアの都合に合わせるだろうから「同じハードウェアならたぶん同じだろう」とは推測できると思います>#9. もちろん「推測」であって「断定」ではありませんが.


以下余談:
物理量を直接書くことは当然知ってるけど (というより「観測値なら直接書くしかない」はずだ), 「8.54×10^-7」を「8.54*pow(10.0, -7,0)」って書くのはいかがなものだろう. 普通はしれっと「8,54e-7」ですますものじゃないかねぇ. そうすれば Spon_HH は「定数行列*T_0」となるし, この「定数行列」そのものは (少なくとも現状はで) static const な配列で書けるのでお得.
さらにいうと例えば z_HHplus を計算するところは関数として切り出せばいい (無駄な条件判断は消す) し,
if(n_H_micro != NULL){
free(n_H_micro);
n_H_micro=NULL;
}
も NULL かどうかの比較は無駄.
もちろん malloc を使ったところで「訳の分からないところで違う領域に上書きされる」現象が回避されるわけではないです.
    • good
    • 0
この回答へのお礼

すみません。そのような書き方があるとは知りませんでした。

お礼日時:2009/05/13 16:57

こりゃ確かにすごい。


で、こういう場合の定石として、
「問題が発生する最小限のコードに絞り込む」
ってのを地味にやるしかないかと。

可能性として考えられるのは、int<->doubleの変換で、intが32bitか64bitかで違いが生じるので、そのからみとか。でも、すべての計算をきっちりdoubleでやっていれば、この問題は起こらない。

あと、doubleのフォーマットが32bit版と64bit版で違う・・ってことはある話なのかなぁ。
    • good
    • 0

これを人間が書いたんだとしたら確かに「すごい」けど>#7, その努力は別のところに使うべきじゃなかったかなぁ....


ene_HA=(double *)malloc(sizeof(double)*6);
とか
Spon_HH[21][0]=8.54*pow(10.0,-7.0);
とか, 人間が書いたとは到底信じられない.
まずは「人間が読めるコード」に修正すべきなのかもしれんが, こんなの触りたくない. 持って来たら突っかえすよ, こんなの.
ま, 他人の協力が得られないことを前提に, #7 で挙げられている gdb を使って自力でなんとかしてください. gcc でコンパイルするときに -g オプションを付けてくださいね.

この回答への補足

確かに6個の配列をmallocで作るのはやり過ぎかもしれませんが、メモリを確保しないと訳の分からないところで違う領域に上書きされることがあったので怖いんです。Spon_HHについては物理量を実験値、理論値からダイレクトに代入することがあることを知って下さい。

補足日時:2009/05/13 00:58
    • good
    • 0

ごくごく普通に書けば、32ビットでも64ビットでも同じく動くはず。


結果が異なるというのは、やはり変な書き方をしていると思われるわけで、ソースを提示するのが一番です。

この回答への補足

ソースを置きましたのでURLをお報せします。
遅くなって澄みません。
http://bechi0226.web.fc2.com/yotsuba.html

補足日時:2009/05/12 19:54
    • good
    • 0

#2 への 補足にあるけれどmallocのサイズ不正でNaNになるのかな?


0除算ならあるかもしれないけれど。。

まぁ、ソースコードと結果を見ないことには予想も立ちませんね。

結果が違うとだけいわれても、
32bitの時、おかしい
64bitの時、おかしい
両方、おかしい
と三通りのあるわけで、ソースコードもなしで、答えなんか出ません。
    • good
    • 0

って~か, malloc を使うときに忘れずに stdlib.h をインクルードすればいいだけじゃないのかなぁ>#3.


普通, sizeof を使わずに malloc ってあんまりしないよね.
要するに「きちんと規格に従って書く」間は問題なし.
    • good
    • 0

回答1に引き続き。


メモリ確保にmallocをお使いとのこと。
「malloc 64bit」で検索すると分かるとおり、64bit環境でのmallocの使い方で悩んでいるケースは結構あります。
mallocは型指定せずにメモリサイズを自分で指定しないといけないため、32bitのときと定義サイズの違うデータ型で使おうとすると正常に動作しません。
ここ↓の回答1が参考になります
http://okwave.jp/qa1683511.html
sizeof(データ型)で抽象的に指定してやればいいのですが、
いずれにしても、malloc ~ freeはプログラム初心者には難しい概念だと思われます。

gccをお使いでしたら、CではなくC++言語にして、new ~ deleteでデータ型を指定したメモリ確保をすれば、その部分では悩まずに済むはずです。

この回答への補足

すみません・・・size_tを使うのは分かるのですが、応用として2次元配列を作るのにはどうしたら良いのかが分かりません。

補足日時:2009/05/12 22:35
    • good
    • 0

こんなソースを書いたところ、こんな風に結果が異なった、


というような、具体的な質問ができますか?

この回答への補足

2次元配列で行列を作ってから逆行列を計算しているとnanが出てきます。

補足日時:2009/05/11 17:25
    • good
    • 1

ポインタのサイズが違います。



32bit環境は、メモリのアドレスを指定できる数が、2の32乗≒43億。
つまり、理論上約4ギガバイトのメモリにアドレスを割り振ることができます。
32bitウィンドウズでのメモリ上限が4GBというのはこのためです。

メモリの「ここ」という情報を格納するポインタ変数において、それを表現するのに、32bit環境の場合、4バイトになります。
64ビットの場合、8バイト。

C/C++をgccでコンパイルした場合、各環境のCPUが直接読めるネイティヴコードが生成されるゆえ、32ビット用、64ビット用と明確に違うバイナリが出てきます。

>どちらのgccでも使える汎用性のあるファイルは書けないのでしょうか?
自分で書くソースは共通のもので大丈夫なはずです。
コンパイラ(gcc)が頑張ってそれぞれに合わせて翻訳するだけなので。

「どちらの環境でも使える汎用性のある実行ファイルはできないか?」
という意味の質問でしたら、
Windowsの場合に限ると、64bitのほうには32bitのプログラムを実行するエミュレーターが搭載されているので、32bitのほうでコンパイルすればどちらの環境でもOKになります。
その他のOSの場合、それぞれ違いますが、エミュレーターのような特別な仕組みが入っていない限り、基本的には不可です。

OSを問わず、環境を問わず実行できるものを目指すのでしたら、Javaのほうが良いと思います。

この回答への補足

詳しいご説明ありがとうございます。
違いがよく分かりました。
OSはUNIXの多分Redhatです(管理者ではないので過去の記憶です)。
重ねての質問になりますが、64ビット用に書き換えるにはどうしたら
良いのでしょうか?
あと、Javaは学術計算に使えますか?

補足日時:2009/05/11 18:24
    • good
    • 0

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