Có hai lỗi trong mã của bạn:
-
Bạn đang cố gắng gửi dữ liệu nhị phân, nhưng bạn không cho
PQexecParams
biết đó là loại nào.Điều đó không thể hoạt động. Thiếu thông tin về loại, PostgreSQL sẽ sử dụng loại
unknown
và coi nó như một chuỗi. Điều đó có nghĩa là biểu diễn nhị phân của bạn sẽ được cung cấp chofloat8in
hàm chuyển đổi các chuỗi thành các giá trị chính xác gấp đôi, điều này sẽ thất bại khủng khiếp. Đây có thể là những gì bạn đang quan sát.Bạn sẽ phải sử dụng tham số thứ tư với
Oid[]
chứa 701 (hoặcFLOAT8OID
nếu bạn muốn sử dụng#define
của PostgreSQL , nhưng bạn phải#include <postgres.h>
và<catalog/pg_type.h>
cho điều đó). -
Bạn nhầm tưởng rằng biểu diễn nhị phân của PostgreSQL về
double precision
type là định dạng nhị phân chodouble
đang được sử dụng trên máy khách của bạn.Điều này có thể vô tình hoạt động nếu chương trình của bạn đang chạy trên big-endian máy, vì hầu như mọi kiến trúc ngày nay đều sử dụng số dấu chấm động IEEE .
Nếu bạn đọc mã nguồn, bạn sẽ thấy rằng định dạng nhị phân over-the-wire của PostgreSQL được xác định trong
pq_sendfloat8
trongsrc/backend/libpq/pqformat.c
, gọipq_sendint64
, chuyển đổi giá trị 8 byte thành thứ tự byte mạng (giống như biểu diễn big-endian).
Vì vậy, bạn phải xác định một hàm chuyển đổi tương tự như sau:
static void to_nbo(double in, double *out) {
uint64_t *i = (uint64_t *)∈
uint32_t *r = (uint32_t *)out;
/* convert input to network byte order */
r[0] = htonl((uint32_t)((*i) >> 32));
r[1] = htonl((uint32_t)*i);
}
Sau đó, mã của bạn có thể trông giống như sau:
Oid types[1];
double converted;
...
types[0] = FLOAT8OID;
to_nbo(value, &converted);
values[0] = (char *)&converted;
Nhưng thẳng thắn mà nói, sẽ dễ dàng hơn nhiều khi sử dụng biểu diễn văn bản. Điều đó sẽ làm cho mã của bạn độc lập với nội bộ PostgreSQL và có lẽ không chậm hơn nhiều.
Nó không giống như vậy, nhưng nếu double precision
giá trị được lấy từ bảng PostgreSQL ở một nơi khác, bạn có thể đặt extra_float_digits
= 3
để bạn được đảm bảo không bị mất bất kỳ độ chính xác nào khi các giá trị được chuyển đổi thành biểu diễn chuỗi của chúng ..