С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/75: Рейтинг темы: голосов - 75, средняя оценка - 4.60
 Аватар для genock94
21 / 21 / 8
Регистрация: 16.11.2012
Сообщений: 349

Точность в N знаков после запятой числа типа double

09.12.2014, 19:01. Показов 14908. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день, уважаемы форумчане!
Возникла проблема, заключающаяся в изменении значения, получающегося в результате выполнения функции atof().
Вот пример:
C++
1
2
char buf[100] = "144.6000000";
double rez = atof(buf);
В результате я получаю:
C++
1
144.59999999999999
А мне НЕОБХОДИМО, чтобы было РОВНО:
C++
1
144.60000000000000
Я пытался делать округление:
C++
1
2
char buf[100] = "144.6000000";
double rez = floor(atof(buf)*100 + 0.5)/100;
Однако результат не изменился.
Вопрос: как мне достичь желаемого результата (с точность до 7-го знака после запятой)?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
09.12.2014, 19:01
Ответы с готовыми решениями:

Вывод числа после запятой переменной типа double
Здравствуйте!!! У меня есть 2 программы, одну мне дали вторую написал. Та программа которая была написана мной работает чуть чуть...

Количество знаков после запятой double, Long double
Есть число большой точности A. A=-1.768573656315270993281 742915329544712934120053405549882 337511135282776553364635382011977 ...

Как вывести double до 2 знаков после запятой?
Нужно вывести число до 2 знаков после запятой. Попробовал так: 1) round(a*100)/100; 2) out.precision(2); out<<a; ...

12
 Аватар для Scythian
59 / 59 / 12
Регистрация: 01.01.2010
Сообщений: 222
09.12.2014, 19:24
C++
1
2
3
4
    char buf[100] = "144.6000000";
    double rez = atof(buf);
    cout<<setiosflags(ios::fixed)<<setprecision(8) << rez << endl;
    return 0;
Вот так попробуйте
1
Модератор
Эксперт С++
 Аватар для zss
13771 / 10964 / 6491
Регистрация: 18.12.2011
Сообщений: 29,241
09.12.2014, 19:28
C++
1
printf("%.7lf\n",rez);
У меня выводит
144.6000000
1
Диссидент
Эксперт C
 Аватар для Байт
27714 / 17332 / 3810
Регистрация: 24.12.2010
Сообщений: 38,978
09.12.2014, 19:47
А если N заранее неизвестно, можно еще так
C
1
printf("%.*f", N, rez);
1
 Аватар для genock94
21 / 21 / 8
Регистрация: 16.11.2012
Сообщений: 349
09.12.2014, 20:02  [ТС]
Scythian, zss, Байт, спасибо, это я понимаю как выводить на экран. Мне бы сохранить ПРАВИЛЬНОЕ значение в переменной.. Веди при выполнении арифметических операций будут получаться такие же кривые значения.. А мне важно, чтобы 3.500000-1.400000 равнялось 2.100000, а не чему-либо другому..
0
 Аватар для D_in_practice
343 / 343 / 331
Регистрация: 02.10.2014
Сообщений: 666
09.12.2014, 20:07
Лучший ответ Сообщение было отмечено genock94 как решение

Решение

genock94, Вы никак не сможете сохранить правильное значение.
Тип дабл это приближенное значение всегда.
Ваше число может выглядеть как
144.60000000000000346647434463
так и
144.59999999999999343453534534
и это абсолютно случайно, Вы никак не можете на это повлиять

P.S. Решайте задачу через символьные типы
1
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
09.12.2014, 20:15
Лучший ответ Сообщение было отмечено genock94 как решение

Решение

Цитата Сообщение от genock94 Посмотреть сообщение
Мне бы сохранить ПРАВИЛЬНОЕ значение в переменной..
Оно и есть правильное, относительно разрядной сетки машины.
Многие дробные числа (с плавающей точкой) нельзя представить точно в разрядной сетке машины.
Вот пара ссылок.
раз
два

