programing

부동 소수점이 아닌 정수를 포함하는 경우 이중 변수 선택

prostudy 2022. 7. 7. 22:32
반응형

부동 소수점이 아닌 정수를 포함하는 경우 이중 변수 선택

제 말은 다음과 같습니다.

  double d1 =555;
  double d2=55.343

나는 d1이 정수이고 d2는 정수라고 말할 수 있기를 원한다.c/c++로 쉽게 할 수 있는 방법이 있나요?

사용방법:

double intpart;
modf(value, &intpart) == 0.0

★★★★★★★★★★★★★★★로 변환하지 말아 주세요int그 !1.0e+300이치노

편집: Pete Kirkham이 지적한 바와 같이, 두 번째 인수로 0을 넘기는 것은 표준에서 보장되지 않으며, 더미 변수를 사용해야 하며, 안타깝게도 코드를 훨씬 더 우아하게 만들 수 없습니다.

c99 및 IEEE-754 준거 환경을 전제로 하고,

(trunc(x) == x)

가 (대부분의 플랫폼에서는)보다 합니다.modf이치노을 하다

:trunc는 이중 결과를 수 있기 에, 의 변환에 걱정할 필요는 이 경우, 예를 들어 「Double-Displayed Results」, 「Displays」, 「Displays」, 「Displays」, 「Displays」, 「Displays」의 , 「Discontain of type conversurruption」를 사용할 필요가 없습니다.(int)x.


편집: @pavon이 코멘트에서 지적한 것처럼 무한에 관심이 있는지 여부 및 원하는 결과에 따라 다른 체크를 추가해야 할 수 있습니다.x한합니니다다

avakar가 거의 맞았습니다.modf를 사용하세요.그러나 자세한 내용은 틀렸습니다.

modf는 부분적인 부분을 반환하므로 modf의 결과가 0.0인지 테스트해야 합니다.

modf는 두 개의 인수를 사용합니다.두 번째 인수는 첫 번째 인수와 같은 유형의 포인터여야 합니다.NULL 또는 0을 전달하면 g++ 런타임에 분할 오류가 발생합니다.표준에서는 0을 통과하는 것이 안전하다고 명시되어 있지 않습니다.Avakar의 머신에서는 동작하지만 동작하지 않을 수 있습니다.

,도할 수 .fmod(a,b)서 됩니다.ab1.1.0을 .이것 또한 부분적인 부분을 줄 것이다.

#include<cmath>
#include<iostream>

int main ()
{
    double d1 = 555;
    double d2 = 55.343;

    double int_part1;
    double int_part2;

    using namespace std;

    cout << boolalpha;
    cout << d1 << " " << modf ( d1, &int_part1 ) << endl;
    cout << d1 << " " << ( modf ( d1, &int_part1 ) == 0.0 ) << endl;
    cout << d2 << " " << modf ( d2, &int_part2 ) << endl;
    cout << d1 << " " << ( modf ( d2, &int_part2 ) == 0.0 ) << endl;
    cout << d2 << " " << modf ( d2, &int_part2 ) << endl;
    cout << d1 << " " << ( modf ( d2, &int_part2 ) == 0.0 ) << endl;

    cout << d1 << " " << fmod ( d1, 1.0 ) << endl;
    cout << d1 << " " << ( fmod ( d1, 1.0 ) == 0 ) << endl;
    cout << d2 << " " << fmod ( d2, 1.0 ) << endl;
    cout << d2 << " " << ( fmod ( d2, 1.0 ) == 0 ) << endl;


    cout.flush();

    modf ( d1, 0 ); // segfault

}
#define _EPSILON_ 0.000001

bool close_to_int(double &d)
{
    double integer,
           fraction = modf(d, &integer);
    if(fraction < _EPSILON_)
    {
        d = integer;
        return true;
    }
    if((1.0 - fraction) < _EPSILON_)
    {
        d = integer + 1;
        return true;
    }
    return false;
}

그러면 정수값의 양쪽이 모두 확인되고 정수값의 제한 범위 내에 있는 경우 d 값이 설정됩니다.

int iHaveNoFraction(double d){
    return d == trunc(d);
}

40년 정도 언어 수정이 없었다면 C가 아니었을 텐데...

식식사는,==intC++에서는 C++로 반환됩니다.bool distro(Ubuntu)를 을 사용하다double trunc(double);또는 컴파일 할 수 있습니다.-std=c99 모든 이 「 매크로」를 취득하기 .<math.h>선언할 수 있습니다.

