]> Git Repo - qemu.git/blobdiff - libdecnumber/decNumber.c
vhost-user: add multi queue support
[qemu.git] / libdecnumber / decNumber.c
index 1bfc08173e06de741ef056a922998c0c9684d071..58211e7afdc0fe5b64e7c112a0cb1b17247cd39f 100644 (file)
@@ -436,6 +436,80 @@ uInt decNumberToUInt32(const decNumber *dn, decContext *set) {
   return 0;
   } /* decNumberToUInt32 */
 
+decNumber *decNumberFromInt64(decNumber *dn, int64_t in)
+{
+    uint64_t unsig = in;
+    if (in < 0) {
+        unsig = -unsig;
+    }
+
+    decNumberFromUInt64(dn, unsig);
+    if (in < 0) {
+        dn->bits = DECNEG;        /* sign needed */
+    }
+    return dn;
+} /* decNumberFromInt64 */
+
+decNumber *decNumberFromUInt64(decNumber *dn, uint64_t uin)
+{
+    Unit *up;                             /* work pointer */
+    decNumberZero(dn);                    /* clean */
+    if (uin == 0) {
+        return dn;                /* [or decGetDigits bad call] */
+    }
+    for (up = dn->lsu; uin > 0; up++) {
+        *up = (Unit)(uin % (DECDPUNMAX + 1));
+        uin = uin / (DECDPUNMAX + 1);
+    }
+    dn->digits = decGetDigits(dn->lsu, up-dn->lsu);
+    return dn;
+} /* decNumberFromUInt64 */
+
+/* ------------------------------------------------------------------ */
+/* to-int64 -- conversion to int64                                    */
+/*                                                                    */
+/*  dn is the decNumber to convert.  dn is assumed to have been       */
+/*    rounded to a floating point integer value.                      */
+/*  set is the context for reporting errors                           */
+/*  returns the converted decNumber, or 0 if Invalid is set           */
+/*                                                                    */
+/* Invalid is set if the decNumber is a NaN, Infinite or is out of    */
+/* range for a signed 64 bit integer.                                 */
+/* ------------------------------------------------------------------ */
+
+int64_t decNumberIntegralToInt64(const decNumber *dn, decContext *set)
+{
+    if (decNumberIsSpecial(dn) || (dn->exponent < 0) ||
+       (dn->digits + dn->exponent > 19)) {
+        goto Invalid;
+    } else {
+        int64_t d;        /* work */
+        const Unit *up;   /* .. */
+        uint64_t hi = 0;
+        up = dn->lsu;     /* -> lsu */
+
+        for (d = 1; d <= dn->digits; up++, d += DECDPUN) {
+            uint64_t prev = hi;
+            hi += *up * powers[d-1];
+            if ((hi < prev) || (hi > INT64_MAX)) {
+                goto Invalid;
+            }
+        }
+
+        uint64_t prev = hi;
+        hi *= (uint64_t)powers[dn->exponent];
+        if ((hi < prev) || (hi > INT64_MAX)) {
+            goto Invalid;
+        }
+        return (decNumberIsNegative(dn)) ? -((int64_t)hi) : (int64_t)hi;
+    }
+
+Invalid:
+    decContextSetStatus(set, DEC_Invalid_operation);
+    return 0;
+} /* decNumberIntegralToInt64 */
+
+
 /* ------------------------------------------------------------------ */
 /* to-scientific-string -- conversion to numeric string                      */
 /* to-engineering-string -- conversion to numeric string             */
