Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.82/55: Рейтинг темы: голосов - 55, средняя оценка - 4.82
6 / 6 / 3
Регистрация: 14.11.2016
Сообщений: 53

Округление числа до n знаков после десятичной точки

10.01.2017, 07:09. Показов 10728. Ответов 10

Студворк — интернет-сервис помощи студентам
Решил задачу для новичков по C++. Задача совсем для зелёных новичков, кто только-только начал изучать C++, и у меня есть ощущение, что её можно решить лучше. Нет ли каких-то замечаний по поводу моего решения? Нельзя ли её решить лучше, правильнее? Сражу скажу, что to_string использовать нельзя. Лично мне с моего непрофессионального взгляда кажется, что моё решение слишком длинное для такой элементарной задачи.

Задача:
Есть число: 2.7182818284590452353602875
Нужно округлить его до целых n.
Пример:
n=0, тогда ответ равен 3
n=25, ответ равен 2.7182818284590452353602875
n=13, ответ равен 2.7182818284590

Вот мой вариант: моё решение корректно, но, может быть, вы подскажите, как можно улучшить код.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <fstream>
#include <iostream>
using namespace std;
#include <stdlib.h>
#include <string>
#include <sstream>
 
int main(int argc, char* argv[])
{
    setlocale(LC_ALL, "rus"); // корректное отображение Кириллицы
    int i,c;
    string b="2.7182818284590452353602875";
        
    ifstream fin("input.txt"); // открыли файл для чтения
    ofstream fout("output.txt", ios_base::out | ios_base::trunc);
    fin >> i;
    if (i==0) {
        fout << 3;
        return 0;       
    }
    
    if (i==1){
        fout <<2.7;
        return 0;
    }
    
    if (i==25){
        fout << b;
        return 0;
    }
 
    c = b[i+2] - '0';   
    
    string answer;
    if (c<5){
        answer = b.substr(0,i+2);
    }
    else{
        ostringstream temp;
        int c = b[i+1] - '0';
        temp << c+1;
        string f = temp.str();
        answer = b.substr(0,i+1)+f;
    }
    
    
    fout << answer;   
  
    return 0;
}
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
10.01.2017, 07:09
Ответы с готовыми решениями:

Округление знаков, после точки
Столкнулся с проблемой при работе с float float x1 = 1.0000000000000000; float x2 = x1 + 0.111111111111; float x3 = x2 +...

Округлить число до 25 знаков после десятичной точки
Есть простая задача: вот я ее решаю таким способом, т.к в задании написано округлить #include &lt;fstream&gt; #include...

Вычислить функцию с точностью 6 знаков после десятичной точки
)Вычислить функцию f(x,a)= при x=0.4, 0.6,..., 1.2 и a=2, 3, 4, 5 с точностью 6 знаков после десятичной точки.

10
58 / 16 / 26
Регистрация: 07.02.2015
Сообщений: 346
10.01.2017, 16:11
Укоротить строку иначе говоря

Пока вспомнил только для double

1)Подключить заголовочный файл
C++
1
#include <iomanip>
Эта библиотека отвечает за наличие манипуляторов с параметрами.

2)Затем использовать
C++
1
setprecision(int count)
где count это количество цифр после запятой
Например
C++
1
cout<<fixed<<setprecision(3)<<b;
Слово
C++
1
fixed
отвечает что выводимое выражение будет фиксированным,после какого либо преобразования
1
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
10.01.2017, 16:19
Цитата Сообщение от vjg2017 Посмотреть сообщение
Сражу скажу, что to_string использовать нельзя
А stringstream буфер можно? То есть то же самое, но чуть подлиннее.
Проблема в том, что при n = 25 у нас нет ни одного стандартного типа для хранения столь длинного числа с заданной точностью. Даже если рассматривать дробную часть как максимально возможное стандартное целое число (64 бита), получается 20-значное значение.
Тут нужна длинная арифметика. И либо массивы, либо строки (например, std::string). Но если to_string нельзя, то скорее всего вариант с решением на строках не подходит.
n точно никак не ограничен?

Добавлено через 38 секунд
Цитата Сообщение от redseven Посмотреть сообщение
Пока вспомнил только для double
double не позволяет хранить числа с точностью до 25 знаков после запятой.
1
Эксперт С++
 Аватар для Mr.X
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
10.01.2017, 21:29
Лучший ответ Сообщение было отмечено vjg2017 как решение

