21 / 21 / 8
Регистрация: 16.11.2012
Сообщений: 349
1

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

09.12.2014, 19:01. Показов 12788. Ответов 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
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.12.2014, 19:01
Ответы с готовыми решениями:

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

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

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

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

12
59 / 59 / 12
Регистрация: 01.01.2010
Сообщений: 222
09.12.2014, 19:24 2
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
Модератор
Эксперт С++
12458 / 10017 / 6030
Регистрация: 18.12.2011
Сообщений: 26,820
09.12.2014, 19:28 3
C++
1
printf("%.7lf\n",rez);
У меня выводит
144.6000000
1
Диссидент
Эксперт C
26970 / 16845 / 3705
Регистрация: 24.12.2010
Сообщений: 37,817
09.12.2014, 19:47 4
А если N заранее неизвестно, можно еще так
C
1
printf("%.*f", N, rez);
1
21 / 21 / 8
Регистрация: 16.11.2012
Сообщений: 349
09.12.2014, 20:02  [ТС] 5
Scythian, zss, Байт, спасибо, это я понимаю как выводить на экран. Мне бы сохранить ПРАВИЛЬНОЕ значение в переменной.. Веди при выполнении арифметических операций будут получаться такие же кривые значения.. А мне важно, чтобы 3.500000-1.400000 равнялось 2.100000, а не чему-либо другому..
0
342 / 342 / 331
Регистрация: 02.10.2014
Сообщений: 666
09.12.2014, 20:07 6
Лучший ответ Сообщение было отмечено genock94 как решение

Решение

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

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

Решение

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

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

Не по теме:

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



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

Решение

genock94, деньги считайте копейками и нет проблем, храните в целых типах, так в банках и делают
1
21 / 21 / 8
Регистрация: 16.11.2012
Сообщений: 349
09.12.2014, 21:23  [ТС] 11
Всем спасибо за ответы и новую для меня информацию!
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
26970 / 16845 / 3705
Регистрация: 24.12.2010
Сообщений: 37,817
09.12.2014, 21:36 12
Цитата Сообщение от genock94 Посмотреть сообщение
Вот функция,
ИМХО, твоя функция ничем не лучше стандартного atof
0
21 / 21 / 8
Регистрация: 16.11.2012
Сообщений: 349
09.12.2014, 21:42  [ТС] 13
Байт, да.. убедился..(
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.12.2014, 21:42
Помогаю со студенческими работами здесь

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

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

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

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


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru