2014 dxdy logo

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

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




На страницу 1, 2  След.
 
 Округление вещественного числа, деление без остатка
Сообщение26.08.2011, 11:17 
Аватара пользователя
Подскажите пожалуйста алгоритмы:

1. Округление (правильное) произвольного вещественного числа до заданной точности/разряда.
2. Проверка произвольного вещественного числа на кратность любому другому вещественному числу.

Спасибо!

 
 
 
 Re: Округление вещественного числа, деление без остатка
Сообщение26.08.2011, 13:58 
2usr00210
1. Пока могу только сказать, что он неединственен (алгоритм).
2. А простой предикат $P(a,\ b)=\big|a-b\cdot\lfloor a/b\rfloor\big|<\varepsilon$ не подходит?

 
 
 
 Re: Округление вещественного числа, деление без остатка
Сообщение28.08.2011, 06:41 
Аватара пользователя
Circiter в сообщении #477869 писал(а):
2usr00210
2. А простой предикат $P(a,\ b)=\big|a-b\cdot\lfloor a/b\rfloor\big|<\varepsilon$ не подходит?


как этим пользоваться на практике? :D

 
 
 
 Re: Округление вещественного числа, деление без остатка
Сообщение28.08.2011, 15:44 
Что-то вроде return fmod(a, b)<eps;. :)

 
 
 
 Re: Округление вещественного числа, деление без остатка
Сообщение28.08.2011, 16:04 
Circiter в сообщении #478304 писал(а):
Что-то вроде return fmod(a, b)<eps;. :)
Используется синтаксис C++
#include <cmath>
#include <iostream>
using namespace std;

int main()
{
    if ( fmod(1.0,0.1) < 1e-9 ) {
        cout << "Int" << endl;
    }
    else {
        cout << "Not Int" << endl;
    }
}
 
Код:
Not Int
Oops! ;-)

 
 
 
 Re: Округление вещественного числа, деление без остатка
Сообщение28.08.2011, 20:00 
Заинтриговали. Я получил тот же эффект при реализации способа, предложенного мной вначале: int P(double a, double b) {return fabs(a-b*floor(a/b))<1e-9;}. Проблема, надо полагать, именно в функции floor.

Правильной работы удалось достичь через modf:
код: [ скачать ] [ спрятать ]
Используется синтаксис C
#include <math.h>
#include <stdio.h>

int P(double a, double b)
{
    double Floor;
    modf(a/b, &Floor);
    return fabs(a-b*Floor)<1e-9;
}

int main()
{
    printf("%s", P(1.0, 0.1)?"yes":"no");
    return 0;
}
 


Как это объяснить?

 
 
 
 Re: Округление вещественного числа, деление без остатка
Сообщение28.08.2011, 22:57 
С modf() ошибка будет на других числах. Проблема в том, что если из-за ошибки округления результат деления оказался чуть меньше целого числа, то floor() вернёт число почти на единицу меньше.
Можно использовать round() или добавить eps*.5 перед вызовом floor() или fmod(). Да и над выбором eps надо дополнительно подумать.

 
 
 
 Re: Округление вещественного числа, деление без остатка
Сообщение29.08.2011, 01:26 
2venco
Цитата:
Можно использовать round() или добавить eps*.5

Честно говоря, слабо представляю, как это может помочь...

Можно ещё попробовать медленное двуступенчатое решение:
return fabs(a-b*floor(a/b))<eps||fabs(a-b*(floor(a/b)+1))<eps; :)

Цитата:
над выбором eps надо дополнительно подумать

А что если через while(eps/2+1>1) eps/=2;? Ну или из float.h константы брать...

 
 
 
 Re: Округление вещественного числа, деление без остатка
Сообщение29.08.2011, 20:02 
usr00210 в сообщении #477843 писал(а):
Подскажите пожалуйста алгоритмы:

1. Округление (правильное) произвольного вещественного числа до заданной точности/разряда.

Помножить на 10 в нужной степени, например до второго знака на 100.
Потом взять целую часть и, если того требует задача, разделить на обратно.

 
 
 
 Re: Округление вещественного числа, деление без остатка
Сообщение29.08.2011, 21:03 
Ни первое, ни второе задание не сформулированы точно: например, существуют абсолютная и относительная точность. И, например, относительную точность можно по разному определить.

 
 
 
 Re: Округление вещественного числа, деление без остатка
Сообщение30.08.2011, 07:02 
Аватара пользователя
Если нужна точность — не используйте числа с плавающей точкой. Фиксированная точка спасёт отца русской демократии. Можно посмотреть libgmp (думаю, там это есть, но не смотрел), можно «ручками» делать.

 
 
 
 Re: Округление вещественного числа, деление без остатка
Сообщение30.08.2011, 10:35 
Portnov в сообщении #478829 писал(а):
Если нужна точность — не используйте числа с плавающей точкой. Фиксированная точка спасёт отца русской демократии...

К сожалению, фиксированная точка спасёт отца русской демократии далеко не всегда. Или это спасение будет стоить слишком дорого.

 
 
 
 Re: Округление вещественного числа, деление без остатка
Сообщение30.08.2011, 11:23 
Аватара пользователя
drozdov_mihail в сообщении #478734 писал(а):
Ни первое, ни второе задание не сформулированы точно: например, существуют абсолютная и относительная точность. И, например, относительную точность можно по разному определить.


если вы скажете мне, чем отличает относительная от абсолютной, то я, возможно, смогу уточнить :D

а что не так со второй форумлировкой?

-- Вт авг 30, 2011 18:26:54 --

Roman Voznyuk в сообщении #478709 писал(а):
usr00210 в сообщении #477843 писал(а):
Подскажите пожалуйста алгоритмы:

1. Округление (правильное) произвольного вещественного числа до заданной точности/разряда.

Помножить на 10 в нужной степени, например до второго знака на 100.
Потом взять целую часть и, если того требует задача, разделить на обратно.


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

использовать арифметику фиксированной точки для произвольного вещественного числа?

 
 
 
 Re: Округление вещественного числа, деление без остатка
Сообщение30.08.2011, 12:14 
usr00210,

Слово "точность" - это ирония по поводу ваших безграмотных формулировок. Замените его на слово "погрешность".

 
 
 
 Re: Округление вещественного числа, деление без остатка
Сообщение30.08.2011, 13:49 
Аватара пользователя
Наиболее правильное решение задачи 1 — использование десятичной арифметики. Придётся реализовывать арифметические действия вручную (или найти готовую библиотеку). В некоторых банковских приложениях так делают, чтобы обеспечить нормативные правила округления.
Иначе придётся как-то жить с тем фактом, что конечная десятичная дробь, вообще говоря, соответствует бесконечной двоичной, и пытаться постоянно контролировать погрешности округления. Граблей на этом пути немало.

 
 
 [ Сообщений: 20 ]  На страницу 1, 2  След.


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group