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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Перевод форматированной строки в double и обратно, Программа не работает с одним значением 
:(
    Опции темы
NeuZeitgeist
Дата 10.5.2009, 10:27 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Помогите найти ошибку в программе.
Задача: ввести строку в формате $345,456.67, перевести ее в double в виде 345456.67 (два знака после запятой), затем перевести это число снова в строку формата $345,456.67
Сделал класс, где есть два метода. Один double mstold() переводит строку в десятичное число, второй - void ldtoms(double) переводит число в форматированный массив строк.
Вроде все работает за исключением самого большого числа $1,123,123,123,123,123.12 
При таком значении неправильно переводит числа после запятой. Помогите, пожалуйста, найти ошибку. Заранее спасибо smile

Код

/*
Задача: перевод форматированной строки в double и обратно. $345,456.67 -> 345456.67 и 345456.67 -> $345,456.67
Проблема: неправильно работает со значением $1,123,123,123,123,123.12
*/
#include<iostream>
#include<stdlib.h>
#include<math.h>
#include <iomanip>

using namespace std;
const int M = 26;

class money
{
    private:
        char mon_ch1[M];//куда вводится денежная строка пользователем
        char mon_ch2[M];//куда выводится денежная строка на экран
        double mon_d;//деньги-число
    public:
        double mstold();//метод перевода строки в десятичное число
        void ldtoms(double);//метод перевода числа в массив строк
        void output()//метод вывода на экран форматированного числа (массива mon_ch2)
        {   cout << mon_ch2 << endl;    }
};

int main()
{
    money mon;
    double m;
    char otvet;
    do
    {
    //вводим число, вызывая функцию mstold и приводя его к типу double
    cout << "Vvedite chislo v formate $1,123,456.45" << endl;
    m = mon.mstold();
    cout << "\nChislo tipa double ravno " << fixed << setprecision(2) << m << endl;
    //передаем это же число в функцию ldtoms, переводим его к типу char и форматируем
    mon.ldtoms(m);
    cout << "Chislo char ravno "; mon.output(); cout << endl;
    cout << "Prodoljit'?";
    cin >> otvet;
    } while(otvet != 'n');
    return 0;
}

double money::mstold()
{
    unsigned int i = 0;
    unsigned int j = 0;
    cin >> mon_ch1;
    for(i = 0; i < strlen(mon_ch1); i++)
    if((mon_ch1[i] >= '0' && mon_ch1[i] <= '9') || mon_ch1[i] == '.')
    {
        mon_ch2[j] = mon_ch1[i];
        j++;
    }
    mon_ch2[j] = '\0';
    mon_d = strtod(mon_ch2, NULL);
    printf ("\nChislo mon_d ravno %.2lf\n", mon_d);
    return mon_d;
}

void money::ldtoms(double t)
{
    //переводим double в char
    sprintf(mon_ch1, "%.2lf", t);//выполняет форматрированный вывод в строку
    cout << "Massiv char soderjit " << mon_ch1 << endl;
    //форматируем массив char
    int i = 0, j = 0, temp1, temp2;
    //Находим длину строки в первом массиве (temp1)
    while(mon_ch1[i] != '\0') i++;
    temp1 = i;
    cout << "temp1 ravno " << i << endl;
    j = M-1;
    for(temp1 = i; temp1 >= 0;)
    {
        mon_ch2[j] = mon_ch1[temp1];
        j--;
        temp1--;
        if(j == 18 || j == 14 || j == 10 || j == 6 || j == 2)
        {
            if(temp1 >= 0)
            {
                mon_ch2[j] = ',';
                j--;
            }
        }
    }
    mon_ch2[0] = '$';
    temp2 = j+1;
    cout << "temp2 = " << temp2 << endl;
    for(j = 1; mon_ch2[temp2] != '\0'; j++ && temp2++)
        mon_ch2[j] = mon_ch2[temp2];
    mon_ch2[j] = '\0';
}

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


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



читать описание стандартных функций: setlocale, printf, scanf
В принципе, потоки в C++ тоже корректно работать должны после вызова setlocale.
Кстати, ты уверен, что тебе точности double хватит? Ведь для работы с деньгами используют алгоритмы бесконечной точности.
PM   Вверх
NeuZeitgeist
Дата 11.5.2009, 22:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(bsa @ 11.5.2009,  19:51)
Кстати, ты уверен, что тебе точности double хватит? Ведь для работы с деньгами используют алгоритмы бесконечной точности.

Не уверен, что хватит double. Но с long double у меня почему-то не работает. Компилятор gcc выдает ошибки по форматированию.
Про алгоритмы для денег я пока ничего не знаю, т.к. осваиваю азы.
Мне уже объяснили, что проблема в переполнении double, но почему то компилятор дурит и с long double. Постараюсь еще покрутить, в чем там дело.
Спасибо большое за советы по функциям.
PM   Вверх
bsa
Дата 12.5.2009, 21:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



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

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

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

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

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


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

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


 




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


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

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