2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу 1, 2  След.
 
 Как в С++ округить число до требуемого знака?
Сообщение02.08.2009, 21:36 


27/08/06
579
Пытаюсь написать программу реализующую элементарные вычисления, и столкнулся с тем, что не могу округлить число до нужного знака :oops: . Подскажите пожалуста кто в курсе: если в сях встроенная функция позволяющая округлять число типа float до нужного знака? И ежели такой нет, то как обычно выходят из положения? Спасибо.

 Профиль  
                  
 
 Re: Как в С++ округить число до требуемого знака?
Сообщение02.08.2009, 21:59 
Модератор
Аватара пользователя


11/01/06
5710
Если округление нужно только при выводе результатов, то эта задача решается спецификаторами printf().
А вообще округлить до $n$-го знака после запятой можно умножив на $10^n$, округлив до целого и поделив на $10^n$:

Код:
float y = round(x*100000)/100000.0;

 Профиль  
                  
 
 Re: Как в С++ округить число до требуемого знака?
Сообщение02.08.2009, 22:12 


27/08/06
579
maxal в сообщении #232547 писал(а):
Если округление нужно только при выводе результатов, то эта задача решается спецификаторами printf().
А вообще округлить до $n$-го знака после запятой можно умножив на $10^n$, округлив до целого и поделив на $10^n$:

Код:
float y = round(x*100000)/100000.0;

Спасибо. Округление нужно не на этапе вывода, а в процессе вычисления. Реализую алгоритм Гаусса, и мне нужно обнулять следующий член в столбце, а он, собака, не обнуляется... Выдаёт хоть и малую, но всё же ошибку.

 Профиль  
                  
 
 Re: Как в С++ округить число до требуемого знака?
Сообщение03.08.2009, 12:44 
Заслуженный участник
Аватара пользователя


01/08/06
3139
Уфа
Dialectic писал(а):
Округление нужно не на этапе вывода, а в процессе вычисления. Реализую алгоритм Гаусса, и мне нужно обнулять следующий член в столбце, а он, собака, не обнуляется... Выдаёт хоть и малую, но всё же ошибку.

Не обращайте внимания, просто считайте, что там 0 и всё. Бороться с такими ошибками округления слишком накладно, да и преимуществ практически никаких.

 Профиль  
                  
 
 Re: Как в С++ округить число до требуемого знака?
Сообщение03.08.2009, 17:36 
Заслуженный участник


11/05/08
32166
Dialectic в сообщении #232549 писал(а):
Реализую алгоритм Гаусса, и мне нужно обнулять следующий член в столбце, а он, собака, не обнуляется... Выдаёт хоть и малую, но всё же ошибку.

Что значит "не обнуляется", когда Вы его обнуляете принудительно?...

Кроме того: в чём бы ни состояла Ваша проблема (я её не понял) -- искусственное занижение точности вычислений ситуацию, естественно, не улучшит.

 Профиль  
                  
 
 Re: Как в С++ округить число до требуемого знака?
Сообщение03.08.2009, 19:45 


27/08/06
579
ewert в сообщении #232675 писал(а):
Dialectic в сообщении #232549 писал(а):
Реализую алгоритм Гаусса, и мне нужно обнулять следующий член в столбце, а он, собака, не обнуляется... Выдаёт хоть и малую, но всё же ошибку.

Что значит "не обнуляется", когда Вы его обнуляете принудительно?...

Как-то не подумал о том, что можно обнулить принудительно... А ведь действительно можно!
Речь просто вот о чём: если отношение двух чисел $a=p/q$
представляет собой бесконечную переодическую дробь, то она, в силу того, что тип float имеет конечную величину - не помещается вся целиком в него. В результате,вместо величины $a$ имеем приближённую величину $a^*$ если потом, выполнить обратное преобразование то величина:
$|q*a^*-p|$ - не будет в точности равна нулю.

ewert в сообщении #232675 писал(а):
Кроме того: в чём бы ни состояла Ваша проблема (я её не понял) -- искусственное занижение точности вычислений ситуацию, естественно, не улучшит.

В данном случае, как видно - улучшит.

 Профиль  
                  
 
 Re: Как в С++ округить число до требуемого знака?
Сообщение03.08.2009, 19:56 
Заслуженный участник


11/05/08
32166
Dialectic в сообщении #232693 писал(а):
В данном случае, как видно - улучшит.

Ну как оно может улучшить, если Вы попросту привносите в вычисления дополнительную погрешность?

 Профиль  
                  
 
 Re: Как в С++ округить число до требуемого знака?
Сообщение03.08.2009, 20:01 
Заслуженный участник


28/04/09
1933
Dialectic
Если Вы работаете только с рациональными дробями, имеет смысл отказаться от float и просто написать класс такой дроби, реализовав используемые операторы, чтобы выражения считались точно (в классе два целых поля - числитель и знаменатель, а операторы работают по арифметическим правилам действий с дробями).
Если же надо обойти проблемы, которые возникают именно с вещественными числами, можно написать класс вещественного числа, который будет отслеживать различные "тонкие" моменты (типа получения результата меньше некоторой заранее определенной константы и ему подобных). В таком классе также очень удобно реализовывать операторы сравнения (то есть числа считаются равными, если отличаются меньше, чем на ту же константу и т.д.).
Конечно, все это актуально, если Вы программируете на C++, а не просто на C.

-- Пн авг 03, 2009 21:03:28 --

Извиняюсь. Не увидел Гаусса, первый вариант отпадает...

 Профиль  
                  
 
 Re: Как в С++ округить число до требуемого знака?
Сообщение03.08.2009, 20:05 


27/08/06
579
ewert в сообщении #232694 писал(а):
Dialectic в сообщении #232693 писал(а):
В данном случае, как видно - улучшит.

Ну как оно может улучшить, если Вы попросту привносите в вычисления дополнительную погрешность?

Так я укруглю до первого знака, и у меня останется нуль. В итоге при перемножении у меня будет в точности нуль.

-- Пн авг 03, 2009 21:13:04 --

EtCetera в сообщении #232697 писал(а):
....

Спасибо. Немедленно приступлю к реализации такого класса.
Только я пока не знаю где описываются классы в C++Builder 6.0 . Его я начал изучать один день назад, и только потому, что надоело читать MSDN в котором основные функции приводятся на этом языке. Не подскажите где описываются классы и как вообще строится проект в С? (ранее я писал на Delphi)

 Профиль  
                  
 
 Re: Как в С++ округить число до требуемого знака?
Сообщение03.08.2009, 20:15 
Заслуженный участник


11/05/08
32166
Dialectic в сообщении #232699 писал(а):
Так я укруглю до первого знака, и у меня останется нуль. В итоге при перемножении у меня будет в точности нуль.

Если у Вас Гаусс, то на каждом шаге Вы вычитаете из всех остальных строк ведущую, умноженную на некоторое число. Обратная операция (которая на самом деле не нужна) -- восстановление предыдущего состояния матрицы -- это прибавление ведущей строки, умноженной на те же числа. Естественно, это восстановление точным не будет. И будет тем менее точным, чем сильнее Вы округляете промежуточные результаты.

 Профиль  
                  
 
 Re: Как в С++ округить число до требуемого знака?
Сообщение03.08.2009, 20:22 


27/08/06
579
ewert в сообщении #232700 писал(а):
Если у Вас Гаусс, то на каждом шаге Вы вычитаете из всех остальных строк ведущую, умноженную на некоторое число.

Всё верно. Но для начала, я это "некоторое число" - должен получить. Оно строится так чтобы обнулить ниже стоящий член в том же столбце. Для этого я и должен умножить в начале на него, а затем разделить на "текущий" член моего столбца взятый спротивоположным знаком. Когда же я проделываю обратную операцию - реализующую непосредственное изменение элементов матрицы, то я не получаю точного нуля.

 Профиль  
                  
 
 Re: Как в С++ округить число до требуемого знака?
Сообщение03.08.2009, 20:27 
Заслуженный участник


11/05/08
32166
Dialectic в сообщении #232703 писал(а):
Когда же я проделываю обратную операцию - реализующую непосредственное изменение элементов матрицы, то я не получаю точного нуля.

Ну и никакими силами не получите. Ну и что? У Вас получится приближённо ноль -- в пределах погрешностей округления. Так ведь и все остальные числа -- те, что ненулевые -- тоже всего лишь приближённые. Почему Вас именно нули вдруг взволновали?...

 Профиль  
                  
 
 Re: Как в С++ округить число до требуемого знака?
Сообщение03.08.2009, 20:34 
Заслуженный участник


15/05/09
1563
Dialectic в сообщении #232699 писал(а):
Только я пока не знаю где описываются классы в C++Builder 6.0 . Его я начал изучать один день назад, и только потому, что надоело читать MSDN в котором основные функции приводятся на этом языке. Не подскажите где описываются классы и как вообще строится проект в С? (ранее я писал на Delphi)
Поддержка С/С++ и Pascal/Delphi у Borland (нынче правильнее говорить CodeGear а еще правильнее Embarcadero :wink: ) принципиально схожа, но отличается в деталях. Понятие unit в С/С++ вообще говоря, отсутствует, его заменяет набор исходных текстов и объектный файл. Набор - потому что как и в Delphi, текст принято разделять на интерфейс (в С принято размещать его в заголовочном файле с расширением .h) и реализацию (помещается в файл с расширением .c/.cpp). Вместо uses используется #include "header.h", который помещается как в реализацию (в этом небольшое отличие от Delphi), так и во все другие файлы, в которых в Delphi Вы написали бы "uses".

В проект включаются .c/.cpp файлы, а все остальное оболочка сама сделает. Создать новый проект - практически так же, как и в Delphi. Советую почитать Help, посмотреть примеры. На первых этапах будете немного спотыкаться с непривычки, но если уловить концепцию, то при написании простых программ различия нет. Разве что комментарии могут вдруг превратиться в некомпилируемые конструкции. :lol:

По собственно языку - лучше Страустропа, пожалуй, ничего не знаю. В синтаксисе, да и в концепции построения классов есть небольшие отличия.

 Профиль  
                  
 
 Re: Как в С++ округить число до требуемого знака?
Сообщение04.08.2009, 20:21 


27/08/06
579
PapaKarlo спасибо большое за ликбез.

 Профиль  
                  
 
 Re: Как в С++ округить число до требуемого знака?
Сообщение04.08.2009, 20:29 
Заслуженный участник


11/05/08
32166
Только надо всё ж таки отдавать себе отчёт в том, что конкретныя языки тут не при чём. Если есть погрешность округления -- так она и есть. И никакое языкознание тут не спасёт. Увы.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 24 ]  На страницу 1, 2  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot]


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group