こんにちは。
現在、Visual Studio 2005を使用してC#のプログラムを作成しています。

32bitの浮動小数点のデータを表示しようとしているのですがうまくいきません。
具体的な例としては
0x42F6E9E0  → 123.456789
0x4476E9E0  → 987.654321
のように変換した結果を表したいと考えています。

c言語では

int main()
{
int h = 0x42F6E9D5;
float f;
f = *(float *)(&h);
return 0;
}

のようにすればfで値(123.45678)が取得できたのですが、
これと同じ事をC#ではどのように書くのでしょうか?

ポインタを含んだキャストのやり方がわかりません。

以上よろしくお願い致します。

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

A 回答 (4件)

C#は基本的にポインタなぞない(できるかもしれないが普通は使わない)


こういう風に書きます

namespace Q4974299
{
class Q4974299A
{
public static void Main(string[] args)
{
int i = 0x42F6E9D5;
System.Console.WriteLine(System.BitConverter.ToSingle(System.BitConverter.GetBytes(i),0)); //123.4567
System.Console.ReadKey(true); //何かキーが押されるまで待機
}
}
}
    • good
    • 0
この回答へのお礼

ありがとうございます。
便利なメソッドがあるんですね。
MSDNで調べてみます。

お礼日時:2009/05/20 12:16

誤差とかそういう問題じゃない。


処理系の浮動小数点数の表現方式が期待している方式と異なっていれば
期待しているのとは全く異なる値になる。
    • good
    • 0
この回答へのお礼

ご指摘ありがとうございました。
なるほどそういうことでしたか。
確かにその通りですね。
浮動小数点について確認してみます。

お礼日時:2009/05/20 23:12

念のためですが, 「C言語」ではそのコードで期待した値が得られることを保証していません.

    • good
    • 0
この回答へのお礼

ご指摘ありがとうございます。
実際に誤差が生じるとしたらどの程度になるのでしょうか?

お礼日時:2009/05/20 15:39

基本的に、No1さんがおっしゃるようにC#ではポインタという概念はありません。


でもどうしてもポインタを使いたい場合があったりします。

たとえば、画像処理プログラムなどで、
読み込んだ画像のピクセルデータを変換したいとか(RGB要素を入れ換えるとか)
だと、GetPixelメソッドなりを使用するのが一般的かもしれません。
ただ、実はこの処理が非常に遅かったりします。
そこで、読み込んだ画像データをメモリ上で操作すれば高速化します。
この時にポインタを使用します。

C#でポインタを使用するためには、unsafeコードで記述します。
参考サイト
http://www.atmarkit.co.jp/fdotnet/csharp_abc/csh …

unsafe
{
unsafeコード内ではポインタが使用できます。
}

今回の質問の内容をunsafeコードで記述すると…。
int i = 0x42F6E9D5;
unsafe
{
int* ip = &i;
float* fp = (float*)ip;
float f = *fp;
}

これで、float型fの中身はお望みの値になってるかと思います。

(※)unsafeコードを記述するにはプロジェクトプロパティのビルド項目で、
   アンセーフコードの許可を指定してください。
    • good
    • 0
この回答へのお礼

ありがとうございます。
自分はC言語から入っていったのでこちらの記述はしっくりきます。
sonata1229さんのおっしゃる通り、用途次第で使い分ける必要がありそうですね。
参考になります。

お礼日時:2009/05/20 12:19

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

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

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

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

Q浮動小数点の正規化の必要性について

 浮動小数点の正規化の必要性について教えてください。

 浮動小数点で数を表す際に、正規化は必ずしも必要なもの(行わなければならないもの)なのでしょうか?
 
 また浮動小数点の正規化のルールとして、
 2進数か16進数に変換したとき
 「指数部を調整して、仮数部の最上位けたを“0以外にする”」というルールがあるようなのですが、何故「指数部を調整して、仮数部の最上位けたを“0以外にする”」という処理が必要となるのでしょうか?

Aベストアンサー

回答ANo.1への補足,に対して。

浮動小数点数における正規化の必要性を説明するのに2進数を持ち出す必要はありません。10進数のままでも説明できます。

一例としてANo.2で挙げられた仮数部長で説明すると,2進数で23bitということは,10進数の桁に換算するとlog10(2^23)=約7桁となります。

もし仮に,仮数部・指数部ともに10進数で記録する浮動小数点数があると仮定し,さらにその仮数部長が7桁だと仮定するならば。

>[10進数]
>0.0000000000123456789012345678901234567890

