PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Cách truyền kiểu bytea để tăng gấp đôi độ chính xác

Với mục đích này, giải pháp tốt nhất có thể là chuyển đổi thành byte bằng tiêu chuẩn IEEE754-1985 bằng cách sử dụng các lệnh SQL.

Đầu tiên cần phải kiểm tra các trường hợp đặc biệt được xác định bởi tiêu chuẩn IEEE754-1985. Sau đó, chỉ cần tuân theo thuật toán tiêu chuẩn để chuyển đổi nếu nó không nằm trong bất kỳ trường hợp đặc biệt nào. Mã mẫu bên dưới.

Đầu vào là bytea_value bytea, is_little_endian boolean sau đó chia thành 4 byte như sau:

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

Sau đó, lấy giá trị nhị phân bằng cách xem xét endian nhỏ hoặc endian lớn

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;

Bây giờ hãy kiểm tra các trường hợp đặc biệt:

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;

Nếu nó không thuộc bất kỳ trường hợp đặc biệt nào, chỉ cần chuyển đổi nó như sau:

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;


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Thay đổi thứ tự cột trong bảng postgres

  2. Hệ số lấp đầy cho một chỉ số tuần tự là PK

  3. Tự động kiểm tra bảo mật cho PostgreSQL

  4. Hiệu suất không được tăng lên thậm chí còn tăng kích thước work_mem

  5. Cài đặt psycopg2 (postgresql) trong virtualenv trên windows