Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> почему 5+5=-2 ? 
V
    Опции темы
Larrikin
Дата 28.9.2007, 12:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 58
Регистрация: 15.8.2007

Репутация: нет
Всего: нет



есть такой код
Код

// Гарантируем возврат хоть какого-нибудь результата
        if ( best.is_null ){
            best.id1 = n[1].id;
            best.id2 = n[1].id;
            best.act = '+';
            printf("id(1) value(%lf)\n",n[1].value);
            best.result = (n[1].value + n[1].value);
            best.err = fabs( n[0].value - best.result );
            best.is_null = false;
        }
        printf("best: id1(%li) id2(%li) act(%c) result(%lf) err(%lf)\n",
            best.id1, best.id2, best.act, best.result, best.err);



выдает:

id(1) value(5.000000)
best: id1(-1) id2(-1) act(+) result(-2.000000) err(0.000000)

каким образом пять плюс пять получается минус два и как с этим бороться? не могу придумать в какую сторону гуглить...
-2 может получиться, если складывать не n[1].value, а n[1].id - только с какой радости это может происходить?


описание сделано в файле ncalc.h

Код

#include <stdio.h>
#include <stdbool.h>
#include <tgmath.h>

// Сколько строк данных мы готовы переварить
// TODO: сделать опцией командной строки
#define MAX_DATALINE 100

// приходящие данные должны содержать целое и дробное число
struct dataline{
    long int id;
    long double value;
};

// общий массив для данных
struct dataline n[MAX_DATALINE + 1];

// в такой форме будем искать результат
struct new{
    long int id1;
    long int id2;
    char act;
    long double result;
    long double err;
    bool is_null;
};

// общая для лучшего предложения
struct new best;

PM MAIL WWW ICQ   Вверх
comcon1
Дата 28.9.2007, 12:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 11.6.2005
Где: Москва ДАС-МГУ

Репутация: 12
Всего: 17



Бред какой-то. Вот эта строчка меня смущает...
Код

