퀴즈! 두 int값의 +연산후 오버플로우 여부 알아내기...

kkb110의 이미지

c++ 문제 한번풀어보세요 ~ ㅎㅎ

문제->

int타입의 변수 a,b 가 있다.
c = a + b; 일때 c가 오버플로우나 언더플로우가 일어나는지 판별하는 함수를 작성하시오.
코드가 빠를수록 점수가 높음.

bool func(int a,int b)
{
         return //오버플로우나 언더플로우가 일어나면 true 안일어나면 false;
}
Forums: 
htna의 이미지

숙제같은 느낌이 드는건 왜일까요. ?

bool func(int a,int b) 
{
    long la, lb;
    return ((la + lb) > __max_int) || ((la + lb) < __min_int);
}

__max_int, __min_int 는 알아서.. ㅋㅋ
int만 가지고 확인하는 방법이 있기는 하지만...
직접 알아보시는것도.. ^^

WOW Wow!!!
Computer Science is no more about computers than astronomy is about telescopes.
-- E. W. Dijkstra

bugiii의 이미지

htna wrote:
bool func(int a,int b) 
{
    long la, lb;
    return ((la + lb) > __max_int) || ((la + lb) < __min_int);
}

int 와 long 타입의 크기가 같은 환경에서는 곤란하지 않을까요?

int 형이므로 a, b 부호가 다르면 일단 over-, underflow 가 발생하지 않을 것이고, 부호가 같다면 절대값으로 문제를 해결할 수도 있을 것 같습니다.

일단 범위를 줄여서 생각해봅시다. int 말고 signed char 타입으로 생각해볼께요. (값의 범위만 틀리지 특성은 동일하므로)

signed char 타입이 가지는 범위는 -128 ~ 127 입니다.
여기서 덧셈 연산의 overflow 는 두 양 수의 합이 127을 넘는 경우이고 양의 두 수의 합의 최대값은 127 + 127 = 254 ( <= 255 ) 입니다. 그러므로 unsinged char 로 두 수를 변환한 후에 더하고 그 값을 구해서 127 < sum 이라고 판단하면 될 것 같습니다.

음수의 최소값은 -128 이므로 2개의 음수의 합의 최소 절대값은 256 이 되기때문에 unsigned char 로는 표현할 수 없는 숫자가 됩니다. 그러므로 128 < abs(a) + abs(b) 같이 하면 두 수의 절대값의 합이 256이 아닌 underflow 를 판별할 수 있습니다.

이 경우는 예외처리를 해서 두수가 모두 -128 이면 underflow 로 동작하게 해야 할 것 같습니다.

이제 이것을 범위를 넓혀서 int 의 최대 최소값을 조사하셔서 적용하시면 되겠습니다. 일반적으로 2의 보수로 표현하는 정수의 경우 타입의 비트수가 n 이면 -2^(n-1) <= num <= 2^(n-1)-1 이므로 해당하는 환경의 int 타입의 비트수를 조사하시면 되겠습니다.

p.s. 숙제스러운 질문에 직접적인 코드는 기술하지 맙시다. -_-;

htna의 이미지

음.. 재밌네요..
이런거에 재미를 붙이다니. orz
테스트는 안해봤습니다.

bool func(int a,int b) 
{ 
    return !(
        ((a&0xF000) != (b&0xF000)) ||
        ((a&0xF000) == ((a+b)&0xF000))
    );
}

PS:
kkb110님이 올리신 글을보고 숙제는 아니라고 판단이 들었네요.
class CBigInteger 머 이런거 만드는 게시판에 올라온 글의 내용을.
여기에 부분적으로 따로 올리신듯...

PS2:
int라고 함수에서 한정을 지어서 이렇게 했습니다만..
정확하게 하자면 signed냐 unsigned냐에 따라 다르게 작업(어디에?)이 들어가야 겠지요 ?
그리고 각 데이터 타입에 따라 다르게 들어가야 하구요..

WOW Wow!!!
Computer Science is no more about computers than astronomy is about telescopes.
-- E. W. Dijkstra

htna의 이미지

template<typename T>
T XXX() {
    return (0x01 << (sizeof(T)*8 - 1));
}
template<typename T>
bool overunderfulo_signed(T a,T b) 
{ 
    return !( 
        ((a&XXX()) != (b&XXX())) || 
        ((a&XXX()) == ((a+b)&XXX())) 
    ); 
}
template<typename T>
bool overunderfulo_unsigned(T a,T b) 
{ 
    return ((a+b < a) || (a+b < b)); 
}

XXX의 명칭이 머더라..
치매가오려나.. 기억이 안나네요...

음...
ASM에서 두 변수의 연산시에 발생한는 overflow bit를 이용하는 방법도 있기는 한데..
기억이 잘 안나네요.. 오래되넘은 거라서...
그렇다고 다시 학부때 ASM 책 뒤지기는 싫고..
귀차니즘의 압박이... orz

WOW Wow!!!
Computer Science is no more about computers than astronomy is about telescopes.
-- E. W. Dijkstra

bugiii의 이미지

그래서 절대값을 구하고 unsigned char 를 이용했습니다.

주어진 타입보다 큰 타입을 이용하면 해당 환경이 지원하지 못하는 경우에는 구현이 불가능합니다.

또한 두 수의 합을 같은 타입으로 계산하면 타입의 최소, 최대값의 경계 값을 넘어서서 오버레핑이 일어나면 잘못된 비교가 될 수 있습니다.

그래서, 어떻게든 연산의 결과가 타입의 범위 안에서 이루어지도록 해야 한다고 생각해서 글을 올렸습니다.

p.s. 엇? 글이 하나가???

htna의 이미지

bugiii wrote:
p.s. 엇? 글이 하나가???

사라졌죠.. ^^;;
제가 올린 글이 좀 딴지성 같아서 올리자마자 지웠는데...
그새 새로운 글이 밑에 붙었네요..
음.. 글 지우는거 정말 조심해야 겠군요..
죄송합니다. ^^

WOW Wow!!!
Computer Science is no more about computers than astronomy is about telescopes.
-- E. W. Dijkstra

doldori의 이미지

재미있는 문제로군요. 일단 연산 결과가 표현 가능한 범위 안에서 이루어져야 한다는
bugiii님의 말씀이 결정적인 힌트입니다. a + b > max를 바꿔서 a > max - b로,
a + b < min을 a < min - b로 생각하면 되겠습니다. 다른 사칙연산에 대해서도
유사한 방법으로 하면 됩니다. 곱셈과 나눗셈의 경우에는 좀 더 복잡합니다만.

htna wrote:
int라고 함수에서 한정을 지어서 이렇게 했습니다만..
정확하게 하자면 signed냐 unsigned냐에 따라 다르게 작업(어디에?)이 들어가야 겠지요 ?
그리고 각 데이터 타입에 따라 다르게 들어가야 하구요..

이걸 보면 템플릿이 딱 떠오르는군요.
힌트 끝! ^^;
htna의 이미지

코드 좀 정리 합니다...
속도좀 빠르게 하려구요.. ^^;
이런거 재미붙이면 안되는데...
근데 제대로 돌아갈까요.. ??
돌려보지를 않아서리. orz

template<typename T> 
bool overunderflow_signed(T a,T b) 
{
    class CXXX {
    public:
        T xxx;
        CXXX() {
            xxx = (0x01 << (sizeof(T)*8 - 1));
        }
    };
    static CXXX xxx;
    return !( 
        ((a&xxx.xxx) != (b&xxx.xxx)) || 
        ((a&xxx.xxx) == ((a+b)&xxx.xxx)) 
    ); 
} 
template<typename T> 
bool overunderflow_unsigned(T a,T b) 
{ 
    return ((a+b < a) || (a+b < b)); 
}

PS:
허거걱... 여기에
overunderflow_signed, overunderflow_unsigned

overunderfulo_signed, overunderfulo_unsigned
로 적었네요..
흐미.. 다른분들 보구 또 머라 하시겠다.. ㅡ.ㅜ
수정합니다.. ^^;;

WOW Wow!!!
Computer Science is no more about computers than astronomy is about telescopes.
-- E. W. Dijkstra

정태영의 이미지

