如何将类型bytea转换为双精度

问题描述:

我有一个类型为bytea的数据库列。它包含作为字节数组转换的浮点数(每个浮点数4个字节),编码为Escape。我可以使用子字符串函数检索相应的bytea字符串。如何将类型bytea转换为双精度

我的问题是如何将bytea字符串转换为在SQL函数内部浮动。之前我转换为C#方面的浮动。我使用dataReader.getByte方法检索字节,然后使用BitConverter.ToSingle(.Net build in class)方法转换为浮点数。

现在我不能使用中间组件作为Npqsql驱动程序。我希望SQL将bytea直接转换为浮点数,并在从第三方应用程序执行查询时返回相应的数字。

由于 Amila

为此最佳的解决方案是将转换成使用标准IEEE754-1985使用SQL命令字节。

首先需要检查IEEE754-1985标准定义的特殊情况。然后只要按照标准算法进行转换,如果它不是在任何特殊情况下。示例代码如下。

输入被bytea_value bytea, is_little_endian boolean然后分成4个字节如下:

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); 

然后得到考虑小端或大端

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; 

现在检查的特殊情况下的二进制值:

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;