という数は,7桁の仮数部長では正確に表現できませんから,丸め誤差が生じます。
同じ数値であっても,仮数と指数を組み合わせれば無限のパターンの表現ができます。今回の場合は,次の7つのパターンのうちのいずれかの表現形式を積極的に採用することになるでしょう。

(0.1234567)×10の-10乗
(0.0123456)×10の-9乗
(0.0012345)×10の-8乗
(0.0001234)×10の-7乗
(0.0000123)×10の-6乗
(0.0000012)×10の-5乗
(0.0000001)×10の-4乗

上記はすべて同じ数値なのですが,では「限られたビット数の中に少しでも多くの情報を詰め込」んでいるのはどれでしょう? 仮数部の長さ(=有効桁数)をムダにしないで,同じ数値であってもより精度の高い数として表現できているのはどのパターンでしょう?

その答えは「指数部を調整して、仮数部の最上位けたを“0以外にする”」というルールにのっとった,(0.1234567)×10の-10乗 であるのは明らかではないですか。

追伸.
ANo.2では IEEE754の「隠れ"1"表現」にまで触れているのですが,今回の問いに回答するだけならばそれは不要だと判断しましたので,省いてあります。

回答ANo.1への補足,に対して。

浮動小数点数における正規化の必要性を説明するのに2進数を持ち出す必要はありません。10進数のままでも説明できます。

一例としてANo.2で挙げられた仮数部長で説明すると,2進数で23bitということは,10進数の桁に換算するとlog10(2^23)=約7桁となります。

もし仮に,仮数部・指数部ともに10進数で記録する浮動小数点数があると仮定し,さらにその仮数部長が7桁だと仮定するならば。

>[10進数]
>0.0000000000123456789012345678901234567890

という数は,7...続きを読む

Qfmlのconfig.phで使う、q{~};やq#~#;q%~%;は全て同じ意味?

メーリングリストのカスタマイズをしていて、ネット上で情報を集めているのですがどうしても分からないところがあります。 fml 4.0
$SMTP_OPEN_HOOKなどのHOOKを行うときに、q{~};やq#~#;q%~%を同じサイトであっても使い分けているようで、SMTP_OPEN_HOOKの時には =q{~}; を、START_HOOKでは =q#~#; のようになっています。
プログラムというもの自体触ったことはないのですが、一応記号が変わっているだけで中身は同じなのかなと思っています。
実際のところ別物でしょうか?

fmlとqで検索をかけても情報が引っかかりませんし、fmlとq#などとしてもfmlでしか検索できないみたいで八方ふさがりです。
よろしくお願いします。

Aベストアンサー

fmlはPerlという言語で書かれています。これはPerlの記法の問題です。
どれも意味は同じです。違うのは、
・囲まれた内部で使われて無い記号を使って囲むため
・書いた人が違う
・気分によって使い分け?

Q浮動小数点の正規化方法について

基本情報処理技術者試験を20日に受けます。勉強不足で困っています。どなたか教えてください。
問題「数値を16ビットの浮動小数点表示法で表現する。10進数0.375を正規化せよ:ここでの正規化は仮数部の有効数字よりも上位の0がなくなるように指数部を調節する操作である。」 
答え「0111111000000000」 最初の1ビットが仮数部の符号、次の4ビットが2のべき乗の指数部で負数は2の補数、残りの11ビットが仮数部の絶対値
となっています。
0.375を2進数に直すところまではわかったのですが、次の正規化がよくわかりません。よろしくお願いいたします。

Aベストアンサー

10進数の0.375は、2進数は0.011です。
使用できるビット数が指数部、仮数部ともに限りがありますので、0.011をそのまま表記すると、仮数部が011となります。この先頭の"0"は別になくてもいいですよね?その分を指数部であらわせば、仮数部の桁を一桁稼ぐことができます。つまり、より正確な値を保持できることになります。これが正規化する意義です。

仮数部を(2倍)したわけですから、指数部は(1/2倍)します。よって指数部は(-1)です。負数ですから2の補数で表示すると1111(4ビット)になります。

浮動小数点表示は、正規化が絡んできますので、場合によっては情報落ちや桁落ちなどが発生します。このあたりを、再確認して試験に臨んでください。

QGASの.align 4,0x90の0x90の意味

Cソースをアセンブリしたとき、.align 4,0x90とでるのですが、.align 4,0x90の0x90はどういう意味ですか。align 4+NOPという意味ですか。それとも4Bを0x90で埋めろと意味ですか。どちらでしょう。

Aベストアンサー

困ったときはまずマニュアルを読む.

参考URL:https://sourceware.org/binutils/docs-2.24/as/Align.html#Align

