2012-02-21 7 views
2

型bytea型のデータベース列があります。これは、バイト配列(1フロート当たり4バイト)として変換された浮動小数点数を含み、エンコーディングはEscapeです。私は部分文字列関数を使って、対応するbytea文字列を取得することができます。型byteaを倍精度にキャストする方法

私の質問は、SQL関数内でbytea文字列をfloatに変換する方法です。以前私はC#側でフロートに変換されました。 dataReader.getByteメソッドを使用してバイトを取得し、BitConverter.ToSingle(.Netクラスのクラス)メソッドを使用してfloatに変換しました。

Npqsqlドライバとして中間コンポーネントを使用することはできません。私は、SQLを直接浮動小数点に変換し、第三者のアプリケーションからクエリを実行するときに対応する数値を返すようにします。この目的のために

おかげ Amila

答えて

2

最善の解決策は、IEEE754-1985標準使用してSQLコマンドを使用してバイトに変換することです。

まず、IEEE754-1985規格で定義されている特殊なケースを確認する必要があります。それで、特別なケースでない場合は、変換する標準アルゴリズムに従ってください。サンプルコードは以下の通りです。そして、今、特別な場合をチェックリトルエンディアンまたはビッグエンディアン

IF is_little_endian THEN 
     binary_value:= byte_array[0]::bit(8) || byte_array[1]::bit(8) || byte_array[2]::bit(8) || byte_array[3]::bit(8); 
    ELSE 
     binary_value:= byte_array[3]::bit(8) || byte_array[2]::bit(8) || byte_array[1]::bit(8) || byte_array[0]::bit(8); 
    END IF; 

を考慮してバイナリ値を取得

byte_array[0]:= get_byte(bytea_value, 0); 
    byte_array[1]:= get_byte(bytea_value, 1); 
    byte_array[2]:= get_byte(bytea_value, 2); 
    byte_array[3]:= get_byte(bytea_value, 3); 

入力は以下のように4バイトに分け、その後bytea_value bytea, is_little_endian booleanです

IF binary_value = '00000000000000000000000000000000' OR binary_value = '10000000000000000000000000000000' THEN -- IEEE754-1985 Zero 
     return 0.0; 
    END IF; 

sign := substring(binary_value from 1 for 1); 
    exponent := substring(binary_value from 2 for 8); 
    mantissa := substring(binary_value from 10 for 23); 

    IF exponent = '11111111' THEN 
     IF mantissa = '00000000000000000000000' THEN -- IEEE754-1985 negative and positive infinity 
      IF sign = '1' THEN      
       return '-Infinity';      
      ELSE      
       return 'Infinity'; 
      END IF;     
     ELSE 
      return 'NaN'; -- IEEE754-1985 Not a number 
     END IF; 
    END IF; 

特殊なケースに属していない場合は、以下:

exp := exponent::int; 

    IF exp > 126 THEN 
    exp := exp - 127; 
    ELSE 
    exp:= -exp; 
    END IF; 

    WHILE mantissa_index < 24 LOOP 
     IF substring(mantissa from mantissa_index for 1) = '1' THEN 
      result := result + power(2, -(mantissa_index)); 
     END IF; 
     mantissa_index = mantissa_index + 1; 
    END LOOP; 

    result := result * power(2, exp); 

    IF(sign = '1') THEN 
     result = -result; 
    END IF; 

    return result;