如何将Bytea类型转换为双精度 [英] How to cast type bytea to double precision

查看:246
本文介绍了如何将Bytea类型转换为双精度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a database column which type is bytea. It contains floats converted as byte array (4 bytes per one float) and encoding is Escape. I'm be able to retrieve corresponding bytea string using substring function.

我的问题是如何将BYtea字符串转换为浮点型SQL函数。之前,我转换为C#端的float。我使用dataReader.getByte方法检索字节,然后使用BitConverter.ToSingle(.Net内置类)方法转换为浮点型。

My question is how can I convert bytea string to float inside a SQL function. Earlier I converted to float in C# side. I used dataReader.getByte method to retrieve bytes and then Converted to float using BitConverter.ToSingle (.Net build in class) method.

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

Now I can't use intermediate component as Npqsql driver. I want SQL to directly convert bytea into floats and return the corresponding number when execute a query from 3rd party application.

感谢
Amila

Thanks Amila

推荐答案

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

For this purpose the best possible solution is to convert into bytes using IEEE754-1985 standard using SQL commands.

首先,需要检查IEEE754-1985标准定义的特殊情况。如果不是特殊情况,只需遵循标准算法进行转换。示例代码如下。

First it is required to check for special cases defined by IEEE754-1985 standard. Then just follow the standard algorithm to convert if it is not in any special cases. Sample code is below.

输入的是 bytea_value bytea,is_little_endian布尔值,然后分成4个字节,如下所示:

Inputs are bytea_value bytea, is_little_endian boolean then divide into 4 bytes as below:

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

然后通过考虑小字节序或大字节序获得二进制值

Then get the binary value by considering little endian or big endian

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;

如果它不属于任何特殊情况,则将其转换如下:

If it does not belong to any special cases just convert it as below:

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;

这篇关于如何将Bytea类型转换为双精度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