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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Странная арифметика, у хитрого злобного double 
:(
    Опции темы
keisik
  Дата 25.10.2002, 19:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Есть вот такая пргораммка, для разбиения суммы на составляющие:
Код
void main(void)
{
int i=0, v[13];
double t,z,b1[13]={500,200,100,50,20,10,5,1,0.5,0.25,0.1,0.05,0.01};
z=23.24;//это сумма
do{
v[i]=z/b1[i];
t=v[i]*b1[i];
z=z-t;
i++;
}while (i<13);
for(i=0;i<8;i++){
if (v[i]!=0) printf("\n Банкнот %.0lf $ - %d", b1[i],v[i]);
}
for (i=8;i<13;i++){
if (v[i]!=0) printf("\n Монет %.0lf $ - %d\n", b1[i]*100,v[i]);
}
}

Внимание, вопрос:
Сумма 23.24 разбивается неправильно, ибо в момент, когда в Z остаётся 0,24 $, и пытаемся пооделить на 0.10 происходит следующее:
v[i]=z/b1[i];//z=0.24, b1[i]=0.10,v[i] соответственно остаётся 2
t=v[i]*b1[i];//t=2*0.10 и равно 0.20
z=z-t;//а вот тут самое интересное, z=0.24-0.20 и равно не 0.04 как хотелось бы надеяться, а 0.039999998 или что-то в этом роде.
Почему?
При том что сумму 3.24 обрабатывает нормально.
ЗЫ: Проверено и в VC и в Билдере, и там и там одинаково.
--------------------
...None of that can stop us now,we will make it through somehow...
PM MAIL   Вверх
Fantasist
Дата 26.10.2002, 02:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


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

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



А потому, что двоичное представление реальных чисел не всегда может отразить точно десятичное представление. То есть переменные типа double имеют ограниченную точность.  Что бы понять почему так, тебе нужно прочитать где-нибудь о форме представления double в памяти.


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


Gothic soul
****


Профиль
Группа: Модератор
Сообщений: 3041
Регистрация: 25.3.2002
Где: Верхняя Галилея, Кармиэль

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



У чисел с одинарной точностью - 1 бит знак, 8 бит степень, 23 бит мантисса. Чтобы перевести в десятичное значение, надо отнять от степени 127, сдвинуть на получившееся число знаков запятую в мантиссе, перевести отдельно целую ио дробную часть, поставить знак.
У чисел с двойной точностью - 1 бит знак, 8 бит степень, 53 бит - мантисса. Алгоритм перевода такой же.


--------------------
The truth comes from within ...

Покойся с миром, Vit 
PM MAIL WWW ICQ Skype GTalk   Вверх
keisik
Дата 28.10.2002, 18:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Спасибо, буду знать.
Весьма ненадёжные товарищи получается эти реальные числа...
--------------------
...None of that can stop us now,we will make it through somehow...
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.0399 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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