ceil(), round(), floor() 함수의 실행 속도 - 페이지 4

 
Alexey Navoykov :

따라서 DBL_EPSILON은 소수점 이하 16자리입니다. 2.2204460492503131e-016

그리고 귀하의 경우 실제로 하나인 것으로 밝혀졌습니다. 왜냐하면. 차이는 1e-16에 불과하며 이는 엡실론보다 2배 작습니다.


0.9999999999999997에서는 작동하지만 0.9999999999999998에서는 작동하지 않습니다.

 
Nikolai Semko :

0.9999999999999997에서는 작동하지만 0.9999999999999998에서는 작동하지 않습니다.


여기 또 다른 농담이 있습니다.

Y=( int )(x+ 1 - 2 * DBL_EPSILON );
Print (Y);                              // 3
Y=( int )(x+ 1 - DBL_EPSILON - DBL_EPSILON );
Print (Y);                              // 4
 

십진법의 숫자 2.2204460492503131e-016은 이중 형식 ( https://msdn.microsoft.com/en-us/library/6bs3y5ya(v=vs.100).aspx )의 해상도를 의미하며, 이것은

x + 1.0이 1.0과 같지 않도록 하는 가장 작은 양수 x입니다.

1.0을 더하면 숫자 값이 변경되는 가장 작은 양수입니다. 즉, 이것은 숫자 표현의 상대 오차입니다. 즉, 16의 경우 이 경계에는 십진수 9가 너무 많이 포함되고 64의 경우 끝에 1에서 4배 더 차이가 날 것이고 8에서는 2배 더 적을 것입니다. 따라서 가능한 최고의 정확도로 반올림 속도를 높이려면 이 정확도를 계산해야 합니다. 이러한 계산은 일반 반올림 함수를 실행하는 것보다 더 빨리 발생하지 않을 것입니다. MQL은 숫자의 주소로 직접 작업하는 것을 허용하지 않기 때문에 숫자에서 순서 비트를 가져오는 것이 불가능합니다. 기본 2에서 로그 함수의 아날로그를 생각해 내야 합니다. 작동하지 않을 것입니다. 빠르게.

Пределы констант с плавающей запятой
Пределы констант с плавающей запятой
  • msdn.microsoft.com
В следующей таблице представлены ограничения на значения констант с плавающей запятой. Эти ограничения также заданы в стандартном файле заголовка FLOAT.H. Ограничения на константы с плавающей запятой КонстантаЗначениеЗначение Количество цифр q, при котором число с плавающей запятой с q десятичными цифрами можно округлить в представление с...
 
Nikolai Semko :

여기 또 다른 농담이 있습니다.

모든 수학적 작업은 추가 오류를 발생시키며, 이는 양수 및 음수일 수 있습니다. 따라서 일반적으로 Vladimir가 지적했듯이 얻은 결과를 정규화해야 합니다.

 

ceil(), floor()는 반복될 가능성이 낮습니다. µl부터 FPU의 반올림 모드를 제어할 수 없습니다. 어느 정도 적절하게 작동할 수 있는 유일한 것은 round()이며 이는 표준을 정확히 따르지 않습니다. 그건 그렇고, C round()는 다음과 같습니다.

 double round ( double x)
{
    fenv_t save_env;
    feholdexcept(&save_env);
     double result = rint(x);
     if (fetestexcept(FE_INEXACT)) {
        fesetround(FE_TOWARDZERO);
        result = rint(copysign( 0.5 + fabs (x), x));
    }
    feupdateenv(&save_env);
     return result;
}
 
여기서 반올림하려는 것을 이해하려면 DOUBLE 형식을 INT 형식으로 변환할 때 손실되는 방법과 손실을 정확히 알아야 합니다. 이 경우 절단 후에 남은 전체 부분만 얻습니다. 결과적 으로 소수점 이하 자릿수와 소수점 이하 자릿수가 포함된 모든 숫자는 삭제되고 정수 부분만 남습니다.
예시:
 2.1758716871 -> ( int ) 2.1758716871 = 2
2.0000000001 -> ( int ) 2.0000000001 = 2
2.9999999999 -> ( int ) 2.9999999999 = 2
숫자 형식이 변경될 때 이를 정밀도 손실 이라고 합니다.
따라서
 MathFloor (x)  =  ( int )(x)
MathCeil (x)   =  ( int )(x)+ 1 ;
MathRound (x)  =  ( int )(x+0.5)

감사합니다.
 
Andrey Kisselyov :
여기서 반올림하려는 것을 이해하려면 DOUBLE 형식을 INT 형식으로 변환할 때 손실되는 방법과 손실을 정확히 알아야 합니다. 이 경우 절단 후에 남은 전체 부분만 얻습니다. 결과적 으로 소수점 이하 자릿수와 소수점 이하 자릿수가 포함된 모든 숫자는 삭제되고 정수 부분만 남습니다.
예: 이것은 숫자 형식을 변경할 때 정밀도 손실 이라고 합니다.
따라서

감사합니다.

왜 그렇게 어렵습니까?

 MathRound (x)  - >  ( int )(x)+( int )( 2 .*(x-( int )(x)));

이것이 단순한 것보다 나은 이유는 무엇입니까?

 MathRound (x)  ->  ( int )(x+ 0.5 );
 
Alexey Navoykov :

모든 수학적 작업은 추가 오류를 발생시키며, 이는 양수 및 음수일 수 있습니다. 따라서 일반적인 경우 Vladimir가 지적했듯이 결과를 정규화해야 합니다.


파블릭_ :

ceil(), floor()는 반복될 가능성이 낮습니다. FPU 반올림 모드는 µl에서 제어할 수 없습니다. 어느 정도 적절하게 작동할 수 있는 유일한 것은 round()이며 이는 표준을 정확히 따르지 않습니다. 그건 그렇고, C의 round()는 다음과 같습니다.


물론 당신이 맞습니다. 그러나 나는 반복할 것이다. 99.9%의 작업에서 (int) 또는 (long)으로의 분수 유형 변환을 사용하여 반올림 함수를 대체 빠른 옵션으로 교체하는 것은 절대적으로 합법적입니다. 숙련된 프로그래머는 이 사실을 알고 적절할 때 적용하기만 하면 됩니다.

 Для положительных x:
y= floor (x); -> y=( int )x;
y= ceil (x);  -> y=( int )(x+ 0.9999999999999997 );
y= round (x); -> y=( int )(x+ 0.5 );
 
Nikolai Semko :

왜 그렇게 어렵습니까?

이 옵션이 단순한 옵션보다 나은 이유는 무엇입니까?

당신도 그것을 시도할 수 있습니다.

니콜라이 셈코 :
숙련된 프로그래머는 이 사실을 알고 적절할 때 적용하기만 하면 됩니다.

그는 마땅히 알아야 할 대상이 아니라 알아야 할 의무가 있습니다.

감사합니다.

추신 귀하의 수식은 전체 값 집합에 대해 정확하지 않습니다.
y= ceil (x);  -> y=( int )(x+ 0.9999999999999997 );
내 것을 확인하십시오. 라운드를 짧은 공식으로 업데이트했습니다. 이제 목록이 완전하고 완벽하게 작동합니다. 즐기십시오.
 
Andrey Kisselyov :


추신 귀하의 수식은 전체 값 집합에 대해 정확하지 않습니다.

내 것을 확인하십시오. 짧은 공식으로 라운드를 업데이트했습니다. 이제 목록이 완전하고 완벽하게 작동합니다. 즐기십시오.

참조

x = 3(모든 정수)일 때 엉망이 됩니다 :))

사유: