powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / ntohl и значения типа float
14 сообщений из 14, страница 1 из 1
ntohl и значения типа float
    #35653284
Koldun451
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Помогите пожалуйста решить проблему.
Проблема в считывании из таблицы значений типа float:

char *ID_ptr;
char *Password_ptr;
char *Time_ptr;

ID_ptr = PQgetvalue(res, i, ID_fnum);
Password_ptr = PQgetvalue(res, i, Password_fnum);
Time_ptr = PQgetvalue(res, i, Time_fnum);
//Здесь все ОК. Переворачиваем припомощи ntohl, получаем что надо.
unsigned long A = (unsigned long)ntohl(*((long*)ID_ptr));
int B = ntohl(*((int*)Password_ptr));

//А здесь косяк. Значения получаются все, корме нужного

float C = ntohl(*((float*)Time_ptr));

А во всей документации упорно все приводиться к int-ам
...
Рейтинг: 0 / 0
ntohl и значения типа float
    #35654211
Quadrix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А какой текст в Time_ptr ? Может быть проблема в локали, т.е. если у тебя там вещественное число в виде строки с точкой приходит, а надо с запятой, например.
...
Рейтинг: 0 / 0
ntohl и значения типа float
    #35654272
Koldun451
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Пробовал и целые и с запятой и с точной. Все не то).
...
Рейтинг: 0 / 0
ntohl и значения типа float
    #35654685
Фотография Ёш
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Koldun451//А здесь косяк. Значения получаются все, корме нужного

float C = ntohl(*((float*)Time_ptr));а почему это должно работать ?

Код: plaintext
1.
2.
3.
4.
       uint32_t htonl(uint32_t hostlong);
       uint16_t htons(uint16_t hostshort);
       uint32_t ntohl(uint32_t netlong);
       uint16_t ntohs(uint16_t netshort);
сдесь нет float. У Вас во первых происходит срезание дробной части при вызове (float->int), а при возврате из ntohl ваш float интерпретируется как uint32_t и получается не мантиса и степень а мантиса и степень интерпретируются как одно целое число uint32_t (которое в битовом представлении соответсвует битам float) которое потом присваивается float C - то есть ничего общего не имеющее с исходным числовым float значением.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>

int main()
{
        float f =  123 . 456 ;
        float *pf = &f

        float C = ntohl(*pf);
        uint32_t r = ntohl(*pf);

        printf("[sizeof float %u] f: %f | (uint32_t)(*((float*) pf)): %08X (%u) | C: %f (%08X %u) | C as int: %08X\n",
                sizeof f,
                f, // исходное значение
                (uint32_t)(*((float*) pf)), // то что у Вас происходит при вызове - обрезание дробной части, приведение к uint32_t
                (uint32_t)(*((float*) pf)), // то что у Вас происходит при вызове - обрезание дробной части, приведение к uint32_t
                C, // результат, uint32_t результата приведён к float
                r, // результат - перевёрнутое битовое представление дробного числа приведённого к целому
                r, // результат - собственно само значение в виде целого числа, оно то как раз равно Вашему C
                *((uint32_t*) &C) // битовое представление результата
        );

        return  0 ;
}

Код: plaintext
1.
2.
3.
seb@seb:/tmp/o$ gcc --std=c99 -W -Wall -Wextra -pedantic ttt.c -o ttt
seb@seb:/tmp/o$ ./ttt
[sizeof float 4] f: 123.456001 | (uint32_t)(*((float*) pf)): 0000007B (123) | C: 2063597568.000000 (7B000000 2063597568) | C as int: 4EF60000
...
Рейтинг: 0 / 0
ntohl и значения типа float
    #35654782
Koldun451
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо огромное. Все понятно, теперь точно разберусь.
...
Рейтинг: 0 / 0
ntohl и значения типа float
    #35654851
Фотография Ёш
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ещё как заметил Quadrix - float скорее всего передаётся в виде строки, и в pg_dump.c есть такой кусок:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
case FLOAT4OID:
case FLOAT8OID:
case NUMERICOID:
        {
                /*
                 * These types are printed without quotes unless
                 * they contain values that aren't accepted by the
                 * scanner unquoted (e.g., 'NaN').      Note that
                 * strtod() and friends might accept NaN, so we
                 * can't use that to test.
                 *
                 * In reality we only need to defend against
                 * infinity and NaN, so we need not get too crazy
                 * about pattern matching here.
                 */
                const char *s = PQgetvalue(res, tuple, field);

                if (strspn(s, "0123456789 +-eE.") == strlen(s))
                        archprintf(fout, "%s", s);
                else
                        archprintf(fout, "'%s'", s);
        }
        break;
то есть (судя по strspn и strlen) там таки строковое представление float, а не четыре бинарных байта float.


--
„Истина — это вовсе не то, что можно убедительно доказать, это то, что
делает всё проще и понятнее“ — Антуан де Сент-Экзюпери
...
Рейтинг: 0 / 0
ntohl и значения типа float
    #35655154
Koldun451
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
т.е. получается, просто считать значения типа float4(8) из Постгресса функцией PQgetvalue в переменную типа float никак нельзя(((((?
...
Рейтинг: 0 / 0
ntohl и значения типа float
    #35655341
Фотография Ёш
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
sscanf(PQgetvalue(res, i, Time_fnum), "%f", &C);
так не работает ?


--
„Истина — это вовсе не то, что можно убедительно доказать, это то, что
делает всё проще и понятнее“ — Антуан де Сент-Экзюпери
...
Рейтинг: 0 / 0
ntohl и значения типа float
    #35655360
Koldun451
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Нет, как ни странно, даже вообще не меняет первоначальное значение C.
...
Рейтинг: 0 / 0
ntohl и значения типа float
    #35655718
Koldun451
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Нет, вообще никак не выходит.

Если только обрезать дробную часть и приводить к целому, как уже оговаривалось.
Вообще как-то странно, что такая возможность не предусмотрена явно. Не свои же типы данных вводить самом деле, а забивать на точность ну никак нельзя(((
...
Рейтинг: 0 / 0
ntohl и значения типа float
    #35656008
Фотография Ёш
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Koldun451, как Вы выполняете запрос ? через PQexec или через PQexecParams ? покажите. Возможно у Вас просто NULL в Time ? Какой тип у поля Time ?
...
Рейтинг: 0 / 0
ntohl и значения типа float
    #35656011
Фотография Ёш
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
http://www.postgresql.org/docs/current/static/libpq-example.html

читали ?


--
„Истина — это вовсе не то, что можно убедительно доказать, это то, что
делает всё проще и понятнее“ — Антуан де Сент-Экзюпери
...
Рейтинг: 0 / 0
ntohl и значения типа float
    #35666949
Koldun451
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть в аналах Postgres еще функции)))))))

void pq_sendfloat4(StringInfo buf, float4 f)
...
Рейтинг: 0 / 0
ntohl и значения типа float
    #35666958
Koldun451
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А лучше, наверное, выдрать цельные ее кусок)))

union
{
float4 f;
uint32 i;
} swap;

swap.f = f;
swap.i = htonl(swap.i);
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / ntohl и значения типа float
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]