Форум программистов, компьютерный форум, киберфорум
Наши страницы

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 21, средняя оценка - 4.62
Kgfq
74 / 37 / 2
Регистрация: 23.09.2012
Сообщений: 408
#1

double + cout - C++

14.10.2012, 15:42. Просмотров 3545. Ответов 27
Метки нет (Все метки)

Через cout вывожу double.

C++
1
2
double a =  48.799999999999997;
cout << a;
Выводит: 48.8.

Как сделать, что бы не округляло?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.10.2012, 15:42
Здравствуйте! Я подобрал для вас темы с ответами на вопрос double + cout (C++):

cout (double) - C++
Всем привет! Подскажите плз как вывести число типа дабл при помощи cout так чтобы были видны столько знаков, сколько я захочу а не 6...

double a=1/2; cout<<a;(a=0) что не так? - C++
#include &lt;iostream&gt; using namespace std; void main() { double a=1/2; cout&lt;&lt;a; } выводит a=0; использую 2008 студию....

Неправильно работает cout для чисел типа double и float - C++
Здравствуйте. Скажите, почему эта программа выводит на экран число 2, а не 2.5 ? #include &lt;iostream.h&gt; int main() { double...

Ошибки error C2296: -: недопустимо, левый операнд имеет тип "double (__cdecl *)(double,double,double - C++
Думаю из-за polp #include&lt;iostream&gt; #include&lt;cmath&gt; #include&lt;cstdlib&gt; using namespace std; double polp(double af,double...

Ошибка: error LNK2001: unresolved external symbol "double __cdecl Akk(double,double,double)" - C++
#include &lt;iostream&gt; #include &lt;cmath&gt; using namespace std; double Akk(double x, double y, double z); int main() { int a, b, c; ...

Cout <<endl; Что это значит? Если ничего нету в cout? - C++
Здравствуйте ! Обьясните пожалуйста что значит cout &lt;&lt;endl; если он используется после цикла for?

27
Evg
Эксперт CАвтор FAQ
18706 / 6675 / 472
Регистрация: 30.03.2009
Сообщений: 18,693
Записей в блоге: 29
15.10.2012, 16:11 #16
Цитата Сообщение от Kgfq Посмотреть сообщение
Evg, о выводе БЕЗ округления вовсе
Без округления это число будет выглядеть как бесконечная последовательность. Просто разработчики stl знают о том, как в машине хранятся плавающие числа, а ты - нет. Потому они понимают невозможность решения задачи в такой постановке, а ты - нет

Возьми пример из поста #20 и вместо 20 подставь 50, 100, 200 и т.д. Может после этого ты начнёшь всё-таки понимать, о чём тебе тут говорят. Если нет, тогда либо забей на этот вопрос, либо сядь и конкретно разберись с представлением плавающих чисел на машине. Потому что без этого ты никогда не поймёшь бредовость своей постановки задачи
0
Kgfq
74 / 37 / 2
Регистрация: 23.09.2012
Сообщений: 408
15.10.2012, 16:48  [ТС] #17
Evg,

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
#include <iostream>
#include <sstream>
using namespace std;
 
void Out(double out, int prec)
{
    ostringstream oss;
    oss.precision(20);
    oss << out;
    string out_s = oss.str(), out_o;
    for(unsigned int j = 0; j < out_s.length(); ++j)
    {
        out_o += out_s[j];
 
        if(out_s[j] == '.')
        {
            for(unsigned int i = j+1; i < j + prec + 1 && i < out_s.length(); ++i)
            {
                out_o += out_s[i];
            }
            
            goto qwe;
        }
    }
 
    qwe:;
    cout << out_o;
}
 
 
int main()
{
    Out(48.7999999999999, 5);
 
    cout << "\n\n";
    system("pause");
    return 0;
}
Evg, бесконечная? ага.
Если это можно сделать самому, то разрабы стл тем более могли написать.