어때.

if (abs(d1 - (round(d1))) < 0.000000001) {
   printf "Integer\n"; /* Can not use "==" since we are concerned about precision */
}

Anna가 발견한 버그를 반영하기 위해 반올림을 사용하여 작업을 수정했습니다.

대체 솔루션:

if ((d1 - floor(d1) < 0.000000001) || (d1 - floor(d1) > 0.9999999999)) {
   /* Better store floor value in a temp variable to speed up */
   printf "Integer\n"; /* Can not use "==" since we are concerned about precision */
}

플로어, 0.5 빼기, abs() 빼기, 0.4999999와 비교한 것도 있습니다만, 큰 퍼포먼스 향상은 되지 않는다고 생각합니다.

#include <math.h>
#include <limits>

int main()
{
  double x, y, n;
  x = SOME_VAL;
  y = modf( x, &n ); // splits a floating-point value into fractional and integer parts
  if ( abs(y) < std::numeric_limits<double>::epsilon() )
  {
    // no floating part
  }
}

CMath가 있다고 가정하면<math.h>도서관 바닥과 대조해서 번호를 확인하세요.만약 그 숫자가 음수일 수 있다면, 당신이 절대적인 것을 먼저 얻었는지 확인하세요.

bool double_is_int(double trouble) {
   double absolute = abs( trouble );
   return absolute == floor(absolute);
}

이건 어때?

if ((d1 - (int)d1) == 0)
    // integer

d1과 d2를 테스트하기 위한 코드는 다음과 같습니다.테스트해야 할 것은 변수 값이 int 유형으로 변환된 동일한 값과 동일한지 여부뿐입니다.그렇지 않으면 정수가 아닙니다.

#include<iostream>
using namespace std;

int main()
{
    void checkType(double x);
    double d1 = 555;
    double d2 = 55.343;        
    checkType(d1);
    checkType(d2);
    system("Pause");
    return 0; 
}
void checkType(double x)
{
     if(x != (int)x)
     {
          cout<< x << " is not an integer "<< endl;
     }
     else 
     {
         cout << x << " is an integer " << endl;
     }
};

시험:

bool isInteger(double d, double delta)
{
   double absd = abs(d);

   if( absd - floor(absd) > 0.5 )
      return (ceil(absd) - absd) < delta;

   return (d - floor(absd)) < delta;
}

많은 계산에서 부동소수점 결과에 여러 곱셈으로 인해 발생할 수 있는 작은 수치 오류가 있음을 알 수 있습니다.

그래서 여러분이 찾고 싶은 것은 정수값의 1e-5 안에 있는 이 숫자입니다.이 경우 이 방법이 더 효과적이라고 생각합니다.

bool isInteger( double value )
{
    double flr = floor( value + 1e-5 );
    double diff = value - flr;
    return diff < 1e-5;
}

나도 비슷한 질문에 직면했다.어쨌든 더블 라운드를 해야 했기 때문에, 그것이 효과가 있는 것을 알 수 있었습니다.

double d = 2.000000001;
int i = std::round(d);
std::fabs(d-i) < 10 * std::numeric_limits<double>::epsilon()

d의 ceil과 바닥 값을 비교하기만 하면 됩니다.

return floor(d)==ceil(d);

그래서...d1=555, 상기의 스테이트먼트는 다음과 같습니다.return 555==555즉, 입니다.그러면 정수입니다.

그리고...d2=555.6, 상기의 스테이트먼트는 다음과 같습니다.return 555==556즉, 거짓이므로 이중입니다.

modf는 그 이유를 사용합니다.nearbyint10진수 없이 더블을 반환하고 더 빠를 수 있습니다.

#include <iostream>
#include <cmath>

int main() {
    double      number = 55.12;

    if (!(number - std::nearbyint(number))) {
      std::cout << "Is integer!";
    } else {
      std::cout << "Has decimal!";
    }
    
    return 0;
}

이 기능을 하는 샘플코드가 스니핑되어 있습니다.

if (  ABS( ((int) d1) - (d1)) )< 0.000000001) 

 cout <<"Integer" << endl;

else

 cout <<"Flaot" << endl;

EDIT: 올바른 코드를 반영하도록 변경.

언급URL : https://stackoverflow.com/questions/1521607/check-double-variable-if-it-contains-an-integer-and-not-floating-point

반응형