Q浮動小数点(エクセス64形式)、倍精度(64bit)仮数部は何bit?

タイトルの通り、エクセス64形式の倍精度(64bit)のときの指数部、仮数部がそれぞれ何bitなのかわかりません。IEEE形式のものと、単精度(32bit)のものは調べられたのですが・・・
(421C 1999 9999 99A0)
等、いくつかエクセス64形式で表記された値があり、これを実数でいくつになるか確認するためです。

よろしくお願いします。

Aベストアンサー

参考URLによると
1,7,56
みたいですね

参考URL:http://cs.maritime.kobe-u.ac.jp/waka/course/ip2004s/IPnt03b.pdf

QVS2010での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です。
よろしくお願いします。

Aベストアンサー

Aの方は、全て0になりそうですが。どうでした?

型の違う数値演算をしているときは、
なるべく精度の高いものに合わせて計算されます。

内部的にキャストが行われているので、予めこれを読んで数式を作る必要があります。


Aの例、i=1のとき
---------------------------------------
float A;

A = (float) ( 1/9 ); // i=1のときの計算
---------------------------------------
これだと先に括弧の中は(int同士の計算ですから少数以下は切り捨てられて)0になります。

ところが演算の中にintよりも精度の高い型が含まれていると、関連する数値は全て
格上げされて(キャスト)計算されます。

double > float > int みたいな感じで、左のほうが精度が高い。
混在した時は、一番精度の高いものに変換(キャスト)してから演算が行われます。

ですので、Bの例は以下のような変換が行われています
---------------------------------------
float B;

B = (float) ( (float) 1 / 9.0f ) // i=1のときの計算
---------------------------------------

これならば小数点以下も結果に残ります。
私が書き足した(float)の部分をコンパイラが勝手にやります。

例えば以下の計算結果は0になりますが、
---------------------------------------
int b;

b = 1 / 4.0; // 4.0 が暗黙に doubleでの演算を求めている
---------------------------------------
これは一回doubleで演算し、0.25と言う答えを得てから、
intにキャストする段階で小数点以下が捨てられます。
(処理系依存ですが、考え方はこれが基本)


以下も同様のキャストが暗黙に行われる
---------------------------------------
int b;

b = 1 + 4.0; // 4.0 が暗黙に doubleでの演算を求めている
---------------------------------------
答えは5になりますが、一度内部的に 1.0 + 4.0が演算されています。
(処理系依存ですが、考え方はこれが基本)

B = i / (MAX - 1.0f );

ですと、MAXは整数ですが、1.0fが暗黙にfloatへのキャストを求めています。
ですので、(MAX - 1.0f)の戻り値の型がfloatになっています。
つまり、

B = i / 9.0f;

と透過になり、分母がfloatですので、iが整数でもfloatへのキャストが求められ、
結果的に、全てがfloatで演算されます。

以上ご参考になれば。

Aの方は、全て0になりそうですが。どうでした?

型の違う数値演算をしているときは、
なるべく精度の高いものに合わせて計算されます。

内部的にキャストが行われているので、予めこれを読んで数式を作る必要があります。


Aの例、i=1のとき
---------------------------------------
float A;

A = (float) ( 1/9 ); // i=1のときの計算
---------------------------------------
これだと先に括弧の中は(int同士の計算ですから少数以下は切り捨てられて)0になります。

ところが演算の中にintよりも精度...続きを読む

Q浮動小数点数の表現について

浮動小数点数の表現で、このIEEEともう一つの方式の違いは何でしょうか?
参考書にこう載っていましたが、よく理解できませんでした。
違いを教えてください。

10進数の28をIEEE仕様の浮動小数点数で表示します。

仮数部を2進数に (28)10 → (11100)2
仮数部の正規化 (11100)2 ×2 0 →(1.1100)2 ×2 4
指数部をイクセス表記に2 4 → 2 131

10進数の28をもう一つの仕様の浮動小数点数で表示します。

仮数部を16進数に (28)10 → (1C)16
仮数部の正規化 (1C)16×16 0 → (0.1C)16 ×16 2

Aベストアンサー

> 浮動小数点数の表現で、このIEEEともう一つの方式の違いは何でしょうか?

もう一つの方式って,IBM 方式 (エクセス64形式) でしょうか?
主な違いは基数が2と16の違いという点でしょう.

・仮数部:正規化する場合,後者は4ビット単位でしかシフトできない.
 このため基数2の場合に比べて,仮数部ビット数が同じならば
 下位3ビット分の精度が失われる場合がある.
 (つまり仮数部の小数点以下3ビットが .000 となる場合)

