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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблемы с отбрасыванием дробной части, это что-то совсем странное... 
V
    Опции темы
Cheese
Дата 22.7.2009, 18:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Суть проблемы: надо из double сделать int, убрав дробную часть. Казалось, бы всего ничего, преобразовать в int, но не работает, причём выдаёт воистину чудовищный результат: 6.000000 превращается в 5. Подозреваю, что тут что-то с точностью, так как если сделать не double а long double проблема исчезает. На некоторое время, потому что если взять число побольше, опять n превращается в n-1. Пробовал не (int) y, а floor(y) - та же проблема. 
Вот пример, чтобы не быть голословным:

Код

#include <stdio.h>
int main()
{
    int i;
    double y = 0;
    int dx = 5;
    int dy = 3;
    double k = (double) dy/dx;
    for ( i=0; i<11; i++, y+=k )
    printf( "y = %f, y_rounded = %i\n", y, (int) y );
}


Здесь формируется игрик, через складывание множества дробных чисел. При этом программа выдаёт:

Код

y = 0.000000, y_rounded = 0
y = 0.600000, y_rounded = 0
y = 1.200000, y_rounded = 1
y = 1.800000, y_rounded = 1
y = 2.400000, y_rounded = 2
y = 3.000000, y_rounded = 3
y = 3.600000, y_rounded = 3
y = 4.200000, y_rounded = 4
y = 4.800000, y_rounded = 4
y = 5.400000, y_rounded = 5
y = 6.000000, y_rounded = 5


Последняя строка убивает. Товарищи, в чём дело?
Работаю в линуксе, через gcc.

Это сообщение отредактировал(а) Cheese - 22.7.2009, 18:55
PM MAIL   Вверх
Фантом
Дата 22.7.2009, 19:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вы это прекратите!
***


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

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



Ну да, проблема с точностью. Если нужно так обрабатывать только числа, фактически являющиеся целыми, то просто прибавляйте 0.5 перед отбрасыванием дробной части.
PM   Вверх
Леопольд
Дата 22.7.2009, 21:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Cheese @ 22.7.2009,  18:55)
Код

...
y = 6.000000, y_rounded = 5


Последняя строка убивает. Товарищи, в чём дело?
Работаю в линуксе, через gcc.

Похоже на то что printf округляет значение. Выглядит правдоподобно, если, например, y = 5.9999999

Я угадал. Попробуй это:
Код

#include <stdio.h>

int main()
{
    int i;
    double y = 0;
    int dx = 5;
    int dy = 3;
    double k = (double) dy/dx;
    for ( i=0; i<11; i++, y+=k )
    printf( "y = %.20f, y_rounded = %i\n", y, (int) y );
}


Правильнее будет сделать так:
printf( "y = %.20f, y_rounded = %.0f\n", y, y );

Это сообщение отредактировал(а) Леопольд - 22.7.2009, 21:56


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
codelord
Дата 23.7.2009, 11:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 777
Регистрация: 7.5.2005
Где: ты моя темноглаза я где?!

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



Код

#include <math.h>
long dround( double x )
{
        return (long)round(x);
}




--------------------
Доступен поиск по исходным кодам в GOOGLE.
http://www.google.com/codesearch
PM MAIL   Вверх
PirateTigo
Дата 1.8.2009, 23:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



у Вас написано так:
Код

printf( "y = %.20f, y_rounded = %i\n", y, (int) y );


а если попробовать так:
Код

printf( "y = %.20f, y_rounded = %d\n", y, (int) y );


?

Это сообщение отредактировал(а) PirateTigo - 1.8.2009, 23:45
PM MAIL ICQ Skype   Вверх
VC15
Дата 4.8.2009, 17:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Да, дело здесь именно в том, что printf округляет. Поэтому на самом деле в y хранится 5.99999999, а выводится 6.0000. Чтобы избавиться от этой проблемы, я предлагаю использовать printf( "y = %f, y_rounded = %i\n", y, int(y + 1e-9) );

Это сообщение отредактировал(а) VC15 - 4.8.2009, 17:28
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.0992 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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