Решение

Цитата Сообщение от vjg2017 Посмотреть сообщение
моё решение корректно
А вы не горячитесь в этом утверждении?
Мое решение:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <iostream>
#include <string>
///////////////////////////////////////////////////////////////////////////////
typedef std::string     T_str;
///////////////////////////////////////////////////////////////////////////////
T_str   round_with_precision
    (
        T_str   const   &   s,
        size_t              n
    )
{
    const   char    POINT_SYMB  {'.'};
    const   char    ZERO_SYMB   {'0'};
 
    auto    s_cur       =   s;
    auto    point_pos   =   s_cur.find( POINT_SYMB );
 
    auto    n_cur       =   point_pos   ==  T_str::npos
                                ?   0
 
                                :       s_cur.size()
                                    -   1
                                    -   point_pos;
 
    if( n   <   n_cur )
    {
        auto    new_back_pos   =   point_pos + n + 1;
 
        s_cur.erase( ++new_back_pos );
        auto    is_rest     =   s_cur.back()    >=  '5';
        s_cur.pop_back();
 
        if( is_rest )
        {
            s_cur   =   ZERO_SYMB     +   s_cur;
 
            for (
                    int
                    p   =   s_cur.size() - 1;
                    p   >=  0;
                    --p
                )
            {
                if  (
                        s_cur[p]    ==  POINT_SYMB
                    )
                {
                    continue;
                }
 
                ++s_cur[p];
                s_cur[p]    -=  ZERO_SYMB;
                s_cur[p]    %=  10;
                s_cur[p]    +=  ZERO_SYMB;
 
                if  (
                        s_cur[p]    !=  ZERO_SYMB
                    )
                {
                    break;
                }
            }//for
 
            while   (
                            s_cur.front()   ==  ZERO_SYMB
                        &&  s_cur[1]        !=  POINT_SYMB
                    )
            {
                s_cur.erase(0, 1);
            }
        }//if is_rest
 
        if  (
                s_cur.back()    ==  POINT_SYMB
            )
        {
            s_cur.pop_back();
        }
    }//if
 
    return  s_cur;
}
///////////////////////////////////////////////////////////////////////////////
int     main()
{
    T_str   s   =   "2.7182818284590452353602875";
 
    for( int  i = 30 ; i >= 0; --i )
    {
        std::cout   <<  std::endl
                    <<  "n = "
                    <<  i
                    <<  std::endl
                    <<  round_with_precision( s, i )
                    <<  std::endl;
    }//for
}
1
6 / 6 / 3
Регистрация: 14.11.2016
Сообщений: 53
11.01.2017, 00:13  [ТС]
MrGluck,
"А stringstream буфер можно? То есть то же самое, но чуть подлиннее".
Я не знаю, я выбрал один сайт с интересными задачами, чтобы подучить язык. Задачки интересные, есть те, где нужно подумать (но они не слишком сложные, то есть некий баланс). Попробовал сдать задание с to_string -- не прошло. Мой вариант прошёл тесты, но стало интересно, а нельзя ли сделать задачу лучше. Например, я задал такой же вопрос по Java -- получил новые знания Оценить качество кода -- решение учебное задачи для начинающих В следующий раз, когда буду сдавать задачи по Java -- буду использовать те вещи, которые узнал.

"Но если to_string нельзя, то скорее всего вариант с решением на строках не подходит.
n точно никак не ограничен?"

Нет, n не ограничен. n может быть равен 25 максимум. Минимум -- 0.

Mr.X
"А вы не горячитесь в этом утверждении?
Мое решение:"


Чтобы ответить на ваш вопрос, мне нужно каким-то образом запустить вашу программу. Я для решение задач использую Dev-C++ 5.11.

Я скопировал ваш код -- попробовал запустить.

Получил ошибки:
1. main.cpp In function 'T_str round_with_precision(const T_str&, size_t)':

2. main.cpp [Warning] extended initializer lists only available with -std=c++11 or -std=gnu++11

3. 13 33 main.cpp [Warning] extended initializer lists only available with -std=c++11 or -std=gnu++11

4. 15 13 main.cpp [Error] 's_cur' does not name a type

5. 16 13 main.cpp [Error] 'point_pos' does not name a type

Если бы я мог запустить вашу программу, я дал ответ на ваш вопрос, но моя программа успешно прошла 20 тестов. Её засчитала автоматическая система. Я здесь разместил сообщение, потому что, может быть, узнаю что-то новое, что могу использовать на новых задачах.
0
Неэпический
 Аватар для Croessmah
18146 / 10730 / 2066
Регистрация: 27.09.2012
Сообщений: 27,029
Записей в блоге: 1
11.01.2017, 00:20
Цитата Сообщение от vjg2017 Посмотреть сообщение
Её засчитала автоматическая система
Ваше решение корректно только для нескольких частных случаев - не более.
1
Эксперт С++
 Аватар для Mr.X
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
11.01.2017, 00:54
Цитата Сообщение от vjg2017 Посмотреть сообщение
Я здесь разместил сообщение, потому что, может быть, узнаю что-то новое
Цитата Сообщение от vjg2017 Посмотреть сообщение
-std=c++11
Ну, вот вам и новенькое!
1
6 / 6 / 3
Регистрация: 14.11.2016
Сообщений: 53
11.01.2017, 20:15  [ТС]
Правильно, так что и здесь я тоже что-то узнал для себя нового и полезного. Так что создал тему не просто так.

Добавлено через 19 часов 14 минут
Кстати, мне удалось улучшить свой первоначальный вариант (напомню, что условие задача -- не сократить произвольное число с n знаками, а только частный вариант с n=25 и числом, равным, 2.7182818284590452353602875). Я сумел сократить код своей задачи по числу линий почти в два раза:
было у меня -- 50 строк
Стало -- 27 строк.

То есть я нашёл более короткое решение задачи -- она прошла автоматическую проверку по 20 тестам:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{
    string s = "2.7182818284590452353602875";
    int n;
    ifstream fin("input.txt");
    ofstream fout("output.txt", ios_base::out | ios_base::trunc);
    fin >> n;
    if (n==0){
          fout<<3;
    }
    else{
        for (int i=0;i<n+1;i++){
            fout <<s[i];
        }
        if (s[n+2]>'4'){
            fout<<(char)((int)s[n+1]+1);
        }
        else{
            fout <<s[n+1];
        }
    }
}
0
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
11.01.2017, 20:54
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <string>
 
int main()
{
    std::string s = "2.7182818284590452353602875";
    int n;
    std::cin >> n;
    if (n != 0)
    {
        if (s[n+2] > '4')
            s[n+1]++;
        std::cout << s.substr(0, n+2);
    }
    else
        std::cout << 3;
}
Добавлено через 3 минуты
Решение на С (алсо работает для С++)
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
 
int main(void)
{
    char s[] = "2.7182818284590452353602875";
    int n;
    scanf("%d", &n);
    if (n != 0)
    {
        if (s[n+2] > '4')
            s[n+1]++;
        s[n+2] = '\0';
        printf("%s", s);
    }
    else
        printf("3");
    return 0;
}
1
Неэпический
 Аватар для Croessmah
18146 / 10730 / 2066
Регистрация: 27.09.2012
Сообщений: 27,029
Записей в блоге: 1
11.01.2017, 22:17
MrGluck, предлагаю проверить на строке
C
1
char s[] = "2.4444449";
1
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
12.01.2017, 00:21
Croessmah, у ТС вполне конкретные условия. И я переписал его код выше, просто в более компактной форме.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
12.01.2017, 00:21
Помогаю со студенческими работами здесь

Вывести в выходной файл округленное до n знаков после десятичной точки число E
Выведите в выходной файл округленное до n знаков после десятичной точки число E. Число Е, округленное до 25 знаков после десятичной точки,...

Выведите в выходной файл округленное до n знаков после десятичной точки число E
Как пишутся очень короткие программы на C++ или C (менее 150 символов, не считая пробелов и табуляций)? Например, задача Вот мое...

Округление числа до двух знаков после запятой
8. Написать программу, которая предлагает пользователю ввести дробное число, округляет его до двух знаков после запятой и выводит результат...

Функция round(), округление числа до 4-х знаков после запятой
Вот наткнулся на проблемку как округлить число до 4 знаков после запятой? Подскажите что делать?

Округление числа в строке до указанного количества знаков после запятой
Как делать округление в строке, до знака после запятой порядковый номер который задаёт пользователь с клавиатуры


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! */ #include <iostream> #include <stack> #include <cctype>. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru