2013-12-19 12 views
6

私は(unsigned-byte 32)の配列を持っていますが、かなりのデータが含まれています。その一部は浮動小数点形式です。つまり、一部のバイトは32ビットの浮動小数点数として、ビットフィールドを含む整数として扱われます。sbcl:(符号なしバイト32)を単精度浮動小数点数に変換する

アレイのデータを読み書きする必要があります。

残念ながら、関数sb-kernel:make-single-float(signed-byte 32)の引数をとり、sb-kernel:single-float-bitsも署名付きの単語を返します。したがって、これらのベクトルはベクターと直接互換性がありません。一方、符号付きバイトを含むようにベクトルを変換すると、ビットフィールド演算が苦痛になります。

はこれまでのところ、私は正しいことをし

(defun u32-to-sf (x) 
    (declare (optimize (speed 3) (compilation-speed 0) (debug 0)) 
      (type (unsigned-byte 32) x)) 
    (if (>= x #x80000000) 
     (sb-kernel:make-single-float (- x #x100000000)) 
     (sb-kernel:make-single-float x))) 

書かれているが、生成されたアセンブリは、その条件ジャンプ、不要な比較と減算で醜いん。

float-to-beのビット単位の内容として、unsigned-byteのビット単位の内容を受け入れるようにsbclを説得する方法に関するアイデアはありますか?

答えて

3

(declare (optimize (safety 0)) (type (signed-byte 32) x)))です。それはずっと短いアセンブリを生成するように思われます(使用されていないif分岐を最適化します)と同じ結果になります。私はアセンブリを実際に精査し、完全な回帰テストでこれを保証することを提案します。

+0

確かに、正しいアセンブリコードが生成されます。もちろん、この場合は 'if'全体は不要です。しかし、もう一度、これはややこしい解決策であり、現在のバージョンで動作しますが、将来も正常に動作すると想定するのは一般的に安全だとは思いません。しかし、当分の間、十分に良い - ありがとう! – jlahd

関連する問題