W Twoim kodzie są dwa błędy:
-
Próbujesz wysłać dane binarne, ale nie mówisz
PQexecParamsjaki to jest typ.To nie może działać. Brak informacji o typie PostgreSQL użyje typu
unknowni traktuj to jako ciąg. Oznacza to, że twoja binarna reprezentacja zostanie przekazana dofloat8infunkcja, która konwertuje ciągi na wartości podwójnej precyzji, co strasznie się nie powiedzie. To jest prawdopodobnie to, co obserwujesz.Będziesz musiał użyć czwartego parametru z
Oid[]który zawiera 701 (lubFLOAT8OIDjeśli wolisz używać#definePostgreSQLa , ale musiałbyś#include <postgres.h>i<catalog/pg_type.h>za to). -
Błędnie zakładasz, że binarna reprezentacja PostgreSQL
double precisiontype to format binarny dladoublew użyciu na komputerze klienckim.Może to przypadkowo zadziałać, jeśli Twój program działa na big-endian maszyny, ponieważ obecnie praktycznie każda architektura używa liczby zmiennoprzecinkowe IEEE .
Jeśli przeczytasz kod źródłowy, odkryjesz, że format binarny PostgreSQL jest zdefiniowany w
pq_sendfloat8wsrc/backend/libpq/pqformat.c, który wywołujepq_sendint64, który konwertuje wartość 8-bajtową na sieciowy porządek bajtów (który jest taki sam jak reprezentacja big-endian).
Musisz więc zdefiniować funkcję konwersji podobną do tej:
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);
}
Wtedy Twój kod może wyglądać tak:
Oid types[1];
double converted;
...
types[0] = FLOAT8OID;
to_nbo(value, &converted);
values[0] = (char *)&converted;
Ale szczerze mówiąc, znacznie łatwiej byłoby użyć reprezentacji tekstowej. To sprawi, że Twój kod będzie niezależny od wewnętrznych elementów PostgreSQL i prawdopodobnie nie będzie dużo wolniejszy.
Nie wygląda na to, ale jeśli double precision wartości są pobierane z tabeli PostgreSQL gdzie indziej, możesz ustawić extra_float_digits
= 3 dzięki czemu masz gwarancję, że nie stracisz precyzji, gdy wartości zostaną przekonwertowane na ich reprezentację w postaci ciągu.