struct new{

разве можно называть структуру ключевым словом??? или я чот не в теме
переназови тип и выведи так:
Код

// Гарантируем возврат хоть какого-нибудь результата
        if ( best.is_null ){
            best.id1 = n[1].id;
            best.id2 = n[1].id;
            best.act = '+';
            printf("id(1) value(%lf)\n",n[1].value);
            printf("idsum0 (%lf)\n",n[1].value + n[1].value);
            best.result = (n[1].value + n[1].value);
            printf("idsum1 (%lf)\n", best.result);
            best.err = fabs( n[0].value - best.result );
            best.is_null = false;
        }
        printf("best: id1(%li) id2(%li) act(%c) result(%lf) err(%lf)\n",
            best.id1, best.id2, best.act, best.result, best.err);



--------------------
PM MAIL   Вверх
Larrikin
Дата 28.9.2007, 12:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 58
Регистрация: 15.8.2007

Репутация: нет
Всего: нет



насчет ключеватости имени был не в курсе в-виду нубства в С, переделал в такое ncalc.h:

Код

#include <stdio.h>
#include <stdbool.h>
#include <tgmath.h>

// Сколько строк данных мы готовы переварить
// TODO: сделать опцией командной строки
#define MAX_DATALINE 100

// приходящие данные должны содержать целое и дробное число
struct dataline{
    long int id;
    long double value;
};

// общий массив для данных
struct dataline n[MAX_DATALINE + 1];

// в такой форме будем искать результат
struct willnew{
    long int id1;
    long int id2;
    char act;
    long double result;
    long double err;
    bool is_null;
};

// общая для лучшего предложения
struct willnew best;


код стал:
Код

// Гарантируем возврат хоть какого-нибудь результата
        if ( best.is_null ){
            best.id1 = n[1].id;
            best.id2 = n[1].id;
            best.act = '+';
            printf("id(1) value(%lf)\n",n[1].value);
            printf("idsum0 (%lf)\n",n[1].value + n[1].value);
            best.result = (n[1].value + n[1].value);
            printf("idsum1 (%lf)\n", best.result);
            best.err = fabs( n[0].value - best.result );
            best.is_null = false;
        }
        printf("best: id1(%li) id2(%li) act(%c) result(%lf) err(%lf)\n",
            best.id1, best.id2, best.act, best.result, best.err);



вывод:

id(1) value(5.000000)
idsum0 (-2.000000)
idsum1 (-2.000000)
best: id1(-1) id2(-1) act(+) result(-2.000000) err(0.000000)

PM MAIL WWW ICQ   Вверх
Ln78
Дата 28.9.2007, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 274
Регистрация: 25.11.2006

Репутация: 13
Всего: 15



А компилятор какой? Возможно, для long double нужно использовать формат Lf. Ну и просто, если есть возможность в отладчике посмотреть сами значения (не printf), то можно это сделать для локализации ошибки.
PM MAIL   Вверх
Larrikin
Дата 28.9.2007, 12:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 58
Регистрация: 15.8.2007

Репутация: нет
Всего: нет



> uname -rs
FreeBSD 6.2-STABLE
> ll
total 26
-rw-r--r--  1 larrikin  wheel  1330 Sep 28 12:46 best_plus.c
-rw-r--r--  1 larrikin  wheel  1684 Sep 28 14:05 best_plus.o
drwxr-xr-x  2 larrikin  wheel   512 Sep 27 21:56 data
-rw-r--r--  1 larrikin  wheel  1934 Sep 27 20:55 getdata.c
-rw-r--r--  1 larrikin  wheel  1812 Sep 28 14:05 getdata.o
-rwxr-xr-x  1 larrikin  wheel   356 Sep 27 21:21 lmake
-rw-r--r--  1 larrikin  wheel   950 Sep 28 09:49 main.c
-rw-r--r--  1 larrikin  wheel  1368 Sep 28 14:05 main.o
-rwxr-xr-x  1 larrikin  wheel  7758 Sep 28 14:05 ncalc
-rw-r--r--  1 larrikin  wheel   562 Sep 28 12:37 ncalc.h
> ./lmake
gcc -c best_plus.c getdata.c main.c -I /home/larrikin/files/ncalc
gcc -c best_plus.c getdata.c main.c -I /home/larrikin/files/ncalc
gcc -c best_plus.c getdata.c main.c -I /home/larrikin/files/ncalc
gcc  -o ncalc best_plus.o getdata.o main.o
>

Добавлено через 14 минут и 4 секунды
вот нашел вроде непонятную интересность:

Код

// Гарантируем возврат хоть какого-нибудь результата
        if ( best.is_null ){
            best.id1 = n[1].id;
            best.id2 = n[1].id;
            best.act = '+';
            printf("id(1) value(%lf)\n",n[1].value);
            printf("id(1) value(%lf)\n",n[1].value);
            printf("crazy %lf + %lf = %lf\n",n[1].value, n[1].value, n[1].value + n[1].value);
            printf("idsum0 (%Lf)\n",n[1].value + n[1].value);
            best.result = (n[1].value + n[1].value);
            printf("idsum1 (%lf)\n", best.result);
            best.err = fabs( n[0].value - best.result );
            best.is_null = false;
        }
        printf("best: id1(%li) id2(%li) act(%c) result(%lf) err(%lf)\n",
            best.id1, best.id2, best.act, best.result, best.err);



выдает

id(1) value(5.000000)
id(1) value(5.000000)
crazy 5.000000 + 0.000000 = 0.000000
idsum0 (nan)
idsum1 (-2.000000)
best: id1(-1) id2(-1) act(+) result(-2.000000) err(0.000000)


че за?
PM MAIL WWW ICQ   Вверх
akizelokro
Дата 28.9.2007, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Крокодил
**


Профиль
Группа: Участник
Сообщений: 761
Регистрация: 30.7.2007

Репутация: 1
Всего: 5



Поменяй формат вывода, вместо "%lf" поставь "%3.4e"


--------------------
a = a + b; b = a - b; a = a - b;
PM MAIL   Вверх
Larrikin
Дата 28.9.2007, 13:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 58
Регистрация: 15.8.2007

Репутация: нет
Всего: нет



какая-то бугага полная

Код

// Гарантируем возврат хоть какого-нибудь результата
        if ( best.is_null ){
            best.id1 = n[1].id;
            best.id2 = n[1].id;
            best.act = '+';
            printf("id(1) value(%3.4e)\n",n[1].value);
            printf("id(1) value(%3.4e)\n",n[1].value);
            printf("crazy %3.4e + %3.4e = %3.4e\n",n[1].value, n[1].value, n[1].value + n[1].value);
            printf("idsum0 (%3.4e)\n",n[1].value + n[1].value);
            best.result = (n[1].value + n[1].value);
            printf("idsum1 (%3.4e)\n", best.result);
            best.err = fabs( n[0].value - best.result );
            best.is_null = false;
        }
        printf("best: id1(%li) id2(%li) act(%c) result(%3.4e) err(%3.4e)\n",
            best.id1, best.id2, best.act, best.result, best.err);



id(1) value(5.0000e+00)
id(1) value(5.0000e+00)
crazy 5.0000e+00 + 3.3172e-315 = 6.6564e-116
idsum0 (-2.0000e+00)
idsum1 (-2.0000e+00)
best: id1(-1) id2(-1) act(+) result(-2.0000e+00) err(3.2379e-319)


Добавлено через 4 минуты и 26 секунд
может быть это из-за того, что машина выполняется под VMWare?
PM MAIL WWW ICQ   Вверх
akizelokro
Дата 28.9.2007, 13:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Крокодил
**


Профиль
Группа: Участник
Сообщений: 761
Регистрация: 30.7.2007

Репутация: 1
Всего: 5



Проверь тогда где у тебя 1(единица), а где l(буква лы).
Неа, все онрма. Уже посмотрел сам.

попробуй еще... рискну предложить на время Long double поменять на double

Это сообщение отредактировал(а) akizelokro - 28.9.2007, 13:40


--------------------
a = a + b; b = a - b; a = a - b;
PM MAIL   Вверх
Larrikin
Дата 28.9.2007, 13:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 58
Регистрация: 15.8.2007

Репутация: нет
Всего: нет



проверил все вхождения 1 и l - всё на местах...
PM MAIL WWW ICQ   Вверх
xvr
Дата 28.9.2007, 14:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(Larrikin @ 28.9.2007,  12:06)
есть такой код
Код

// Гарантируем возврат хоть какого-нибудь результата
        if ( best.is_null ){
            best.id1 = n[1].id;
            best.id2 = n[1].id;
            best.act = '+';
            printf("id(1) value(%lf)\n",n[1].value);
            best.result = (n[1].value + n[1].value);
            best.err = fabs( n[0].value - best.result );
            best.is_null = false;
        }
        printf("best: id1(%li) id2(%li) act(%c) result(%lf) err(%lf)\n",
            best.id1, best.id2, best.act, best.result, best.err);



выдает:

id(1) value(5.000000)
best: id1(-1) id2(-1) act(+) result(-2.000000) err(0.000000)


описание сделано в файле ncalc.h

Код

// приходящие данные должны содержать целое и дробное число
struct dataline{
    long int id;
    long double value;
};

В gcc long double выводится по формату Lf, а не lf:

man 3 printf:

Код

       Here, integer conversion stands for d, i, o, u, x, or X conversion.
 
       l      (ell) A following integer conversion corresponds to a long int or unsigned long  int
              argument,  or  a following n conversion corresponds to a pointer to a long int argu-
              ment, or a following c conversion corresponds to a wint_t argument, or a following s
              conversion corresponds to a pointer to wchar_t argument.
 
       L      A  following a, A, e, E, f, F, g, or G conversion corresponds to a long double argu-
              ment.  (C99 allows %LF, but SUSv2 does not.)
 

PM MAIL   Вверх
Larrikin
Дата 28.9.2007, 14:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 58
Регистрация: 15.8.2007

Репутация: нет
Всего: нет



Цитата(xvr @  28.9.2007,  15:06 Найти цитируемый пост)
В gcc long double выводится по формату Lf, а не lf:

да, похоже делов в этом, прочесал все файлы и стало выводить корректно ожидаемо...
PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0551 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.