doldori wrote:
재미있는 문제로군요. 일단 연산 결과가 표현 가능한 범위 안에서 이루어져야 한다는
bugiii님의 말씀이 결정적인 힌트입니다. a + b > max를 바꿔서 a > max - b로,
a + b < min을 a < min - b로 생각하면 되겠습니다. 다른 사칙연산에 대해서도
유사한 방법으로 하면 됩니다. 곱셈과 나눗셈의 경우에는 좀 더 복잡합니다만.

x86 instruction manual 을 찾아봤습니다...

Quote:
It evaluates the result for both signed and unsigned integer operands and sets the OF and CF flags to indicate a carry(overflow) in the signed or unsigned result, respectively

OF 플래그나 CF 플래그가 발생했는지 확인해보면 되겠군요 :)

곱하기나 나누기도 마찬가지입니다 =3=33

오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

cppig1995의 이미지

bool func(int a, int b)
{
   bool Bigger = true;

   if((a < 0) || (b < 0)) Bigger = !Bigger;


   int c = a + b;

   if(Bigger && ((c < a) || (c < b))) return false;
   else if(!Bigger && ((c > a) || (c > b))) return false;
   
   return true;
}

Real programmers /* don't */ comment their code.
If it was hard to write, it should be /* hard to */ read.

cppig1995의 이미지

정태영 wrote:
doldori wrote:
재미있는 문제로군요. 일단 연산 결과가 표현 가능한 범위 안에서 이루어져야 한다는
bugiii님의 말씀이 결정적인 힌트입니다. a + b > max를 바꿔서 a > max - b로,
a + b < min을 a < min - b로 생각하면 되겠습니다. 다른 사칙연산에 대해서도
유사한 방법으로 하면 됩니다. 곱셈과 나눗셈의 경우에는 좀 더 복잡합니다만.

x86 instruction manual 을 찾아봤습니다...

Quote:
It evaluates the result for both signed and unsigned integer operands and sets the OF and CF flags to indicate a carry(overflow) in the signed or unsigned result, respectively

OF 플래그나 CF 플래그가 발생했는지 확인해보면 되겠군요 :)

곱하기나 나누기도 마찬가지입니다 =3=33

Architecture Dependent?

Real programmers /* don't */ comment their code.
If it was hard to write, it should be /* hard to */ read.

cppig1995의 이미지

kkb110 wrote:
c++ 문제 한번풀어보세요 ~ ㅎㅎ

문제->

int타입의 변수 a,b 가 있다.
c = a + b; 일때 c가 오버플로우나 언더플로우가 일어나는지 판별하는 함수를 작성하시오.
코드가 빠를수록 점수가 높음.

bool func(int a,int b)
{
         return //오버플로우나 언더플로우가 일어나면 true 안일어나면 false;
}

Warning on Line 003 : Prototype of function 'func' specified to return 'bool' value. Garbage value will return

I am compiler... orz

Real programmers /* don't */ comment their code.
If it was hard to write, it should be /* hard to */ read.

philossh의 이미지

c에서 플래그 레지스터의 상태를 얻어오는 방법은 없나요??

To be or not to be.
That is the question.

정태영의 이미지

cppig1995 wrote:
Architecture Dependent?

예 아키텍쳐에 의존적이긴 하겠지요 :)

philossh wrote:
c에서 플래그 레지스터의 상태를 얻어오는 방법은 없나요??

인라인 어셈블리를 쓰는 거 말고는 잘 모르겠군요....

오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

doldori의 이미지

cppig1995 wrote:
bool func(int a, int b)
{
   /* ... */
   int c = a + b;
   /* ... */
}

두 수를 더한 결과가 범위를 넘어선다면 더하는 행위 자체가 정의되지 않는 결과를
낳습니다. a + b 같은 코드가 나오면 안되는 거죠.
morris의 이미지

htna님이 하신거랑 비슷하지만

bool func(int a, int b)
{
    unsigned int c, result;

    c = (unsigned)a + (unsigned)b;
    result = (a ^ c) & (b ^ c);
    if (result & (0x80 << (sizeof(int)-1)*8))
        return 1;
    else
        return 0;
}

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.