Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Странная арифметика


Автор: keisik 25.10.2002, 19:00
Есть вот такая пргораммка, для разбиения суммы на составляющие:
Код
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 и в Билдере, и там и там одинаково.

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

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

Автор: keisik 28.10.2002, 18:23
Спасибо, буду знать.
Весьма ненадёжные товарищи получается эти реальные числа...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)