• ベストアンサー

float 型のデータのメモリ上での理解の仕方

詳しい方教えていただけると助かります。 OS:LINUX コンパイラ:GCC 以下のプログラムを実行し、結果ファイルの test.txt を od で見ると 期待した通りの結果になりません。long 型や、short型は期待通りの結果になるのですが。  どういうロジックを経て、以下のような数値になっているのでしょうか?変換ロジック等がわかるとありがたいのですが・・・。 #include <stdio.h> main() { float f; char line[4]; FILE *fp; f = 1234; memcpy(&line[0], &f, sizeof(float)); fp = fopen("test.txt", "w"); fputc(line[0], fp); fputc(line[1], fp); fputc(line[2], fp); fputc(line[3], fp); fclose(fp); } test.txt 内容を od した結果の数値 0000 c000 8c29 4167

質問者が選んだベストアンサー

  • ベストアンサー
  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.5

こちらの環境では、以下のようになりました。 od -t x1 test.txtの結果が 00 40 9a 44 となります。 od -t x test.txt なら 449a4000 です。 od test.txtなら 040000 042232 です。 odコマンドは具体的には、どのようなオプションを指定されてますか。 実行環境は以下の通りです。 CPU INTEL系 OS CentOS release 4.4 gcc 3.4.6

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (5)

noname#233826
noname#233826
回答No.6

この処理の結果、8バイトのファイルができているということでしょうか。fputc() は1バイト出力すると思いますので、4バイトのファイルができているはずですが……。 一度、test.txt を削除し、コンパイルもやり直してから実行しても同じ結果でしょうか。"od -t x1 test.txt" の結果を見たいですね。

全文を見る
すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

#1 ですが, この結果が本当なら IEEE754 を見ても幸せにはなれないです. すみません. IEEE754 なら 1234 は 449a4000 になります. とりあえずお使いの CPU と gcc のバージョンを示してもらえませんか?

全文を見る
すると、全ての回答が全文表示されます。
  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.3

たぶん、float型の1234.0という数値は、メモリに 41678c29c0000000 と格納していると思うのです。 odでそういう出力結果を得るのは、エンディアンネスが関係していると思うのです。 お使いのマシンは、たぶんリトルエンディアンだろうと思うのです。 エンディアンネスやリトルエンディアン(ビッグエンディアンっていうのもあります)について よくわからなければ、GoogleやWikipediaあたりで調べてみればよいと思うのです。

motodani
質問者

お礼

od -x test.txt としていたので、並びがおかしかったようです。 ありがとでした。

全文を見る
すると、全ての回答が全文表示されます。
  • arain
  • ベストアンサー率27% (292/1049)
回答No.2

確認手順として、fputc()の第一引数にcharを入れている時点でもおかしくなる。 fputc()の第一引数はint。 charなのに、0x00~0xFF以上の値が出力されたらおかしいと思いませんか?

motodani
質問者

お礼

大変失礼しました。色々試していたので、質問の記事の切り貼りに失敗してしまっていました。 ただ、fputc()の第一引数は int 型ですが、上記プログラムの動作には問題ないとおもいます。od の結果を double型のテスト結果を貼り付けてしまっていたのです(汗)大変失礼しました。

全文を見る
すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

多分, IEEE754 を調べると幸せになれると思う.

motodani
質問者

お礼

