[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-ppc] [PATCH 10/37] libdecnumber: Introduce decNumberIntegralToInt6
From: |
Tom Musta |
Subject: |
[Qemu-ppc] [PATCH 10/37] libdecnumber: Introduce decNumberIntegralToInt64 |
Date: |
Fri, 18 Apr 2014 09:50:14 -0500 |
Introduce a new conversion function to the libdecnumber library.
This function converts a decNumber to a signed 64-bit integer.
In order to support 64-bit integers (which may have up to 19
decimal digits), the existing "powers of 10" array is expanded
from 10 to 19 entries.
Signed-off-by: Tom Musta <address@hidden>
---
include/libdecnumber/decNumber.h | 1 +
include/libdecnumber/decNumberLocal.h | 2 +-
libdecnumber/decContext.c | 6 +++-
libdecnumber/decNumber.c | 46 ++++++++++++++++++++++++++++++++-
4 files changed, 51 insertions(+), 4 deletions(-)
diff --git a/include/libdecnumber/decNumber.h b/include/libdecnumber/decNumber.h
index f4bf994..9fa4e6a 100644
--- a/include/libdecnumber/decNumber.h
+++ b/include/libdecnumber/decNumber.h
@@ -122,6 +122,7 @@
char * decNumberToEngString(const decNumber *, char *);
uint32_t decNumberToUInt32(const decNumber *, decContext *);
int32_t decNumberToInt32(const decNumber *, decContext *);
+ int64_t decNumberIntegralToInt64(const decNumber *dn, decContext *set);
uint8_t * decNumberGetBCD(const decNumber *, uint8_t *);
decNumber * decNumberSetBCD(decNumber *, const uint8_t *, uint32_t);
diff --git a/include/libdecnumber/decNumberLocal.h
b/include/libdecnumber/decNumberLocal.h
index f5f508f..cd4eb79 100644
--- a/include/libdecnumber/decNumberLocal.h
+++ b/include/libdecnumber/decNumberLocal.h
@@ -98,7 +98,7 @@
/* Shared lookup tables */
extern const uByte DECSTICKYTAB[10]; /* re-round digits if sticky */
- extern const uInt DECPOWERS[10]; /* powers of ten table */
+ extern const uLong DECPOWERS[19]; /* powers of ten table */
/* The following are included from decDPD.h */
extern const uShort DPD2BIN[1024]; /* DPD -> 0-999 */
extern const uShort BIN2DPD[1000]; /* 0-999 -> DPD */
diff --git a/libdecnumber/decContext.c b/libdecnumber/decContext.c
index 737cca9..88e5dd0 100644
--- a/libdecnumber/decContext.c
+++ b/libdecnumber/decContext.c
@@ -56,8 +56,10 @@ const uByte DECSTICKYTAB[10]={1,1,2,3,4,6,6,7,8,9}; /* used
if sticky */
/* ------------------------------------------------------------------ */
/* Powers of ten (powers[n]==10**n, 0<=n<=9) */
/* ------------------------------------------------------------------ */
-const uInt DECPOWERS[10]={1, 10, 100, 1000, 10000, 100000, 1000000,
- 10000000, 100000000, 1000000000};
+const uLong DECPOWERS[19] = {1, 10, 100, 1000, 10000, 100000, 1000000,
+ 10000000, 100000000, 1000000000, 10000000000, 100000000000,
+ 1000000000000, 10000000000000, 100000000000000, 1000000000000000,
+ 10000000000000000, 100000000000000000, 1000000000000000000, };
/* ------------------------------------------------------------------ */
/* decContextClearStatus -- clear bits in current status */
diff --git a/libdecnumber/decNumber.c b/libdecnumber/decNumber.c
index 01ef30a..825fde0 100644
--- a/libdecnumber/decNumber.c
+++ b/libdecnumber/decNumber.c
@@ -471,6 +471,50 @@ decNumber *decNumberFromUInt64(decNumber *dn, uint64_t uin)
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 */
@@ -4265,7 +4309,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 */
--
1.7.1
- [Qemu-ppc] [PATCH 00/37] target-ppc: Decimal Floating Point, Tom Musta, 2014/04/18
- [Qemu-ppc] [PATCH 02/37] libdecnumber: Eliminate #include *Symbols.h, Tom Musta, 2014/04/18
- [Qemu-ppc] [PATCH 03/37] libdecnumber: Prepare libdecnumber for QEMU include structure, Tom Musta, 2014/04/18
- [Qemu-ppc] [PATCH 04/37] libdecnumber: Modify dconfig.h to Integrate with QEMU, Tom Musta, 2014/04/18
- [Qemu-ppc] [PATCH 05/37] libdecnumber: Change gstdint.h to stdint.h, Tom Musta, 2014/04/18
- [Qemu-ppc] [PATCH 06/37] libdecnumber: Eliminate redundant declarations, Tom Musta, 2014/04/18
- [Qemu-ppc] [PATCH 07/37] libdecnumber: Eliminate Unused Variable in decSetSubnormal, Tom Musta, 2014/04/18
- [Qemu-ppc] [PATCH 15/37] target-ppc: Introduce DFP Helper Utilities, Tom Musta, 2014/04/18
- [Qemu-ppc] [PATCH 10/37] libdecnumber: Introduce decNumberIntegralToInt64,
Tom Musta <=
- [Qemu-ppc] [PATCH 08/37] target-ppc: Enable Building of libdecnumber, Tom Musta, 2014/04/18
- [Qemu-ppc] [PATCH 11/37] libdecnumber: Fix decNumberSetBCD, Tom Musta, 2014/04/18
- [Qemu-ppc] [PATCH 09/37] libdecnumber: Introduce decNumberFrom[U]Int64, Tom Musta, 2014/04/18
- [Qemu-ppc] [PATCH 12/37] target-ppc: Define FPR Pointer Type for Helpers, Tom Musta, 2014/04/18
- [Qemu-ppc] [PATCH 13/37] target-ppc: Introduce Generator Macros for DFP Arithmetic Forms, Tom Musta, 2014/04/18
- [Qemu-ppc] [PATCH 14/37] target-ppc: Introduce Decoder Macros for DFP, Tom Musta, 2014/04/18
- [Qemu-ppc] [PATCH 17/37] target-ppc: Introduce DFP Add, Tom Musta, 2014/04/18