Помогите разобраться. У меня есть код, в котором я подключаю проверку на переполнение типа double с помощью функции _finite() относительно математических операций, а не через присваивание переменных. В консоли для z выводит ошибку OVERFLOW error. Возможно ли в этом случае обойтись без обработки исключений? Компилятор - C++Builder 6. Буду очень благодарен.
#include
int main (void)
{
double x = 10E200;
double y = 10E400;
double z = pow(x, 2);
if(_finite(x) != 0)
{
cout << "This is finite number: " << x << endl;
}
else cout << "This is infinity: " << x << endl;
if(_finite(y) != 0)
{
cout << "This is finite number: " << y << endl;
}
else cout << "This is infinity: " << y << endl;
if(_finite(z) != 0)
{
cout << "This is finite number: " << z << endl;
}
else cout << "This is infinity: " << z << endl;
system("pause");
}
Update: Это моя вина, многие не поняли, чего я хотел, поэтому добавлю второй пример. Через pow() или x * x выводит ошибку о переполнении. Как мне корректно проверить условие, чтобы не выводило ошибку?
#include
int main (void)
{
double x;
char str[] = "Введите число, которое мы будем возводить в степень: ";
CharToOem(str,str);
cout << str;
cin >> x;
int check = 0; // флаг переполнения
do
{
if(_finite(pow(x, 2)) != 0)
{
x = pow(x, 2);
cout << x << endl;
}
else check = 1;
}
while(check == 0);
system("pause");
}
Ответ
Через pow() или x * x выводит ошибку о переполнении. Как мне корректно проверить условие, чтобы не выводило ошибку? Если я ничего не путаю: ( a * e ^ x ) * ( b * e ^ y ) = c * e ^ ( x + y + z ), где z - экспонента получаемая при перемножении a на b, а c - остаточная мантисса от этой операции. Т.е. чтобы определить, будет ли переполнение, можно просто умножить целочисленную экспоненту на n (показатель степени - второй параметр функции pow) и проверить, выходит ли это значение за пределы используемого диапазона ( для double - это 1024). Если не выходит, нужно выделить остаточную экспоненту от квадрата мантиссы, добавить к ней вычисленное ранее произведение и проверить на выход за границы снова. Вобщем - достаточно муторно, но не смертельно. Чтобы выделить остаточную экспоненту, нужно выполнить целочисленное умножение 64-битных мантисс. Предварительно, нужно маской удалить из них экспоненту (те самые 11 бит) и привести обратным кодом в натуральный диапазон. После умножения - обнулить старший бит, и посчитать число правых сдвигов результата до того момента, пока эти 11 бит не обнулятся. Число этих сдвигов и дают остаточную экспоненту. p.s.: экспоненты - тоже знаковые, это следует учитывать при их сложении, вернее - при проверке на выход за пределы границ диапазона (для этого, надо перевести 11-битную экспоненту в short, заполняя оставшиеся 5 старших бит значением старшего бита этой экспоненты).
Комментариев нет:
Отправить комментарий