Скорость выполнения функций ceil(),round(),floor() - страница 3

 
Nikolai Semko:

да, но если:

то все нормально.

Осталось убедиться, что все нормально будет для любого числа x
 

A100:

void OnStart()
{
        Print( (int)(3.0001 + 0.999999999999999)); //все равно 4
        Print( floor(3.00001));                    //3
}




не понял. В чем косяк?

 
A100:
Осталось убедиться, что все нормально будет для любого числа x

Конечно не будет...

Ведь если происходит такое:

double x=3;
x=x+0.1;
x=x+0.1;
x=x+0.1;
x=x+0.1;
if (x!=3.4) Print("oppps..."); // oppps...

то, вопросы не ко мне и не к этой идее.

 
Nikolai Semko:
В чем косяк?
void OnStart()
{
        double d =  16 + 0.999999999999999;
        Print( (int)(d + 0.999999999999999)); //18
        Print( (int)ceil( d ));               //17
}
 
Nikolai Semko:
то, вопросы не ко мне и не к этой идее.
floor(), ceil(), round() для того и существуют - чтобы не было вопросов
 

я думаю что все эти вышеперечисленные огрехи выходят за рамки практического использования данного решения ускорения округления положительных чисел, т.к. мало кому нужны точности на уровне 16 знака. А косяки эти возникают из различных рода переполнениях на уровнях дцатых знаков самого компилятора.

 
A100:
floor(), ceil(), round() для того и существуют - чтобы не было вопросов

Я ж не запрещаю вам их использовать. Пользуйтесь на здоровье. Сам их буду использовать. Но если я создаю алгоритм, где важна скорость, я буду юзать этот вариант округления с учетом всех нюансов данного способа. Я думаю другим программистам будет тоже полезно знать о существовании такой альтернативы. Для того чтобы знать о нюансах данного способа округления - как раз и необходимо обсуждение. За что всем большое спасибо. Разве я не прав?

 
Nikolai Semko:

DBL_MIN и DBL_EPSILON не работают - слишком маленькие. Наверное имеет смысл оставить 0.9999999999999999 (16 девяток- максимальное число знаков после запятой в double)

Так DBL_EPSILON - это и есть 16 знаков после запятой:  2.2204460492503131e-016

А в вашем случае получается фактически единица, т.к. разница составляет всего 1e-16, что в 2 раза меньше epsilon.

 
Alexey Navoykov:

Так DBL_EPSILON - это и есть 16 знаков после запятой:  2.2204460492503131e-016

А в вашем случае получается фактически единица, т.к. разница составляет всего 1e-16, что в 2 раза меньше epsilon.


Да, я это понял, но не работает. Оказывается и не работает с 16 девятками (странно, вроде раньше получалось). Работает только с 15 девятками.

double x=3;
int Y=(int)ceil(x);
Print(Y);                         // 3
Y=(int)(x+0.999999999999999); 
Print(Y);                         // 3  (15 9-ток)
Y=(int)(x+0.9999999999999999);
Print(Y);                         // 4  (16 9-ток)
Y=(int)(x+1-DBL_EPSILON);
Print(Y);                         // 4
Причина обращения: