W Twoim kodzie są dwa błędy:
-
Próbujesz wysłać dane binarne, ale nie mówisz
PQexecParams
jaki to jest typ.To nie może działać. Brak informacji o typie PostgreSQL użyje typu
unknown
i traktuj to jako ciąg. Oznacza to, że twoja binarna reprezentacja zostanie przekazana dofloat8in
funkcja, 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 (lubFLOAT8OID
jeśli wolisz używać#define
PostgreSQLa , ale musiałbyś#include <postgres.h>
i<catalog/pg_type.h>
za to). -
Błędnie zakładasz, że binarna reprezentacja PostgreSQL
double precision
type to format binarny dladouble
w 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_sendfloat8
wsrc/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.