我有一个数据库列,其类型为bytea。它包含转换为字节数组的浮点数(每个浮点数4个字节),编码为Escape。我可以使用子字符串函数检索相应的bytea字符串。
我的问题是如何将字节转换为浮点数的SQL函数中。之前,我转换为C#端的float。我使用dataReader.getByte方法检索字节,然后使用BitConverter.ToSingle(.Net内置类)方法转换为float。
现在,我不能将中间组件用作Npqsql驱动程序。我希望SQL在执行来自第三方应用程序的查询时直接将bytea转换为float并返回相应的数字。
为此,最好的解决方案是使用SQL命令使用IEEE754-1985标准将其转换为字节。
首先,需要检查IEEE754-1985标准定义的特殊情况。然后,如果不是特殊情况,只需遵循标准算法进行转换。示例代码如下。
bytea_value bytea, is_little_endian boolean然后将输入分为4个字节,如下所示:
bytea_value bytea, is_little_endian boolean
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;