Ada dua kesalahan dalam kode Anda:
-
Anda mencoba mengirim data biner, tetapi Anda tidak memberi tahu
PQexecParamsjenis apa itu.Itu tidak bisa bekerja. Kurangnya informasi jenis, PostgreSQL akan menggunakan jenis
unknowndan memperlakukannya sebagai string. Itu berarti representasi biner Anda akan diumpankan kefloat8infungsi yang mengubah string menjadi nilai presisi ganda, yang akan gagal total. Ini mungkin yang Anda amati.Anda harus menggunakan parameter keempat dengan
Oid[]yang berisi 701 (atauFLOAT8OIDjika Anda lebih suka menggunakan#definePostgreSQL , tetapi Anda harus#include <postgres.h>dan<catalog/pg_type.h>untuk itu). -
Anda keliru berasumsi bahwa representasi biner PostgreSQL dari
double precisiontype adalah format biner untukdoublesedang digunakan di mesin klien Anda.Ini mungkin tidak sengaja bekerja jika program Anda berjalan pada big-endian mesin, karena hampir setiap arsitektur saat ini menggunakan nomor floating point IEEE .
Jika Anda membaca kode sumber, Anda akan menemukan bahwa format biner over-the-wire PostgreSQL didefinisikan dalam
pq_sendfloat8disrc/backend/libpq/pqformat.c, yang memanggilpq_sendint64, yang mengubah nilai 8-byte menjadi urutan byte jaringan (yang sama dengan representasi big-endian).
Jadi, Anda harus mendefinisikan fungsi konversi yang mirip dengan ini:
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);
}
Maka kode Anda akan terlihat seperti ini:
Oid types[1];
double converted;
...
types[0] = FLOAT8OID;
to_nbo(value, &converted);
values[0] = (char *)&converted;
Tapi terus terang, akan jauh lebih mudah menggunakan representasi teks. Itu akan membuat kode Anda independen dari internal PostgreSQL dan mungkin tidak jauh lebih lambat.
Tidak terlihat seperti itu, tetapi jika double precision nilai ditarik dari tabel PostgreSQL di tempat lain, Anda dapat mengatur extra_float_digits
= 3 sehingga Anda dijamin tidak akan kehilangan presisi saat nilai dikonversi ke representasi string..