Haskell(Appleのバイナリプロパティリスト形式)でバイナリファイル形式を解析しようとしています。この形式に必要なものの1つは、バイトのシーケンスを(a)符号なし1-、2-、または4-のいずれかとして扱うことです。バイト整数; (b)符号付き8バイト整数。(c)32ビットfloat; および(d)64ビットdouble。バイトのシーケンスを符号なし整数に変換するのは簡単で、符号付き整数を扱うことさえひどいことではありません。しかし、符号付き整数の場合、特にFloatsとsの場合Double、ロジックを自分で実装したくありません。私は関数int2Float# :: Int# -> Float#とGHC.Primint2Double# :: Int# -> Double#を見つけることができました、しかしこれらは理想的ではないようです(私は特に箱なしのタイプで作業したくありません)。[Word8]私の望みは、aまたはWord32s/ sのいずれかからキャストする方法があることWord64です。タイプ、、、、または同様の機能はありWord32 -> FloatますかWord64 -> Double?Word64 -> Int64
2788 次
2 に答える
5
気づいていない場合は、fromIntegral積分を完全に変換します。また、バイナリパッケージおよび関連するdata-binary-ieee754パッケージは、問題に非常に適しています。
λ> :set -XOverloadedStrings
λ> import Data.Binary.Get (runGet)
λ> import qualified Data.Binary.IEEE754 as I
λ> runGet I.getFloat32le "\STX\SOH\SOH\SOH"
2.369428e-38
λ> runGet I.getFloat32le "\STX\SOH\SOH\SOHtrailing characters are ignored"
2.369428e-38
λ> runGet I.getFloat32le "\STX\SOH\SOH" -- remember to use `catch`:
*** Exception: Data.Binary.Get.runGet at position 0: not enough bytes
CallStack (from HasCallStack):
error, called at libraries/binary/src/Data/Binary/Get.hs:351:5 in binary-0.8.5.1:Data.Binary.Get
于 2011-01-10T04:10:20.093 に答える
1
Unsafe.Coerce.unsafeCoerceC++のようにタイプ間で変換できますreinterpret_cast<>。注意して使用してください。
それ以外の場合は、を使用して独自のIEEE-754デコードを実装できますRealFloat。
bitsAsIEEE754 :: (Bits a, Integral a, RealFloat b) => a -> b
bitsAsIEEE754 word =
assert (floatRadix float == 2) $
assert (bitSize word == 1 + es + ms) $
assert (1 `shiftL` es == maxE - minE + 3) $
float
where
ms = floatDigits float - 1
(minE, maxE) = floatRange float
es = length $ takeWhile (< maxE - minE + 2) $ iterate (* 2) 1
sgn = if testBit word (ms + es) then negate else id
e = fromIntegral $ word `shiftR` ms .&. (1 `shiftL` es - 1)
nor = if e == 0 then id else flip setBit ms
m = sgn . toInteger . nor $ word .&. (1 `shiftL` ms - 1)
float = encodeFloat m $ max minE (e + minE - 1) - ms - 1
-0少なくとも私のGHCでは、を作成してNaN使用することはできないようですencodeFloatが、他のすべては機能するはずです。
于 2011-01-10T03:58:43.647 に答える