Осторожно, C++Builder 5 и double
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено Отделение 13 08 августа 2003 г. 11:00

Если функция, возвращающая значение типа double, объявлена __fastcall, то Builder возвращает значение в регистрах математического сопроцессора. При этом возвращается не double, а long double. Вроде бы это даже лучше :). Однако это может привести к странным результатам, например:

double __fastcall foo(double v1, double v2)
{
return v1 / v2;
}
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
double v1 = 1.0;
double v2 = 3.0;
double r1 = foo(v1, v2);
if (r1 != foo(v1, v2))
Label1->Caption = "Не может быть";
else
Label1->Caption = "Все в порядке";
}

После первого вызова функции foo() компилятор округляет long double до double и сохраняет в переменной r1. После второго вызова результат long double не приводится к double, а тут же сравнивается в FPU с переменной r1. И если после первого вызова результат округлялся, то получим странный результат. В данном случае (1 / 3) != (1 / 3).
Этого эффекта (скорее дефекта :) можно избежать, если ввести промежуточную переменную:

...
double r2 = foo(v1, v2);
if (r1 != r2)
Label1->Caption = "Не может быть";
else
Label1->Caption = "Все в порядке";

Здесь как раз "Все в порядке".
Такая же ерунда должна быть и с float, кто хочет проверьте.

Составить ответ  |||  Конференция  |||  Архив

Ответы



Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание  |||  Без кадра

E-mail: info@telesys.ru