Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 67, средняя оценка - 4.75
Count
0 / 0 / 0
Регистрация: 06.11.2011
Сообщений: 24
#1

Округлить любое вещественное число до определённого количества знаков с математической точностью - C++

06.11.2011, 21:17. Просмотров 8635. Ответов 26
Метки нет (Все метки)

Пишем Microsoft Visual Studio -> Win32 Console Application -> C++.
Нужно написать функцию, которая округляет любое вещественное число до определённого количества знаков с математической точностью.
Вот что уже готово, можете подсказать в чем ошибка и как исправить?
(Изучаю функцию одну пару, так что хочу попросить объяснять и показывать как можно проще и примитивнее Про ceil нам тоже еще не рассказывали, читал Дейтел, нашел решил попробовать...)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
# include <locale>
# include <Windows.h>
#include <cmath>
using namespace std;
void main ()
{
int z;
cout<<"Введите число\n";
    cin>>z;
    cout<<Fal(z);
}
int Fal ( int a)
{
    char q;
    q = ceil(a);
    return q;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.11.2011, 21:17
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Округлить любое вещественное число до определённого количества знаков с математической точностью (C++):

Как округлить в С++ вещественное число до 2 знаков после запятой? - C++
Ну собсно вопрос в теме. заранее спасибо))

Функция, округляющая вещественные числа до определённого количества знаков - C++
Написать функцию, которая округляет любое вещественное число до определённого количества знаков с математической точностью.

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

Дано вещественное число, проверить является ли это число симметричным относительно положения точки до двух знаков после запятой. - C++
Только начинаю программировать на с/с++ и столкнулась с логическими выражениями, простейшие задачи могу решить а в эту никак не могу...

Пользователь вводит с клавиатуры: начальную сумму, внесённую на депозит (вещественное положительное число), годовой процент (вещественное положительно - C++
Пользователь вводит с клавиатуры: начальную сумму, внесённую на депозит (вещественное положительное число), годовой процент (вещественное...

исправьте ошибку!округлить double до 2-х знаков после запятой - C++
округлять,не используя math.h #include &quot;stdafx.h&quot; #include &lt;stdio.h&gt; int main () { double i; printf (&quot;i=&quot;); scanf...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
21.03.2015, 18:12 #16
Цитата Сообщение от Count Посмотреть сообщение
Вот что уже готово, можете подсказать в чем ошибка и как исправить?
В том, что
Цитата Сообщение от Count Посмотреть сообщение
вещественное число
твоя функция даже принять не способна.
zss
Модератор
Эксперт С++
6367 / 5931 / 1923
Регистрация: 18.12.2011
Сообщений: 15,240
Завершенные тесты: 1
24.03.2015, 19:44 #17
Предлагаю целую и дробную части хранить отдельно в целых числах.
Иначе будут возникать проблемы типа
1.2349999999999999
C++
1
2
3
4
5
6
7
8
9
10
11
12
void okrugl(double a, int b)
{
    int celoe, drob;
    celoe=(int)a;
    a=fabs(a-celoe);
    for(int i=0;i<b;i++)
        a*=10;
    drob=(int)a;
    if(a-drob>0.5)
        drob++;
    cout<<celoe<<'.'<<drob<<"\n";
}
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
24.03.2015, 19:49 #18
zss, что то Ваша проблема не понятна.
zss
Модератор
Эксперт С++
6367 / 5931 / 1923
Регистрация: 18.12.2011
Сообщений: 15,240
Завершенные тесты: 1
24.03.2015, 20:14 #19
Цитата Сообщение от taras atavin Посмотреть сообщение
что то Ваша проблема не понятна
Переменные типа double Нельзя точно перевести в десятичное представление,
всегда возможна ошибка в последней цифре.
В результате могут получаться результаты типа
1.239999999999999999999
1.240000000000000000000
1.240000000000000000001
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
25.03.2015, 09:06 #20
Цитата Сообщение от zss Посмотреть сообщение
В результате могут получаться результаты типа
1.239999999999999999999
1.240000000000000000000
1.240000000000000000001
В результате чего? Округления до десятых? Бред. Округления до 21-й цифры после запятой? Ну вот такое оно в этой точности получилось, а все погрешности данной цифры следует отнести к процессу вычисления самого числа. 10 делится на 2 на цело без остатка, поэтому всякая конечная двоичная дробь имеет точное десятичное представление, но не наоборот. В противоположность этому ни одна троичная дробь не имеет точного десятичного представления и на наоборот.
CppJava
0 / 0 / 0
Регистрация: 08.02.2015
Сообщений: 19
25.03.2015, 09:10 #21
Для алгебраических и некоторых трансцендентных чисел можно использовать стандартные алгоритмы.
zss
Модератор
Эксперт С++
6367 / 5931 / 1923
Регистрация: 18.12.2011
Сообщений: 15,240
Завершенные тесты: 1
25.03.2015, 09:34 #22
taras atavin,
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include<iostream>
int main() 
{
    double a=1234567.123456789;
    a*=100.;
    a=(int)a;
    a/=100.;
    std::cout.precision(20);    
    std::cout<<a<<std::endl;
    system("pause");
    return 0;
}
Округлить любое вещественное число до определённого количества знаков с математической точностью
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include<iostream>
int main() 
{
    double a=1234567.123456789;
    a*=100.;
    a++;
    a=(int)a;
    a/=100.;
    std::cout.precision(20);    
    std::cout<<a<<std::endl;
    system("pause");
    return 0;
}
Округлить любое вещественное число до определённого количества знаков с математической точностью
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
25.03.2015, 12:19 #23
Цитата Сообщение от zss Посмотреть сообщение
int main() { double a=1234567.123456789; a*=100.; a=(int)a; a/=100.; std::cout.precision(20); std::cout<<a<<std::endl; system("pause"); return 0; }
И что? Вы скормили машине десятичную дробь без точного двоичного представления, преобразовали её в двоичную с потерей точности, выполнили два промежуточных вычисления, потом преобразовали её назад в десятичную, увидели погрешность первого преобразования и пытаетесь этим что то доказать? Срочно в первый класс учиться делить на цело. Не степени двойки на цело делятся на десять без остатка, а десять на два. Соответственно все двоичные конечные дроби имеют точные десятичные представления, а вот десятичные дроби могут и не иметь точного двоичного представления. На входе же была как раз десятичная.
zss
Модератор
Эксперт С++
6367 / 5931 / 1923
Регистрация: 18.12.2011
Сообщений: 15,240
Завершенные тесты: 1
25.03.2015, 12:26 #24
C++
1
2
int na=123456; // na целое - никакой погрешности не содержит
double a=na/100.0;
После деления целого на 100.0 ожидаем, что после запятой получим две значащих цифры,
а остальные нули.
Но не тут-то было!
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
25.03.2015, 12:37 #25
Вы делите на 100, что эквивалентно умножению на 0.01, эта дробь не имеет точно двоичного представления. Отсюда и дополнительная погрешность. В итоге Вы и округлили до чёрт знает чего.
zss
Модератор
Эксперт С++
6367 / 5931 / 1923
Регистрация: 18.12.2011
Сообщений: 15,240
Завершенные тесты: 1
25.03.2015, 12:39 #26
Цитата Сообщение от taras atavin Посмотреть сообщение
не имеет точно двоичного представления
Я про это и говорю:
Двоичные числа с плавающей запятой не имеют точного десятичного представления.
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
25.03.2015, 13:17 #27
Имеют. Не имеют как раз некоторые десятичные числа точного двоичного представления.

Добавлено через 12 минут
http://www.cyberforum.ru/cgi-bin/latex.cgi?\frac{1}{2}=0,5\\\frac{1}{4}=0,25\\\frac{1}{8}=0,125\\\frac{1}{16}=0,0625 и так далее, сколько ни удваивай знаменатель, получим конечную дробь. Потому что 10 делится нацело на 2 без остатка. И эти равенства точные. Если единица стоит более, чем в одном разряде, то сумма нескольких конечных дробей также имеет конечную разрядность. Но вот наоборот берём 0,2 десятичное и пробуем перевести. Ноль целых имеем сразу.
0,b
0,2*2=0,4, целой части нет, значит 0
0,0b
0,4*2=0,8
0,00b
0,8*2=1,6 одна целая, значит 1 и дальше переводим 0,6
0,001b
0,6*2=1,2 одна целая, значит 1 и дальше переводим 0,2, то есть пришли к исходной дроби.
0,0011b
0,2d=0,(0011)b. 0 целых и 0011 в периоде.

Добавлено через 2 минуты
Поэтому до восьмых можно округлить, умножив и разделив, до шестнадцатых можно, а до десятых нужен другой алгоритм и всё равно двоичное представление будет не точным. Но хоть погрешность менее 1 десятой можно гарантировать.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.03.2015, 13:17
Привет! Вот еще темы с ответами:

Вывод определённого кол-ва знаков после запятой в структуре! - C++
Ребята,передо мной была поставлена задача,которую я решил,но теперь вот у меня возник вопрос! вот прога по структурам,которую я написал: ...

Функция floor для округления значения до определённого числа знаков дробной части - C++
Всем привет ребята. кто мог бы объяснить где и что неправильно у меня в коде и как это исправить. Благодарю за внимание. Условие задачи:...

Округлить число до заданного количества знаков после запятой - Bash
Надо написать скрипт (Bash). В общем вот задача. На входе задано число с четырьмя знаками после запятой. Произвести его округление до...

Округлить вещественное число побитно - Assembler
Здравствуйте. Не силён в ассемблере, по этому прошу помощи у Вас. Использую делфи, есть переменная типа extendet. Мне нужно эмулировать...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
25.03.2015, 13:17
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru