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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Ошибка Debugger Exception Notification 
V
    Опции темы
odys
Дата 17.11.2008, 20:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Программа предназначена для вывода дробной части числа - если таковая имеется, либо само число, если она отсутствует. Она работает у меня на значениях до 2 порядка, при больших выдает непонятную ошибку...
Все бы ничего если бы эта прога не была частью большей - в которой тоже самое - но там вообще ничего не обрабатывает, при той же ошибке - вот код
  
Код

 #include <iostream.h>


int obrabotka(double);
main()
{
 int x, z;
 double y;

 cout<<" Input value ";
 cin>>y;
 z = obrabotka(y);  //Функция разбирает введен у нас int или double
 cout<<endl<<" Chislo posle obrabotki = "<<z<<endl; //если int то возращается
 cin>>x; // Оно же, если double - то его дробная часть.
return 0;
}
int obrabotka(double x)
{
 int q = 1;
 int m = x;
 double z = x - m;

 if (z < 0.000001)
    {
     q = x;
    }
 else
    {
    int t = 0;
    while ((z - t) > 0.000001)  //Проверка наличия чисел после запятой
       {
        q = z*10;  // и нахождение не целовй части.
        z*=10;
        t = z;
       }


    }
 return q;
}

Выдает 
Project Project1.exe raised exception class EOverlow with message 'Floating point overlow'. Process stopped. Use step or run to continue.
Закрыл... открыл... теперь не работает при более 3 знаках... в общем не понятна мне причина сией ошибки.
PM MAIL   Вверх
sQu1rr
Дата 17.11.2008, 22:25 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Код

main()

странно - обычно int main(), к тому же заканцивется
Код

return 0;

Разумеется это не причина ошибки ))

И вообще ты слишком много всего наделал. Можно было проще
и кстати насколько я понял
Код

cin>>x;

в конце main() - что бы оставить окно на экране. Лучше используй cin.get() или getch() (для старых комиляторов)
Вот тебе пример твоей функции, как я бы сделал (надеюсь я правильно понял - человек вводит число - если оно дробное, то программа показывает только часть после запятой, в противном случае только целую часть)
Код

__int64 obrabotka(double & x)            // __int64 - не 4, а 8 байтов -> 20зн число (для
{                                        // большей точности
    __int64 integ = __int64(x);            // урезание дробной части
    if(x != double(integ)) {            // проверка на дробность
        x -= double(integ);                // отнимаем целую часть
        __int64 temp = 10;                // считаем цифры целой части
        while(integ != 0) {
            integ /= temp;
            temp *= 10; }                   
        integ = __int64( x * temp ); }    // присваиваем дробную часть переменной
    return integ;
}
/*
Если не обязательна точность 20 цифр, то можешь на int заменить (но там точность 9цифр, а double без дробной части 15 позволяет ;) )
*/


Что хочу сказать: все уперается в точность double (если более 5 цифр в целой части, то дробная имеет максимум 4 (без округления). Так что лучше вместо double испоьзовать два __int64 (один для дробной другой для целой (ну разумеется программа для перевода char в 2 __int64) (__int64 это long long - если так удобнее).

Между прочим не твоя ни моя программа не будет выводить нули после точки xD. т.к. int с не может начинаться с нулей, так что придумай алгоритм получше ;)

Вот мужду прочим твоя ощибка
Код

    while ((z - t) > 0.000001)  //Проверка наличия чисел после запятой
       {
        q = z*10;  // и нахождение не целовй части.
        z*=10;
        t = z;
       }

Что ты делаешь?
        1. Пока Число I - II больше чем 0.00000001 повторять следующие действия
        2. Рузельтат сделать числом I, умноженое на 10 (+1 целая цифра)
        3. Число I умножить на 10 (+1 целая цифра)
        4. Число II сделать равным числу I
        -  Идем к первому пункту (т.к. число I будет равно числу II) - циклю будет бесконечным!
        -  До четырех цифр проходило из-за специфического хранения переменных типа double. Когда дробная часть небольшая, то она на самом деле содержит к примеру не 3 числа а больше, просто в результате они округляются, а при сравнении - разные числа
        -  Если этот же цикл использовать не для double а для другой дробной переменной (ну скажем самостоятельно созданной (с правильно выполненым хранением дробной части), то этот цикл будет бесконечным со всеми дробными частями!

Это сообщение отредактировал(а) sQu1rr - 17.11.2008, 22:49
PM MAIL Skype GTalk   Вверх
odys
Дата 18.11.2008, 10:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



sQu1rr
спасибо... вы мне многое объяснили.
Похоже прийдется сначала доработать эту программу, прежде чем переходить к моделированию черепашъего движения.
насчет cin>>x; - учебники обычно деликатно обходят этот вопрос стороной - поэтому приходилось кустарными методами.
PM MAIL   Вверх
odys
Дата 18.11.2008, 11:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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




насчет cin.get();
а getch() идет как синтакс ошибка.
в данном примере - не рабоает
Код

#include <iostream.h>
void cubeAll (int *, int *, int *);
int main()
{
int x, y, z, f;
cout<<" Vvedite x, y, z "<<endl;
cin>>x>>y>>z;
cubeAll (&x, &y, &z);
cout<<"x = "<<x<<" y = "<<y<<" z = "<<z;
cin>>f;
//cin.get();
//getch();
return 0;
}
void cubeAll (int *xPtr, int *yPtr, int *zPtr)
{
 *xPtr = *xPtr * *xPtr * *xPtr;
 *yPtr = *yPtr * *yPtr * *yPtr;
 *zPtr = *zPtr * *zPtr * *zPtr;
}




Это сообщение отредактировал(а) odys - 18.11.2008, 17:05
PM MAIL   Вверх
sQu1rr
Дата 18.11.2008, 16:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(odys @ 18.11.2008,  11:04)
насчет cin.get();
а getch() идет как синтакс ошибка.
в данном примере - не рабоает
Код

#include <iostream.h>
void cubeAll (int *, int *, int *);
int main()
{
int x, y, z, f;
cout<<" Vvedite x, y, z "<<endl;
cin>>x>>y>>z;
cubeAll (&x, &y, &z);
cout<<"x = "<<x<<" y = "<<y<<" z = "<<z;
cin>>f;
//cin.get();
//getch();
return 0;
}
void cubeAll (int *xPtr, int *yPtr, int *zPtr)
{
 *xPtr = *xPtr * *xPtr * *xPtr;
 *yPtr = *yPtr * *yPtr * *yPtr;
 *zPtr = *zPtr * *zPtr * *zPtr;
}

Ну разумеется...
getch() - это доисторическая версия borland компилятора - я дал просто так (вдруг вы историк или чтото типо того  smile  )

cin.get() - просит ввод (маскимум одного ( так как скобки пустые ) ) символа

тпереь рассмотрим cin >> x;
все что вводится с клавиатуры cin воспринимает, если вы заметели БЕЗ пробелов и БЕЗ конца строки -> если вы введете число 55648, что обозначает грубо говоря char * unnamed = "55648\0", то cin возьмет 55648, а /0 оставит в бефере. Это не беда, так как следующий cin >> y; тоже пропустит мимо этот символ, но вот cin.get() - воспринимет все символы -> оставшийся в буфере символ введется и программа завершится.
Что бы исправить в конце нужо написать cin.get() 2 раза подрят, либо кадый раз после cin >> x; придется писать cin.get()

следовательно или так:
Код

int main()
{
int x;
cin >> x;
cout << x;
cin.get();
cin.get();
}

или так:
Код

{
int x;
cin >> x; 
cin.get();
cout << x;
cin.get();
}


Лучше исползовать второй варинат, чтобы не запустаться smile

Добавлено через 14 минут и 35 секунд
Кстати можешь использовать system("pause") - для того же эффекта

Это сообщение отредактировал(а) sQu1rr - 18.11.2008, 16:53
PM MAIL Skype GTalk   Вверх
odys
Дата 18.11.2008, 17:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Спасибо за задачу) ваша программа работает весьма запутанно... теперь пытаюсь понять почему.
Выводит оно дробную часть исправно - но с особенностями.
1. Если целая часть маленькая тобиш первого порядка - выводится не более 2 знаков после запятой.
2. Если целая часть большая порядка 10 в 4-6 степени - выводятся 4 знака после запятой...
В общем делаю для себя... так что времени подумать уйма) спасибо за подсказку с __int64
PM MAIL   Вверх
sQu1rr
Дата 18.11.2008, 18:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Да, есть у меня ошибочка могу даже подсказать какая:
     Что бы выдернуть дробное число, я его умножаю на некое число, кратное 10
      Как я его должен получить? 10 в степени равной кол-ву чисел после запятой
      Как я его наше? 10 в степени равной кол-ву чисел перед запятой.
Так что удачи в исправлние. Извини за ошибку - спешил ;)
PM MAIL Skype GTalk   Вверх
sQu1rr
Дата 19.11.2008, 00:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Вот поработал минут 15, сделал более приемлимую версию. Принимает до 19 знаков с каждой стороны точки... Если знаков больше, то число округляется
Код

#include <iostream>
#include <string>
#include <cstdlib>
#include <algorithm>
using namespace std;

__int64 _func_num_(const string & value);
__int64 _function_(const string & value);

int main()
{
    string value;
    while(value != string("quit")) {
        cout << "Enter your value: ";
        cin >> value; cin.get();
        cout << "\nAfter function appliyng: " << _function_(value) << endl;
        system("pause");
        system("cls"); }
    return 0;
}

__int64 _function_(const string & value)
{
    // сюда неплохо вставить функцию, проверяющую на допустимые символы и на неповторение
    // точки _some_function_(const string & value); 
    __int64 result;
    int _dot = -1;
    for(int i = 0; i < int(value.size()); i++)
        if(value[i] == '.')
            _dot = i + 1;
    if(_dot != -1) {
        string temp; 
        copy(value.begin() + _dot,value.end(),insert_iterator<string>(temp,temp.begin()));
        result = _func_num_(temp); }
    else
        result = _func_num_(value);
    return result;
}

__int64 _func_num_(const string & value)
{
    bool bOne = false;
    char * temp;
    if(value.size() > 19) {
        temp = new char[20];
        temp[19] = '\0';
        copy(value.begin(),value.begin()+19,temp);
        if(value[19] > 4)
            bOne = true;  }
    else {
        temp = new char[value.size()+1];
        temp[value.size()] = '\0';
        copy(value.begin(),value.end(),temp); }
    __int64 result = _atoi64(temp);
    if(bOne)
        result++;
    return result;
}


Это сообщение отредактировал(а) sQu1rr - 19.11.2008, 00:02
PM MAIL Skype GTalk   Вверх
odys
Дата 21.11.2008, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Да, спасибо, программа действительно работает замечательно. Буду тоже учиться писать в хорошем стиле.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0505 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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