BSON-XS

 view release on metacpan or  search on metacpan

bson/bson-decimal128.c  view on Meta::CPAN

            low;
} _bson_uint128_6464_t;


/**
 *-------------------------------------------------------------------------
 *
 * mul64x64 --
 *
 *    This function multiplies two &uint64_t into a &_bson_uint128_6464_t.
 *
 * Returns:
 *    The product of @left and @right.
 *
 * Side Effects:
 *    None.
 *
 *-------------------------------------------------------------------------
 */
static void
_mul_64x64 (uint64_t              left,    /* IN */
            uint64_t              right,   /* IN */
            _bson_uint128_6464_t *product) /* OUT */
{
   uint64_t left_high, left_low,
            right_high, right_low,
            product_high, product_mid, product_mid2, product_low;
   _bson_uint128_6464_t rt = { 0 };

   if (!left && !right) {
      *product = rt;
      return;
   }

   left_high = left >> 32;
   left_low = (uint32_t)left;
   right_high = right >> 32;
   right_low = (uint32_t)right;

   product_high = left_high * right_high;
   product_mid = left_high * right_low;
   product_mid2 = left_low * right_high;
   product_low = left_low * right_low;

   product_high += product_mid >> 32;
   product_mid = (uint32_t)product_mid + product_mid2 + (product_low >> 32);

   product_high = product_high + (product_mid >> 32);
   product_low = (product_mid << 32) + (uint32_t)product_low;

   rt.high = product_high;
   rt.low = product_low;
   *product = rt;
}

/**
 *------------------------------------------------------------------------------
 *
 * _dec128_tolower --
 *
 *    This function converts the ASCII character @c to lowercase.  It is locale
 *    insensitive (unlike the stdlib tolower).
 *
 * Returns:
 *    The lowercased character.
 */
char
_dec128_tolower (char c)
{
   if (isupper (c)) {
      c += 32;
   }

   return c;
}

/**
 *------------------------------------------------------------------------------
 *
 * _dec128_istreq --
 *
 *    This function compares the null-terminated *ASCII* strings @a and @b
 *    for case-insensitive equality.
 *
 * Returns:
 *    true if the strings are equal, false otherwise.
 */
bool
_dec128_istreq (const char *a, /* IN */
                const char *b /* IN */)
{
   while (*a != '\0' || *b != '\0') {
      /* strings are different lengths. */
      if (*a == '\0' || *b == '\0') {
         return false;
      }

      if (_dec128_tolower (*a) != _dec128_tolower (*b)) {
         return false;
      }

      a++;
      b++;
   }

   return true;
}

/**
 *------------------------------------------------------------------------------
 *
 * bson_decimal128_from_string --
 *
 *    This function converts @string in the format [+-]ddd[.]ddd[E][+-]dddd to
 *    decimal128.  Out of range values are converted to +/-Infinity.  Invalid
 *    strings are converted to NaN.
 *
 *    If more digits are provided than the available precision allows,
 *    round to the nearest expressable decimal128 with ties going to even will
 *    occur.
 *



( run in 1.022 second using v1.01-cache-2.11-cpan-a5162978ef8 )