# Re: Comparing Arbitrary-Precision Integers

Discussion in 'C Programming' started by Michael Angelo Ravera, Jul 27, 2012.

1. ### Michael Angelo RaveraGuest

On Thursday, July 26, 2012 1:06:44 PM UTC-7, David T. Ashley wrote:
> Hi,
>
> I'm using a 2's complement machine (and I'm comfortable baking this
> assumption into the code). I've implemented a large number of
> functions on signed integers that are longer than the machine
> supports.
>
> Does the code below for comparison look correct?
>
> I think the right approach is to compare the most significant limb in
> a signed sense then to compare the least significant limbs in an
> unsigned sense. Is that right?
>
> Code below.
>
> Thanks, Dave A.
>
> ---------
>
> //Signed 96-bit synthetic type, stored least significant words first
> (similar to the
> //way the GMP treats limbs).
> //
> //The dual representation is used because this way the compiler can be
> coerced to
> //choose appropriate instructions in different situations.
> typedef union
> {
> UNSIGNED32_T uw[3];
> SIGNED32_T sw[3];
> } APP_BIGINT_S96_T;
>
>
> //----------------------------------------------------------------------------------------------------
> //DESCRIPTION
> // Compares two signed 96-bit integers and returns -1 if a &lt; b, 0 if
> a == b, and 1 if a &gt; b.
> //
> //INPUTS
> // *in_a, *in_b:
> // Two signed 96-bit integers to compare.
> //
> //OUTPUTS
> // &lt;--
> // -1 if *in_a &lt; *in_b, 0 if *in_a == *in_b, and 1 if *in_a &gt;
> *in_b.
> //
> //EXCEPTION CONDITIONS
> // Passing a NULL or invalid pointer for in_a or in_b will result in
> undefined behavior.
> //
> //REENTRANCY
> // This function has not been evaluated for re-entrancy or thread
> safety. This function is
> // designed to be called from background (non-ISR) software only.
> //
> //UNIT TEST HISTORY
> // 20120713: Not yet unit tested.
> //----------------------------------------------------------------------------------------------------
> SIGNED32_T APP_S96_Cmp(const APP_BIGINT_S96_T *in_a, const
> APP_BIGINT_S96_T *in_b)
> {
> if (in_a-&gt;sw[2] &lt; in_b-&gt;sw[2])
> {
> return(-1);
> }
> else if (in_a-&gt;sw[2] &gt; in_b-&gt;sw[2])
> {
> return(1);
> }
> else if (in_a-&gt;uw[1] &lt; in_b-&gt;uw[1])
> {
> return(-1);
> }
> else if (in_a-&gt;uw[1] &gt; in_b-&gt;uw[1])
> {
> return(1);
> }
> else if (in_a-&gt;uw[0] &lt; in_b-&gt;uw[0])
> {
> return(-1);
> }
> else if (in_a-&gt;uw[0] &gt; in_b-&gt;uw[0])
> {
> return(1);
> }
> else
> {
> return(0);
> }
> }

Your code is reentrant because you aren't storing off any results in the middle of the calculation into static variables and you aren't making changesto the underlying code. Whether your code is thread safe or not depends upon the attributes applied to the various instances of APP_BIGINT_S96Ts thatyou declare.

Michael Angelo Ravera, Jul 27, 2012