職場から質問は書けたのですが、お礼を書こうとすると、ブロックがかかってしまい、返事が遅れてしまいました。 そうか、まず、IEEE754が前提条件としてあったわけですね。ありがとです。  自分の書いた最初の記事が不正確なものになってしまっていたので迷惑をかけたみたいですいません(汗)  大変助かりました、ありがとでした。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • VS2010でのint float数値について

    int MAX =10; for(int i=0; i<MAX-1; i++) {   float A;   A = i / ( MAX-1 );   float B;   B = i / ( MAX-1.0f );   // A or Bを使って処理 } A、Bの数値は変わるのでしょうか? この後のコードで、 Aの場合、望んだ結果が出なかったのですが Bの場合ですと期待通りの結果が出ました… VisualStudio2010 C/C++ Win7 64bitです。 よろしくお願いします。

  • floatの計算

    c言語、32bit環境において float f = (float)99 / (float)10; のコードでfの期待値は9.9なのですが、実際は9.89999996となります。 99から9.9を導くにはどのようにコーディングすれば良いでしょうか?

  • Rubyでの比較 (Float)

    Ruby初心者です。 簡単な比較を行いたいんですが、エラーが出てしまいます。 ファイルに ex. ruby_test.rb 0 12.3243 32 112.233 0.33123 とあり、このファイルを読み込んで比較しようとしています。 以下のコードで比較しようとしました。 ----------------------------------------------------------- fp = open("c:/ruby_test.txt") aaa = Array.new while line2 = fp.gets line2.chomp! bbb = line2.split(/\t/) aaa << bbb[1] if ( bbb[2] < 1.301029996 ) then       ※11行目 print "aaa\n" elsif ( bbb[2] < 8.164943898 ) then print "bbb\n" elsif ( bbb[2] >= 8.164943898 ) then print "ccc\n" end end fp.close -------------------------------------------- 実行すると ( ※ **** はファイル名 ) C:/ruby/*******.rb:11:in'<': comparison of String with Float failed (Argument Error) というエラーが出ます。 比較する  bbb[2] < 1.301029996  を bbb[2] < "1.301029996" すれば 動きますが、これでは文字列としての比較になってしまいますよね?? Floatは数字として比較するにはどうしたらよいのでしょうか? どなたか宜しくお願いします。

  • doubleとfloatについて

    #include <stdio.h> int main() { float height,weight; printf("身長と体重を入力してください。\n"); scanf("%f",&height); scanf("%f",&weight); printf("身長は%fセンチ:体重は%fキロです。\n",height,weight); return 0; } 上記のようなプログラムを作って、身長には175.1体重には56.1という入力を行なって実行したところ、 身長は175.100006センチ:体重は56.099998キロです。 という結果が返ってきました。 heightとweightをdouble型で宣言したところ(もちろんscanf文の変換仕様は%lfにしています。)、結果は 身長は175.100000センチ:体重は56.100000キロです。 と私が、期待していたものが返ってきました。なぜfloat型だと期待通りの結果が返ってこないのでしょうか?ご教授お願い致します。

  • 関数プロトタイプ無しで、引数が float の場合

    またまた float がらみでつまずています。 以下のようなソース(2つのファイルに分割されています)を実行すると、 f = 2.000000 と表示されました。 test1.c で、func() のプロトタイプを書いてないのが諸悪の根源だとは思うのですが(警告もでています)プロトタイプの役割は、 ・引数の型の不整合がないようにする ・必要に応じて、仮引数と実引数の型変換を発生させる だと思います。 このソースでは(たまたまですが)引数の型もあっているので、正常に実行できそうな気がするのですが、なぜ、結果がおかしくなってしまうのでしょうか。 確かに、プロトタイプがないのは好ましくはないですが。 test1.c に、int func(float f); を追加したときには、確かに f = 0.010000 と表示されます。 また、f と func() の引数を double にしたときには、プロトタイプがなくても、正常に実行されます。 ----- test1.c ------------- int main() { float f = 0.01; func(f); return 0; } ----- test2.c ------------- #include <stdio.h> int func(float f) { printf("f = %f", f); return 0; } ----- ここまで ------------

  • fwriteについて

    #include<stdio.h> int main(void) { FILE* fp; double f[5]={ 3.1, 2.9, 4.2, 3.7, 4.0}; double data; fp=fopen("test.txt","wb"); if(fp==NULL) { printf("text.txtが開けません。"); return 0; } fwrite(f,sizeof(double),5,fp); fclose(fp); }と入力したのでが、test.txtファイルを見ると 文字化けがでて、数値がわかりません。 数値もテキストファイルに出力する方法があったらご教授よろしくお願いします。できたらなぜこのようなことが起きたのか教えてくださるとうれしいです。

  • テキスト→配列化→ソートをしたいのですが

    テキストファイル:test.txt 内容:カンマで区切られた数値で最大20個 を読み込んで配列に組み込んでその配列を昇順ソートする。 と言うC言語の課題が内定先の企業より出題されたのですが 今まではC#やデータベース中心だったので 全く解らず困っています。 #include <stdio.h> int main(void) { /* ファイルポインタ */ FILE *fp; int f; fp = fopen( "test.txt", "r" ); if( fp == NULL ) { puts( "test.txtが開けません" ); return 1; } while( 1 ) { f = fgetc( fp ); if( ferror( fp ) ) { /* fgetc関数に対するエラーチェック */ puts( "読み込み中にエラーが発生しました" ); fclose( fp ); return 1; } else if( feof( fp ) ) { break; } printf( "%c", f ); } printf( "\n" ); fclose( fp ); return 0; } } 他のサイト等を参考にファイルを読み込むまでは出来たのですが そこから先が全くわかりません・・・・orz どうかよろしくお願いしますm(_ _)m

  • float型での計算での質問

    下記コードについて、1から10までの値を0.1刻みで順に表示するプログラムですが、結果がこのようになりません。 表示結果 2.700000 までは0.1刻みなのですが、2.800000 と表示されるはずが 2.799999 となってしまいます。 コンパイラーは Borland C++ 5.5.1 for Win32 です。 なぜこのようになるのか教えてください。 int main(void) { float f; for(f=1; f<10.1; f=f + 0.1) printf("%f\n",f); return 0; }

  • C言語のfloat型変数の値代入と表示について

    float型変数の値代入と表示について質問があります。 #include <stdio.h> int main(void) {  float flVal = 50.456;  printf("float型変数:%f", flVal);  return 0; } 上記を実行すると、「float型変数:50.456001」と表示されました。 また、float flVal = 50.1; と変えて実行すると、「float型変数:50.099998」と表示されました。 それぞれ期待していた結果は、 「float型変数:50.456000」、「float型変数:50.100000」だったのですが 代入した値と結果が微妙に異なる理由は何でしょうか。よろしくお願いします。

  • 複数のC言語プログラムが,一つのファイルに書き込み

    2つのプログラムで一つのテキストファイルに書き込むと,エラーが起きてプログラムが停止するんじゃないかなーと思っていましたが,起きませんでした. 検証結果がまた謎であり,知識も足りず,解釈ができないので,力を貸してください. 動作環境は先に言いますと,win7のVC++2010コンパイラです. ---プログラムA FILE *fp = fopen("test.txt", "w"); while(true){ fputc('@', fp); } fclose(fp); ---end ---プログラムB FILE *fp = fopen("test.txt", "w"); while(true){ fputc('_', fp); } fclose(fp); ---end (1)Aを走らせる・・・ファイルには@がたくさん出力されていると思われる. (2)Bを走らせる・・・Aがファイルを操作しているんだから,fopen関数でエラーが出ると思ったが,出なかった.稼働してしまったので,fopenの書き込みモードによってファイルは真っ新になり,「_」が先頭から羅列され始めただろう. (3)Bを停止する・・・「_」の出力は止まっただろうが,プログラムAの方は今何をしているんだろう.元気かな (4)Aを停止する 出力結果すなわちtest.txtの内容は次のようだった. ___________・・・______[NULL][NULL][NULL]・・・[NULL][NULL]@@@@@@@・・・@@@@@@@ これについて質問があります. Q.NULLが出力されているのはどうしてか. Q.AはBが書き込んでいる間,待っていたようだ(Bを停止した後で待ってましたと言わんばかりに@が書き込まれた形跡があるから)が,これは仕様なのか.エラーが出るということを気にする必要はないのか. 余談,予備知識大歓迎です.よろしくお願い致します.

このQ&Aのポイント
  • 美少女の演奏だから感動できるんですか
  • 演奏家にとって容姿の重要性について考えてみましょう。クラシック音楽部門においても容姿に優れた人が多いことは事実です。
  • 826askaさんの演奏に感動できるのは彼女の演奏技術が優れているからですが、美少女だからこそ多くの人を感動させるのだと思います。
回答を見る