Добавлено через 1 минуту
Кстати, выведет 48.79999
0
Evg
Эксперт CАвтор FAQ
18706 / 6675 / 472
Регистрация: 30.03.2009
Сообщений: 18,693
Записей в блоге: 29
15.10.2012, 19:47 #18
Цитата Сообщение от Kgfq Посмотреть сообщение
Evg, бесконечная?
Господи, ну почему же ты не читаешь, что тебе пишут? В 8-й строке замени "20" на "30", а в 33-й - "5" на "30". И почему же в итоге число-то такое кривое выводится, совсем не такое, какое писал ты? Наверное, авторы stl ничего не умеют...

Цитата Сообщение от Kgfq Посмотреть сообщение
Если это можно сделать самому, то разрабы стл тем более могли написать
С какого перепугу им это надо было сделать? Они сделали честное округление при печати. Подрезание строки их никто делать не просил. Точно так их не просили включать в stl какую-нибудь реализацию калькулятора или табулирование функции (наверное, много студентов об этом мечтают)
0
Kgfq
74 / 37 / 2
Регистрация: 23.09.2012
Сообщений: 408
16.10.2012, 23:07  [ТС] #19
Evg, при чем тут студенты или нет?
Не округлять число в повседневной жизни тоже бывает нужно. Ты же не округляешь цену 50000,50
до 50001
и не говоришь каждый раз "пятьдесят копеек"
так вот и тут

и, кстати, я про адекватные точности говорю
0
Evg
Эксперт CАвтор FAQ
18706 / 6675 / 472
Регистрация: 30.03.2009
Сообщений: 18,693
Записей в блоге: 29
16.10.2012, 23:48 #20
Если тебе нужно округлить до целого, то для этого есть специальные функции. Если тебе нужно округлить до стольких-то знаков после запятой, то такая задача не выполнима для встроенных плавающих типов (float, double, long double). О причинах сказано выше, причём не раз
0
Kgfq
74 / 37 / 2
Регистрация: 23.09.2012
Сообщений: 408
17.10.2012, 00:02  [ТС] #21
Evg, я же выполнил, значит выполнима
0
Evg
Эксперт CАвтор FAQ
18706 / 6675 / 472
Регистрация: 30.03.2009
Сообщений: 18,693
Записей в блоге: 29
17.10.2012, 00:16 #22
Ты не выполнил. Ты напечатал с округлением, но не округлил. То бишь получил строковое представление с округлением, но не величину, которую можно будет использовать в вычислениях. Потому что у тебя при вычислениях на машине будет лишний хвост, которого не должно быть в реальности при вычислении на бумаге

C++
1
2
3
4
5
6
7
8
9
#include <iostream>
 
int main (void)
{
  double a =  48.7999999;
  double b = a * 10000000.0;
  std::cout << std::fixed << std::setprecision(20) << b << std::endl;
  return 0;
}
Bash
487999999.00000005960464477539
0
Kgfq
74 / 37 / 2
Регистрация: 23.09.2012
Сообщений: 408
17.10.2012, 00:18  [ТС] #23
Evg, зачем мне вычисления. Мне нужно было лишь ВЫВЕСТИ на экран.
0
Evg
Эксперт CАвтор FAQ
18706 / 6675 / 472
Регистрация: 30.03.2009
Сообщений: 18,693
Записей в блоге: 29
17.10.2012, 01:06 #24
Твой исходный вопрос звучал как "Как вывести число с исходной точностью, но не округляя его?" Тебе ответили, что никак. Потому что число, которое в десятичной системе пишется "48.799999999999997", в двоичной системе записывается в виде бесконечной непериодической записи. В машине представление конечное, а потому бесконечная двоичная запись обрезается и то число, что хранится в машине уже перестаёт в точности совпадать с тем, что ты написал в тексте программы. А потому в машине физически нету числа с "исходной точностью", а потому задача невыполнимая. Ты его можешь напечатать с точностью до стольких-то знаков после запятой
0
Kgfq
74 / 37 / 2
Регистрация: 23.09.2012
Сообщений: 408
17.10.2012, 23:00  [ТС] #25
Evg, исходная точность cout - 6 знаков после запятой. Так что это ты не понял вопроса.
0
Evg
Эксперт CАвтор FAQ
18706 / 6675 / 472
Регистрация: 30.03.2009
Сообщений: 18,693
Записей в блоге: 29
17.10.2012, 23:59 #26
Цитата Сообщение от Kgfq Посмотреть сообщение
исходная точность cout - 6 знаков после запятой
Это не исходная точность, а дефолтное округление, что как бэ не одно и то же

