Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: Macros versus Inline - correction

Author: Gerd Isenberg

Date: 00:18:36 09/27/03

Go up one level in this thread


On September 26, 2003 at 18:38:46, Dieter Buerssner wrote:

>On September 26, 2003 at 16:36:14, Gerd Isenberg wrote:
>
>Before I try more, are the macros/inline functions designed to work for all
>integers.

Hi Dieter,

yes, you found the weak point in this _min/_max-functions.
If an overflow occurs in the subtraction (a-b) they are wrong.
Therefore the appropriated range should be -2**(N-2)+1 .... 2**(N-2), which is
good enough for my porpuse, where i use them in common score range, which fits
in 16-bit ints.

>
>I tried
>
>#include <stdlib.h>
>#include <stdio.h>
>
>#if __GNUC__
>#define MY_INLINE __inline__
>#else
>#define MY_INLINE __forceinline
>#endif
>
>/* Not really portable, but that is not an issue here */
>#define minusMask(a)  ((int)(a)>>(sizeof(int)*8-1))
>#define ifLessZero(a) ((a) & minusMask(a))
>
>/* I am not 100% sure, but names like _abs - with the leading underscore,
>   may belong to the name space of the implementation. Also no issue here */

I see. Considering the reduced validity range,
i should use other names, e.g. scoreMin, scoreMax.

>
>MY_INLINE int _abs(int a)        {return a - 2*ifLessZero(a);}
>MY_INLINE int _max(int a, int b) {return a - ifLessZero(a-b);}
>MY_INLINE int _min(int a, int b) {return a + ifLessZero(b-a);}
>
>
>#define _absm(a)   ((a) - 2*ifLessZero(a))
>#define _maxm(a,b) ((a) - ifLessZero((a)-(b)))
>#define _minm(a,b) ((a) + ifLessZero((b)-(a)))
>
>int min(int a, int b) {return a<b?a:b;}
>int max(int a, int b) {return a>b?a:b;}
>
>int main(int argc, char *argv[])
>{
>  int a, b, ri, rm, rl;
>  if (argc != 3)
>    return 1;
>  a = atoi(argv[1]);
>  b = atoi(argv[2]);
>
>  printf("a=%d, b=%d\n", a, b);
>
>  ri = _abs(a);
>  rm = _absm(a);
>  rl = abs(a);
>
>  printf("abs(a): inline %d, macro %d, lib %d\n", ri, rm, rl);
>
>  ri = _abs(b);
>  rm = _absm(b);
>  rl = abs(b);
>
>  printf("abs(b): inline %d, macro %d, lib %d\n", ri, rm, rl);
>
>  ri = _min(a,b);
>  rm = _minm(a,b);
>  rl = min(a,b);
>
>  printf("min(a,b): inline %d, macro %d, lib %d\n", ri, rm, rl);
>
>  ri = _max(a,b);
>  rm = _maxm(a,b);
>  rl = max(a,b);
>
>  printf("max(a,b): inline %d, macro %d, lib %d\n", ri, rm, rl);
>
>  return 0;
>}
>
>I get:
>
>a=2147483647, b=-2147483647
>abs(a): inline 2147483647, macro 2147483647, lib 2147483647
>abs(b): inline 2147483647, macro 2147483647, lib 2147483647
>min(a,b): inline 2147483647, macro 2147483647, lib -2147483647
>max(a,b): inline -2147483647, macro -2147483647, lib 2147483647
>
>Gcc seems to produce identical code for the macro and for the inline version, if
>I looked correctly.
>
>BTW. I always wondered why the return value for abs is not unsigned. For example
>with typical 2 complements implementation abs(INT_MIN) will fail, while an
>unsigned result would be ok.
>

Yes, but one has to be care about -(INT_MIN) in any case.
Most often one assigns abs or int-expressions with abs to some int variables.
Ok, abs leaves anly positive results per definition. But changing the "semantic"
of the sign-bit during this function call only for INT_MIN may lead to some
other confusions.

Regards,
Gerd

>Regards,
>Dieter




This page took 0 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.