Добавлено через 5 минут
Цитата Сообщение от D_in_practice Посмотреть сообщение
и это абсолютно случайно
Ну, скажем так, оно не случайно, а в соответствии со стандартом IEEE 754. Ну, по крайней мере, в распространенных случаях. Всякие экзотические железки мы тут не рассматриваем, надеюсь?
2
 Аватар для genock94
21 / 21 / 8
Регистрация: 16.11.2012
Сообщений: 349
09.12.2014, 20:32  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Всякие экзотические железки мы тут не рассматриваем, надеюсь?
Нет) Дело в том, что программа, которую я планирую написать, работает с деньгами. Поэтому нужна точность. 13.560000 рублей и 13.499999 рублей это разные суммы денег. Пусть здесь разница не велика, но я боюсь, что когда будут производиться сотни тысяч арифметических операций, результат будет существенно отличаться от настоящего.
P.S. и вообще, как все устроено в банках? там же точность играет важную роль..
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
09.12.2014, 20:40

Не по теме:

Цитата Сообщение от genock94 Посмотреть сообщение
Нет) Дело в том, что программа, которую я планирую написать, работает с деньгами.
Я слышал, что программистов, которые используют double для хранения денег потом находят на дне реки с забетонированными ногами :)



Можно использовать фиксированную точку вместо плавающей.
1
 Аватар для D_in_practice
343 / 343 / 331
Регистрация: 02.10.2014
Сообщений: 666
09.12.2014, 20:43
Лучший ответ Сообщение было отмечено genock94 как решение

Решение

genock94, деньги считайте копейками и нет проблем, храните в целых типах, так в банках и делают
1
 Аватар для genock94
21 / 21 / 8
Регистрация: 16.11.2012
Сообщений: 349
09.12.2014, 21:23  [ТС]
Всем спасибо за ответы и новую для меня информацию!
P.S. Возможно, кому-нибудь пригодится...
Вот функция, которая принимает в качестве параметра указатель на строку с числом (например: 123.1234567890) и возвращает число типа double:
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
double charToDouble(char* src){
    double rez = 0.0;
    unsigned int pointPos = 0;
    double k = 1.0;
    
    for (unsigned int i=0; i<strlen(src); i++){
        if ( src[i] == '.' ){
            pointPos = i;
        }
    }
 
    for (unsigned int i=0; i<pointPos-1; i++){
        k = k * 10.0;
    }
 
    for (unsigned int i=0; i<strlen(src); i++){
        if ( src[i] != '.' ){
            rez = rez + ((double) (src[i] - '0')) * k;
            k = k / 10.0;
        }
    }
 
    return rez;
}
0
Диссидент
Эксперт C
 Аватар для Байт
27714 / 17332 / 3810
Регистрация: 24.12.2010
Сообщений: 38,978
09.12.2014, 21:36
Цитата Сообщение от genock94 Посмотреть сообщение
Вот функция,
ИМХО, твоя функция ничем не лучше стандартного atof
0
 Аватар для genock94
21 / 21 / 8
Регистрация: 16.11.2012
Сообщений: 349
09.12.2014, 21:42  [ТС]
Байт, да.. убедился..(
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
09.12.2014, 21:42
Помогаю со студенческими работами здесь

Подсчет знаков после запятой в переменной double
Не получается, так как в double числа хранятся не точно, и на моменте, когда i == 3345333, d == 3345333.0000000004 и программа...

Как отображать у double больше знаков после запятой?
Что-то забыл как это сделать :(

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

Какая функция определяет количество знаков после запятой переменной double?
У меня есть программа, которая считает сумму ряда, в неё вводится значение x, точность, с которой определяется значение ln(x) и по формуле...

DataGrid количество знаков после запятой у типа double
Объясните пожалуйста, как задать стиль у столбца, чтобы содержащиеся в нем значения double отображались (не хранились) с определенным...


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru