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
5702
Если округление нужно только при выводе результатов, то эта задача решается спецификаторами 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
3131
Уфа
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, Супермодераторы



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

Сейчас этот форум просматривают: нет зарегистрированных пользователей


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

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