Цитата Сообщение от Kgfq Посмотреть сообщение
Так что это ты не понял вопроса
Однако упёртый ты товарищ. Возьмём следующий пример. На всякий случай сообщаю, что таким образом распечатывается байтовый образ плавающего числа, хранимого в машине.

C++
#include <iostream>
 
int main (void)
{
  double a = 48.799999999999997;
  double b = 48.799999999999998;
  
  std::cout << std::hex << *((long long*)&a) << std::endl;
  std::cout << std::hex << *((long long*)&b) << std::endl;
  
  return 0;
}
Bash
4048666666666666
4048666666666666
Как видишь, для двух как бы разных плавающих чисел мы видим один и тот же байтовый образ. Т.е. машина не различает эти два плавающих числа. Внимание, вопрос. При печати машина получает 8-байтовый образ числа. Как машина должна догадаться, нужно напечатать "48.799999999999997", "48.799999999999998" или ещё одну из миллиардов разных возможных вещественных величин, которые при переводе в машинное двоичное представление дадут один и то же набор байтов

Добавлено через 17 минут
Если всё-таки я и вправду туплю и тебя интересует ответ на вопрос:

Цитата Сообщение от Kgfq Посмотреть сообщение
Если это можно сделать самому, то разрабы стл тем более могли написать
То встречный вопрос: а почему и зачем они должны были это делать? Если поставить более гипертрофированный вопрос, то почему бы в std::cout не добавить печать, которая на основании поданной строки выделит третье слово и заменит в нём все буквы "a" на "б". Такая встроенная возможность была бы крайне удобна для студента Иванова, которому преподаватель Петров задал вопрос N5 из билета N32.
0
Kgfq
74 / 37 / 2
Регистрация: 23.09.2012
Сообщений: 408
18.10.2012, 00:42  [ТС] #27
Evg, печать без округления бывает полезна. Поэтому вполне логично было бы, если бы ее добавили в стл. Ведь добавили же самые разные вещи.

Впрочем, это уже философский спор. Я понял суть.
0
Evg
Эксперт CАвтор FAQ
18706 / 6675 / 472
Регистрация: 30.03.2009
Сообщений: 18,693
Записей в блоге: 29
18.10.2012, 09:02 #28
Цитата Сообщение от Kgfq Посмотреть сообщение
печать без округления бывает полезна
Многое что бывает полезно. В Си++ добавили в первую очередь исходя из того, что подобная функциональность (возможно, избыточная) была в Си. А избыточность функциональности printf'а в первую очередь диктовалась требованиями производительности: язык-то придумывали в те времена, когда машины были медленные, а памяти было мало

Нигде при печати ведь нету округления целых чисел, ибо к процедуре печати это не имеет никакого отношения. А вот округление плавающих чисел - это не просто дополнительная функциональность и не пижонский набор велосипедов, это просто реальная необходимость, обусловленная тем, что плавающие числа изначально представляются неточно и печать почти любого плавающего числа помимо печати "неправильного" значения будет иметь ещё и очень длинную запись. Поэтому округление при печати пришлось вводить ещё в языке Си (в printf), а затем и в Си++ (в std::cout)
0
18.10.2012, 09:02
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.10.2012, 09:02
Привет! Вот еще темы с ответами:

Подскажите почему после первого cout программа не останавливается для ввода строки, а выводит второй cout - C++
Подскажите почему после первого cout программа не останавливается для ввода строки, а выводит второй cout. Это фрагмент со структурами: ...

В чем разница std::cout и просто cout? - C++
Ребят ,подскажите на простом языке для чайников . В чем разница std::cout и просто cout?

Почему мы пишем double x (double y)? а не через запятую double x,y - C++
почему мы пишем double x (double y)? а не через запятую double x,y

cout.setf и cout.precision - C++
Здравствуйте. В одной книге увидел строчку кода: cout.precision(2); cout.setf(ios::fixed, ios::floatfield); Объясните, что...


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

Или воспользуйтесь поиском по форуму:
28
Ответ Создать тему
Опции темы

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