0

一連のビット演算を使用して float 値を比較するにはどうすればよいですか?

4

9 に答える 9

5

しないでください。ただ...しないでください。==、またはそのワイルドで奇抜な隣人>および を使用し<ます。クレイジーなハイブリッドも<=あり>=ます。これらは、float 比較のすべてのニーズをカバーするはずです。

更新:気にしないで、使用しないでください==。他は問題ないはずです。

更新の更新:使用しない==ということは、おそらく<=またはも使用しないことを意味します>=。この話の教訓は、float は扱いにくいということです。そのため、float に対してビット単位の操作を絶対に試みてはなりません。

于 2010-06-23T16:25:53.923 に答える
2

状況によっては、浮動小数点数をビット単位で操作することは実際には理にかなっています。たとえば、ビット精度が低い、またはビット精度が高いハードウェアをモデル化しようとしている場合です。そのような場合、float番号のビットにアクセスする必要があります。btaが言ったように、最初に知っておくべきことはIEEE 754標準であり、操作しているビットを知ることができます。

そうすれば、新武蔵のような解決策を使うことができますが、もう少し洗練されたものを提案したいと思います。

単精度が必要だとしましょう。

まず、さまざまな浮動小数点フィールドを使用して構造を宣言します。

typedef struct s_float{
    int sign : 1;
    int exponent : 8;
    int mantissa : 23;
}my_float_struct;

次に、ユニオンを次のように宣言します。

union u_float{
    float the_float;
    my_float_struct the_structure;
}my_float;

次に、次のようにしてコード内のfloatにアクセスできます。

my_float.the_float = <float number>;

ビットフィールドは、たとえば次のように使用されます。

printf("%f is %d.%d.%d\n",my_float.the_float,my_float.the_structure.sign,my_float.the_structure.exponent,my_float.the_structure.mantissa);

また、フィールドなど、必要なものを割り当てたり、変更したりすることもできます。

于 2011-10-25T10:28:55.343 に答える
1

でビットごとの演算子を使用してfloatも、あなたが思っていることを行うとは思いません。これを行う前に、 IEEE 754規格に精通していることを確認してください。IEEE 754規格は、浮動小数点数が内部でどのように表現されるかを規定しています。これは完全に有効な操作ですが、あまり役に立たない可能性が高くなります。

正確に何を達成しようとしていますか?それを行うためのより良い方法がある可能性があります。

于 2010-06-23T16:30:57.360 に答える
0

以下のリンクには、このトリックを使用して浮動小数点数の高度に最適化されたソート関数を作成するための適切な説明があります。

http://www.stereopsis.com/radix.html

明らかに、この種のハックの使用は移植性がなく、ほとんどの状況ではお勧めできません。

于 2010-06-23T16:54:27.970 に答える
0

これを行う必要がある非常にまれな状況 (たとえば、PC で操作される VAX G 形式のデータなど、外部の浮動小数点形式を扱う場合) では、通常、浮動小数点データを次の整数に入れることによって行います。同じサイズ、または char の配列 (これも正しいサイズ) に変換します。

そのようなコードが移植可能またはクリーンに近いとは思わないでください。典型的なケースでは、これを可能な限り少なくしたいと考えています。通常は、生データを読み込み、可能な限り最も近いネイティブ浮動小数点値を作成し、それを操作するだけです。そのような外部データを処理する必要がある場合でも、外部形式での比較などを行うことは一般的に避けるべきです。

于 2010-06-23T16:33:25.323 に答える
0

数値で表されるドメインはfloat、ビットの実装と操作にうまく適合しません。

浮動小数点数にビットごとの演算子を簡単に適用できますが、浮動小数点数として扱いたい場合、これらの演算子は単に意味をなさない方法で数値を変更するため、有用なものは得られません..

2 つの指数の AND 演算または 2 つの仮数の XOR 演算はどのような意味を持つでしょうか? 私は実際のフロート操作を意味します..

于 2010-06-23T16:27:57.977 に答える
0

浮動小数点レイアウトは、プラットフォームに大きく依存します。整数演算のみを使用してランダムな浮動小数点数を描画する醜いハックを見たのを覚えていますが、これは間違いなく移植性がありません。

于 2010-06-23T16:28:09.113 に答える
0

整数型に変換します。次に、すべての二項演算を使用できます。変換は一時的なものであることに注意してください (型変換は、別の型であるかのように解釈された値を返す関数のようなものです)。

float real_value;
(int)real_value | 3, // this will work
real_value | 3; // This will not work
于 2011-10-27T12:38:47.597 に答える
0

fp 値に関する IEEE 仕様を注意深く読んだら、あなたは出発点にいます。次のステップは、CPU が fp をサポートしている場合、ハードウェアによって既に行われていることをソフトウェアで実装することです。それ以外の場合は、fp 操作 (IEEE に従って) をソフトウェアでゼロから実装する必要があります... IEEE 754 が必要な場合は、IEEE が cpus または fp コプロセッサに使用される前に行ってください)。

ターゲットがまったく fp できないと仮定して、ゼロから実装する必要があります。次に、数値をメモリに格納する方法を決定するのはあなた次第です (システムのエンディアンに同意するかどうかは自由です)。たとえば、1.23 の float は、私のマシン (LE) では 0xA4709D3F として mem に保存され、実際には「正しい」方法は 0x3F9D70A4 です (私たちの書き方は LE よりも BE に似ていますが、「正しい」方法はありません...この方法ではデータをスペックで直接確認できるため、-1.23 と書き込むと 0xBF9D70A4 が得られますが、符号ビットが 1 になっていることは明らかです)

しかし、ゼロから実装するので、次のようにして数値をメモリに書き込むことができます。

unsigned char p[4];
p[0] = 0x3f; p[1] = 0x9d; p[2] = 0x70; p[3] = 0xa4;

そして、それは難しい部分になります...このように:

bool is_positive(float_t *p)
{
  return ! (p[0] & 0x80); // or alike
}

procが32ビット(またはそれ以上)の整数を処理できないと仮定して、メモリ内で作業します。もちろん、私はより簡単な操作を選びました...!他のものは難しいですが、IEEE 754 の説明から始めて、いくつかの推論を行うことで、必要なものを実装できます。ご覧のとおり、それほど簡単ではありません...浮動小数点ユニットがない場合に fp 数値の操作を実装するライブラリをどこかで見つけることができましたが、今は見つけることができませんでした (例は Amiga mathieeedoubbas.libraryかもしれませんが、私はこのソースを見つけることができないと思います.とにかく、m68k asm に直接含まれている可能性があります...; ソフトウェア impl がどこかに存在する可能性があると言うだけです...)

于 2010-06-23T18:09:08.620 に答える