・指数部:指数部のビット数について言えば,基数16は基数2に比べて,
 2ビット少なくてもほぼ同じ範囲を表現できる.
 例えば浮動小数点数 16.0 について考えてみる.
 説明の都合上仮数部を 1.0 とし,指数部のバイアス (ゲタ) を0とすると,
 16.0 = 1.0 × 2^4 = 1.0 × 16^1 なので,
 基数2の場合の指数部は 100(2) で3ビット,基数16の場合の指数部は 1(2) で1ビット.


浮動小数点数 (Wikipedia)
http://ja.wikipedia.org/wiki/%E6%B5%AE%E5%8B%95%E5%B0%8F%E6%95%B0%E7%82%B9%E6%95%B0

> 浮動小数点数の表現で、このIEEEともう一つの方式の違いは何でしょうか?

もう一つの方式って,IBM 方式 (エクセス64形式) でしょうか?
主な違いは基数が2と16の違いという点でしょう.

・仮数部:正規化する場合,後者は4ビット単位でしかシフトできない.
 このため基数2の場合に比べて,仮数部ビット数が同じならば
 下位3ビット分の精度が失われる場合がある.
 (つまり仮数部の小数点以下3ビットが .000 となる場合)

・指数部:指数部のビット数について言えば,基数16は基数2に比...続きを読む

QUnityのエラー「Rigidbody.AddForce(0,0,speed);」

UnityでJavaを書いています。
実行すると

Rigidbody.AddForce(0,0,speed);

上記の箇所にエラーがあると言われたのですが、
どこが問題なのかわかりません。

お分かりの方がいたら、ご教授ください。
その前後のコードも記載します。


//上矢印キーが押された場合
if(Input.GetKeyDown(KeyCode.UpArrow)){
//玉のZ軸に対して正の力を加える
Rigidbody.AddForce(0,0,speed);
}

//下矢印キーが押された場合
if(Input.GetKeyDown(KeyCode.DownArrow)){
//玉のZ軸に対して負の力を加える
Rigidbody.AddForce(0,0,-speed);
}

Aベストアンサー