@@ -3467,7 +3541,7 @@ uByte * decNumberGetBCD(const decNumber *dn, uint8_t *bcd) {
 /* and bcd[0] zero.                                                  */
 /* ------------------------------------------------------------------ */
 decNumber * decNumberSetBCD(decNumber *dn, const uByte *bcd, uInt n) {
-  Unit *up=dn->lsu+D2U(dn->digits)-1;  /* -> msu [target pointer] */
+  Unit *up = dn->lsu + D2U(n) - 1;      /* -> msu [target pointer] */
   const uByte *ub=bcd;                 /* -> source msd */
 
   #if DECDPUN==1                       /* trivial simple copy */
@@ -4229,7 +4303,7 @@ static decNumber * decDivideOp(decNumber *res,
   uByte bits;                     /* working sign */
   Unit *target;                   /* work */
   const Unit *source;             /* .. */
-  uInt const *pow;                /* .. */
+  uLong const *pow;                /* .. */
   Int  shift, cut;                /* .. */
   #if DECSUBSET
   Int  dropped;                   /* work */
@@ -5201,8 +5275,8 @@ static decNumber * decMultiplyOp(decNumber *res, const decNumber *lhs,
 /* 4. The working precisions for the static buffers are twice the     */
 /*    obvious size to allow for calls from decNumberPower.           */
 /* ------------------------------------------------------------------ */
-decNumber * decExpOp(decNumber *res, const decNumber *rhs,
-                        decContext *set, uInt *status) {
+static decNumber *decExpOp(decNumber *res, const decNumber *rhs,
+                           decContext *set, uInt *status) {
   uInt ignore=0;                  /* working status */
   Int h;                          /* adjusted exponent for 0.xxxx */
   Int p;                          /* working precision */
@@ -5489,7 +5563,8 @@ decNumber * decExpOp(decNumber *res, const decNumber *rhs,
 /*          where x is truncated (NB) into the range 10 through 99,  */
 /*          and then c = k>>2 and e = k&3.                           */
 /* ------------------------------------------------------------------ */
-const uShort LNnn[90]={9016,  8652,  8316,  8008,  7724,  7456,         7208,
+static const uShort LNnn[90] = {
+  9016,  8652,  8316,  8008,  7724,  7456,  7208,
   6972,         6748,  6540,  6340,  6148,  5968,  5792,  5628,  5464,  5312,
   5164,         5020,  4884,  4748,  4620,  4496,  4376,  4256,  4144,  4032,
  39233, 38181, 37157, 36157, 35181, 34229, 33297, 32389, 31501, 30629,
@@ -5561,8 +5636,8 @@ const uShort LNnn[90]={9016,  8652,  8316,  8008,  7724,  7456,    7208,
 /* 5. The static buffers are larger than might be expected to allow   */
 /*    for calls from decNumberPower.                                 */
 /* ------------------------------------------------------------------ */
-decNumber * decLnOp(decNumber *res, const decNumber *rhs,
-                   decContext *set, uInt *status) {
+static decNumber *decLnOp(decNumber *res, const decNumber *rhs,
+                          decContext *set, uInt *status) {
   uInt ignore=0;                  /* working status accumulator */
   uInt needbytes;                 /* for space calculations */
   Int residue;                    /* rounding residue */
@@ -5978,9 +6053,9 @@ static decNumber * decQuantizeOp(decNumber *res, const decNumber *lhs,
 /* The emphasis here is on speed for common cases, and avoiding              */
 /* coefficient comparison if possible.                               */
 /* ------------------------------------------------------------------ */
-decNumber * decCompareOp(decNumber *res, const decNumber *lhs,
-                        const decNumber *rhs, decContext *set,
-                        Flag op, uInt *status) {
+static decNumber *decCompareOp(decNumber *res, const decNumber *lhs,
+                               const decNumber *rhs, decContext *set,
+                               Flag op, uInt *status) {
   #if DECSUBSET
   decNumber *alloclhs=NULL;       /* non-NULL if rounded lhs allocated */
   decNumber *allocrhs=NULL;       /* .., rhs */
@@ -6012,11 +6087,11 @@ decNumber * decCompareOp(decNumber *res, const decNumber *lhs,
 
     /* If total ordering then handle differing signs 'up front' */
     if (op==COMPTOTAL) {               /* total ordering */
-      if (decNumberIsNegative(lhs) & !decNumberIsNegative(rhs)) {
+      if (decNumberIsNegative(lhs) && !decNumberIsNegative(rhs)) {
        result=-1;
        break;
        }
-      if (!decNumberIsNegative(lhs) & decNumberIsNegative(rhs)) {
+      if (!decNumberIsNegative(lhs) && decNumberIsNegative(rhs)) {
        result=+1;
        break;
        }
@@ -7403,7 +7478,6 @@ static void decSetMaxValue(decNumber *dn, decContext *set) {
 /* ------------------------------------------------------------------ */
 static void decSetSubnormal(decNumber *dn, decContext *set, Int *residue,
                            uInt *status) {
-  Int       dnexp;           /* saves original exponent */
   decContext workset;        /* work */
   Int       etiny, adjust;   /* .. */
 
@@ -7448,7 +7522,6 @@ static void decSetSubnormal(decNumber *dn, decContext *set, Int *residue,
 
   /* adjust>0, so need to rescale the result so exponent becomes Etiny */
   /* [this code is similar to that in rescale] */
-  dnexp=dn->exponent;                  /* save exponent */
   workset=*set;                                /* clone rounding, etc. */
   workset.digits=dn->digits-adjust;    /* set requested length */
   workset.emin-=adjust;                        /* and adjust emin to match */
This page took 0.029239 seconds and 4 git commands to generate.