
No.4ベストアンサー
- 回答日時:
Q13 でいいなら, 端数処理の問題はあるけどおそらく考えすぎ.
元の数を x とすると
(int)(x * (1 << 13))
でだいたいうまくいくはず. 負の数のときに問題になりえるんだけど, そのときには負の浮動小数点数を整数に変換するときに丸めが「0 への丸め」じゃないということなので
(x < 0) ? (int)(x * (1 << 13)) : ~(int)(-x * (1 << 13)) + 1
でいいような気がする.
もちろん Q13 でいいかどうかは私にはわからんので確認しといてください.
>Tacosanさん
ご回答,ありがとうございます.
書いて頂いたように記述してみたところ,うまく表示させることができました!
Q13の件についても確認したのですが,やはり固定小数点数で正しかったようです.
本当にありがとうございましたm(__)m
No.5
- 回答日時:
浮動小数点であれば単純な2の補数では表現不可能です。
下記の様にfloat型をそのまま表示しちゃ駄目なのかな?
float型もlong型も32bitの処理系とします。
float f;
long *l;
f = -1.915098;
l = (long *)&f;
printf("%04x\n",*l);
float型
bit[31] 符号ビット
bit[30:21] 指数部
bit[22:0] 可数部
floatの値 = (-1)*符号 * 2^(指数部-127) * 1.仮数部
16進数で出力してますが、2進数には簡単に直せますよね?
また固定小数点なら2の補数で表現可能です。入力範囲とビット幅を決定しなければいけません。
ビット数を32ビットとし
入力範囲を((2^31)-1)/(2^30)=1.999... ~ -(2^31)/(2^30)=-2
とするなら。
float f;
long l;
f = -1.915098;
l = f * (float)(1<<30);
printf("%04x\n",l);
で良いのでは?
入力範囲を超えるならクリップ処理を入れたほうが良いかも。
>ICE_FALCONさん
ご回答,ありがとうございます.
お礼が遅くなってしまい,申し訳ありませんでした…
宣言まで丁寧に書いて頂き,非常に理解しやすかったです.
結果的には,固定小数点数でうまく表示させることができました.
また,ご指摘の通り入力範囲を超える値もありましたので,自分なりにクリップ処理も追加してみました.
この度は,本当にありがとうございました.
また何かありましたら,よろしくお願い致しますm(__)m
No.3
- 回答日時:
No.1です。
「浮動小数点」の認識が、私とは違っているようです。
私の認識では
>「4.125」のように小数部がいわゆる2^(-n)で表現できるような値に関しましては(以下略)
浮動小数点としての表記は(()内は指数)、
4.125=4.125*2(0)
=0.4125*2(1)
となるため、この時点で丸めが発生していますよ。
質問者さんの行っていることは、0.0001を1bitの規定として扱った場合の処理です。
>#また,最終的には小数点を用いずに出力しなければなりません
>(「1.915098」を13ビット(2^13=8192)を基準として表現?できるように,とのことなのですが,
ここが不明瞭です。
「13bit」は少数部のことでしょうか? であれば、「固定16bit」だと「符号部1bit、指数部2bit」しか領域がとれませんよ?
それとも、No.2氏の書かれている通り、固定小数点でしょうか?
どちらにしろ丸めが発生するのは避けられませんが。
質問の
>10進数の値を,固定長16ビットの2進数に変換したいと考えています.
に対して、具体的な結果としてどのような値としたいのかをいくつかの例を教えていただけませんか?
この回答への補足
>SilverThawさん
度々ありがとうございます.ご指摘,大変感謝しています.
まず,
>10進数の値を,固定長16ビットの2進数に変換したいと考えています.
に関してですが,結果として以下のように,複数の小数点や負数を含む数値に対して,それぞれ16ビットの2進数に変換できることを目的としています.
1.915098(10) → xxxx xxxx xxxx xxxx(2)
-3.055348(10) → xxxx xxxx xxxx xxxx(2) … 2の補数表現
0.540523(10) → xxxx xxxx xxxx xxxx(2)
このとき,xxxx xxxx xxxx xxxx(2)は小数点を含まないように表現したいと考えています.
この点から,ご指摘のように「0.0001を1bitの規定として扱った場合の処理」をすることで,小数点を含まず2進数に変換できるのではないかと理解しました…
>#また,最終的には小数点を用いずに出力しなければなりません
>(「1.915098」を13ビット(2^13=8192)を基準として表現?できるように,とのことなのですが,
この件に関しましては,Tacosanさんの言われている通り,固定小数点のQ13表記のことだと思われます.
Q13表記で,上の例を表現しますと,
1.915098(10) → 0011 1101 0100 1000(2)
(1.915098 * 8192 = 15688.48282, 小数点以下切り捨てで15688→0011110101001000)
-3.055348(10) → 1001 1110 0011 1011(2) … 2の補数表現
(-3.055348 * 8192 = -25029.41082, 小数点以下切り捨てで25029→0110000111000101, 2の補数表示で1001111000111011)
0.540523(10) → 0001 0001 0100 1011(2)
(0.540523 * 8192 = 4427.964416, 小数点以下切り捨てで4427→0001000101001011)
という結果になり,目的としていた表示となっていたため,固定小数点ではないかと考えました.
不明瞭にしてしまっていた点に関しましては,私なりに上記のように理解したのですが,おかしい点などがありましたら,ご指摘頂けるとうれしく思います…
No.2
- 回答日時:
たとえば 1.915098 なんかだと変換するときに端数が出るんだけど, その処理はどうするんですか? 切り上げ/切り捨て/四捨五入/最近値のどれにするかによって処理が変わるのでそこは決めておく必要があります.
「13ビット(2^13=8192)を基準として表現」の意味が分からんけどいわゆる Q13 (小数点以下が 13ビットの固定小数) のことなのかなぁ?
この回答への補足
>Tacosanさん
回答ありがとうございますm(__)m
端数の件は考えていませんでした…しかし,おそらく切り捨てで処理すればいいのではないかと考えています.
Q表記という名称に関しましては,正直知りませんでした…
そこで調べさせて頂いたのですが,「13ビット(2^13=8192)を基準として表現」はQ13という意味のような気がしてきました.
例えば 1.915098 の場合ですと,2^13=8192ですので
1.915098(10) * 8192(10) = 15688.48282(10)
となり,ここで15688.48282(10)の小数部分以下を切り捨てたとして,15688(10)を2進数に変換すると
15688.48282(10) = 0011110101001000(2)
となりました.この上式で得られた2進表記がQ13であり,下位から13ビット目と14ビット目の間に小数点があることを表している,と理解しているのですが,ここまでは正しいでしょうか…?
また,001.1110101001000(2)に対して10進数に変換したところ
001.1110101001000(2) = 1.915039...(10)
となりました.
#おそらく,許容される誤差の範囲内だと思います.
No.1
- 回答日時:
単純な「2の補数」ではなく「浮動少数点」の理解が必要なようですが、この部分は理解されていますか?
少なくとも、「-1.915098」といった小数点付を扱うにはその知識が必要ですが、マイナスがつかない場合の変換はできますか?
この回答への補足
>SilverThawさん
早速の回答,ありがとうございますm(__)m
「浮動小数点」に関しましては,概要が多少分かる程度であり,正規化などについては正しく理解できていません…
マイナスが付かない場合の変換に関してですが,ある程度までは出来る形になっています.
例として挙げさせていただいた「1.915098」のような小数部が長い場合の変換はうまく出来ていないのですが,「4.125」のように小数部がいわゆる2^(-n)で表現できるような値に関しましては,
4.125 * 256(=2^8)
を行い,
4.125 * 256 = 1056
として,整数にしてから
1056(10) = 0000010000100000(2)
上のように求めています.
#本来ならば,さらに8ビットシフトが必要かと思いますが,その辺りはまだ…
#また,最終的には小数点を用いずに出力しなければなりません(「1.915098」を13ビット(2^13=8192)を基準として表現?できるように,とのことなのですが,ここはまだ理解できていません…)
しかしながら,この方法では「1.915098」のような値をうまく求めることができず,どうしたものかというのが現状です.
乱文で申し訳ありませんが,よろしくお願い致します…
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- 計算機科学 2進数の計算について 2進数の値は全て8ビットで負数は2の補数形式とする。結果が8ビットで表現出来な 3 2023/07/22 14:08
- 計算機科学 ビット計算 2 2023/04/16 14:26
- 数学 フーリエ変換後の負の周波数成分の扱いについて 4 2022/09/03 10:18
- 計算機科学 6ビット(符号含む)の二進数 4 2023/04/16 13:22
- 数学 2変数関数の条件つき極値問題について、 ラグランジュ未定乗数法で候補点を求めたあと、 ①ヘッセ行列の 4 2022/11/13 18:14
- 情報処理技術者・Microsoft認定資格 2進数の問題を教えてください。 1 2022/07/27 09:42
- 情報処理技術者・Microsoft認定資格 情報技術の問題についてです。 10進数の−36を以下のような16ビットの浮動小数点表示にするといくつ 3 2022/05/21 19:53
- Java Java 配列<選挙> 4 2023/07/31 15:07
- 数学 以下の問題が分かりません。 8ビット浮動小数点数が、最上位ビットから順に符号1ビット、指数部3ビット 4 2023/07/22 16:06
- 数学 虚数単位i について「i =√-1<=> i^2=-1」と定められていますが、これらが同値であること 12 2023/07/05 16:39
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Format関数の戻り値
-
バイナリデータの文字列変換(5...
-
sscanfの16進出力の逆処理
-
VB6.0の「vbFromUnicode」はVB....
-
計算方法
-
オリジナルプログラムです。
-
10進数を2進数
-
n進数の値を10進数の値に変換す...
-
2進数から10進数へ変換
-
VB.NET ゼロ埋め
-
Pythonの指数表記について
-
textbox.textやlabel.captionの...
-
VBでUTF-8で出力
-
C#でテキストボックスに入力し...
-
エクセルのマクロ コンボボッ...
-
INT64対応のprintf系関数はあり...
-
VBとアクセスでSQL文に変...
-
Notesのフォームを動的に・・・
-
【VB.NET】Excelの最終行までの...
-
SQL同時実行違反
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VB6.0の「vbFromUnicode」はVB....
-
VB.NETで1→A、2→B、26→Z、27→AA...
-
WORD型をCString型に変換する方法
-
16進をASCIIコードに変換する...
-
バイト型のデータをLong型に変換
-
16進コード文字列を文字列に変換
-
VB6.0 String型→Long型変換方法...
-
C#で文字列を数値に変換する方法
-
【C++/CLI】int型からString型...
-
2の補数の計算について
-
VC++ std::stringからLPCWSTRに...
-
vb6の桁数指定
-
C#でListとDictionaryの判別方法
-
VBAのstrConv関数のUNICODE変換...
-
対数変換のついて
-
文字型を日付/時刻型に変換する...
-
C++ 文字列変数と16進数の比較
-
RGBとHSLを相互変換する際の端...
-
Excelの数字(文字列)合計につい...
-
Boolean型変数の値を反転する方法
おすすめ情報