Javaは凄くうっすらやった事がある程度なのですが、
こちらのサイトを参考にすると「Rigidbody.AddForce(」の後は
数字ではなく英語にて指示を記述しているので、そこを変えてみたら直るかも…?

http://openbook4.me/projects/161/sections/1045

Q浮動小数点について

当方、浮動小数点を勉強しているのですが、
テキストの解説を読んでも理解が出来ません。

正規化とか指数と仮数の意味が分かりません。
そこで質問なのですが、浮動小数点の計算方法を教えて下さい。
IEEE形式の浮動小数点も教えて頂けると助かります。

また、下記の問題について解説して下さい。
数値を16ビットの浮動小数点表示法で表現する。
形式は図に示す通りである。10進数0.375を正規化した表現は、どれか。
ここでの正規化は、仮数部の有効数字よりも上位の0が無くなるように、
指数部を調節する操作である。
(図は添付します)

何故「E」の値が「1111」になるのでしょうか。
お手数ですが、ご教授お願いします。

尚、特に分かり易いホームページがあったら、
そのURLを記載して頂いても結構です。

以上、よろしくお願い致します。

Aベストアンサー

浮動小数点数の考え方について、まず10進数での「指数表記」について説明します。
これは、有効数字を明記するためによく使われる数値表現方法です。

例えば、1234560000 という数値を表現することを考えます。
この数値は123456×10000 と表されます。かけ算の右側は、0が続くだけですから、情報としては0の数だけで表現できます。つまり「123456」と0が「4個」という二つの数値の組で、1234560000 という数値を表現できるのです。
これは、べき乗をつかった式で「123456×10の4乗」(べき乗は、その回数だけかけ算を繰り返す演算で、10の4乗=10×10×10×10=1000です)と表現できます。
あるいは簡潔に「123456×10^4」や「123456E4」といった表記をします。
この「123456」が仮数部で、「4」が指数部になります。

さて、「123.456×10000000」すなわち「123.456×10^7」も、同じ1234560000を表します。
そこで、同じ数値を表す表現が複数あるのは紛らわしいので、表記を統一します。
10進数の指数表記では、仮数部が1以上10未満になる(1の位に数値は入っているが、10の位より上には数値が入らない)ようにします。
これを正規化といい、1234560000を正規化した指数表現で表すと「1.23456×10^9」になります。

小さい数を指数表記表現する場合も考え方は同じです。
例えば、0.00123456の場合は、=1.23456×0.01=1.23456×10^-2となります。(負の乗数はわり算になります。10の-2乗は、1÷10÷10=0.01)

以上が指数表記の考え方です。これを2進数を使って表現するのが「浮動小数点数」です。
たとえば、10進数での100という数値は、2進数では、01100100b になります。
これを、0.1100100b×128 すなわち、0.1100100×2^7 と考えて、「0.1100100b」と「7」という数値の組で表現します。

0.375の場合も、これを2進数で表すと、0.011b です。(0.375=0.250 + 0.125 = 0.01b + 0.001b)
これは、0.011b=0.11000000000b × 2^(-1) (0.11かける2の-1乗)ですので、
浮動小数点で表したときの、仮数M=0.11000000000、指数E=-1になります。
-1を4bitの2の補数表現で表すと、E=1111です。

浮動小数点数の考え方について、まず10進数での「指数表記」について説明します。
これは、有効数字を明記するためによく使われる数値表現方法です。

例えば、1234560000 という数値を表現することを考えます。
この数値は123456×10000 と表されます。かけ算の右側は、0が続くだけですから、情報としては0の数だけで表現できます。つまり「123456」と0が「4個」という二つの数値の組で、1234560000 という数値を表現できるのです。
これは、べき乗をつかった式で「123456×10の4乗」(べき乗は、その回数だけかけ算...続きを読む

QUNITY Float型の接尾辞fって

UNITYに限ったものではないのですが、Float型の接尾辞fについて
Wikiやhttp://www.wisdomsoft.jp/40.html/を見てみたのですが
ちょっと難しく理解できません。fってどのような時に使うのでしょうか?

Vector3 構造体のコンストラクタの部分で
public Vector3(float x, float y, float z)   ←となっていますが、
Vector3 v = new Vector3(765, 961, 876); ←fはついていないですし。


またUNITYのTransformで
PositionをX=0.5、Y=0.5、Z=0.5とするのと、X=0.5f、Y=0.5f、Z=0.5fとするのと位置が全然違います。

分かりやすい説明、サイトなどあれば教えてください

Aベストアンサー

これは多分、C#の解説を見たんでしょうね。Unityでは、JavaScript(UnityScript)の他、C#などの言語が使えます。Unityのコードの解説を読むときは、それが何の言語で書かれたものかを理解して読む必要があります。

0.5fとかの「f」は、C#で「float型リテラル」を示すものです。リテラルというのはソース・コード内に直接記述される値のことです。C#では、fを付けずに普通に0.5というように書くとdouble型(floatより値の精度が高い値と判断されます。Unityでは、実数を扱うメソッドなどではすべてfloat型が使われているため、そのまま0.5というように書くと叱られるのです。それで、0.5fというように書いて、float型の値にします。

また、Vector3 v = new Vector3(765, 961, 876);というサンプルコードは、これは引数すべてが整数(int値)になっています。C#では、floatなどの実数の引数に整数を指定すると暗示的キャストといって自動的にfloatに変換してくれるんです。だから、わざわざnew Vector3(765f, 961f, 876f);なんて書かなくていいんです。(doubleからfloatへは自動で変換してくれません。だから、0.5はいちいち0.5fと書かないといけません)

ただし、これは「C#という言語を使ってプログラムを書くとき」の話です。UnityのソフトでインスペクターのTransformに値を設定するときは、(Unityのソフトの部分はプログラミング言語とは関係ないので)0.5と書きます。0.5fって数字はありませんから、そんな具合に書くと正しく判断されないでしょう(おそらく、ゼロ扱いになるのでは)。

またUnityのプログラムでも、JavaScriptではソースコードはすべて0.5と書かれます。0.5fとは書きません(書いても動きますが意味ありません)。言語が違えば、書き方も変わってくるのです。

Unityの解説サイトなどでは、C#とJavaScriptが混在しています。そして大抵の場合、C#などの言語は既に理解しているものとして詳しい説明は省いてます。ですので、まずはC#について初歩から学んでおくとよいと思います。

これは多分、C#の解説を見たんでしょうね。Unityでは、JavaScript(UnityScript)の他、C#などの言語が使えます。Unityのコードの解説を読むときは、それが何の言語で書かれたものかを理解して読む必要があります。

0.5fとかの「f」は、C#で「float型リテラル」を示すものです。リテラルというのはソース・コード内に直接記述される値のことです。C#では、fを付けずに普通に0.5というように書くとdouble型(floatより値の精度が高い値と判断されます。Unityでは、実数を扱うメソッドなどではすべてfloat型が使わ...続きを読む


人気Q&Aランキング