static constexpr Part topPartMask{static_cast<Part>(~0) >> extraTopPartBits};
public:
+ struct ValueWithOverflow {
+ Integer value;
+ bool overflow;
+ };
+
+ struct ValueWithCarry {
+ Integer value;
+ bool carry;
+ };
+
+ struct Product {
+ Integer upper, lower;
+ };
+
+ struct QuotientWithRemainder {
+ Integer quotient, remainder;
+ bool divisionByZero, overflow;
+ };
+
// Constructors and value-generating static functions
constexpr Integer() { Clear(); } // default constructor: zero
constexpr Integer(const Integer &) = default;
}
}
+ static constexpr ValueWithOverflow ReadUnsigned(
+ const char *&pp, std::uint64_t base = 10) {
+ Integer result;
+ bool overflow{false};
+ const char *p{pp};
+ while (*p == ' ' || *p == '\t') {
+ ++p;
+ }
+ if (*p == '+') {
+ ++p;
+ }
+ Integer radix{base};
+ for (; unsigned char ch = *p; ++p) {
+ std::uint64_t digit;
+ if (ch >= '0' && ch < '0' + base) {
+ digit = ch - '0';
+ } else if (base > 10 && ch >= 'A' && ch < 'A' + base - 10) {
+ digit = ch - 'A' + 10;
+ } else if (base > 10 && ch >= 'a' && ch < 'a' + base - 10) {
+ digit = ch - 'a' + 10;
+ } else {
+ break;
+ }
+ Product shifted{result.MultiplyUnsigned(radix)};
+ overflow |= !shifted.upper.IsZero();
+ ValueWithCarry next{shifted.lower.AddUnsigned(Integer{digit})};
+ overflow |= next.carry;
+ result = next.value;
+ }
+ pp = p;
+ return {result, overflow};
+ }
+
static constexpr Integer HUGE() { return MASKR(bits - 1); }
// Returns the number of full decimal digits that can be represented.
// Two's-complement negation (-x = ~x + 1).
// An overflow flag accompanies the result, and will be true when the
// operand is the most negative signed number (MASKL(1)).
- struct ValueWithOverflow {
- Integer value;
- bool overflow;
- };
constexpr ValueWithOverflow Negate() const {
Integer result{nullptr};
Part carry{1};
}
// Unsigned addition with carry.
- struct ValueWithCarry {
- Integer value;
- bool carry;
- };
constexpr ValueWithCarry AddUnsigned(
const Integer &y, bool carryIn = false) const {
Integer sum{nullptr};
}
}
- struct Product {
- Integer upper, lower;
- };
constexpr Product MultiplyUnsigned(const Integer &y) const {
Part product[2 * parts]{}; // little-endian full product
for (int j{0}; j < parts; ++j) {
return product;
}
- struct QuotientWithRemainder {
- Integer quotient, remainder;
- bool divisionByZero, overflow;
- };
constexpr QuotientWithRemainder DivideUnsigned(const Integer &divisor) const {
if (divisor.IsZero()) {
return {MASKR(bits), Integer{}, true, false}; // overflow to max value
)
add_executable(leading-zero-bit-count-test
- leading-zero-bit-count-test.cc
+ leading-zero-bit-count.cc
)
target_link_libraries(leading-zero-bit-count-test
)
add_executable(bit-population-count-test
- bit-population-count-test.cc
+ bit-population-count.cc
)
target_link_libraries(bit-population-count-test
)
add_executable(integer-test
- integer-test.cc
+ integer.cc
)
target_link_libraries(integer-test
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "testing.h"
#include "../../lib/evaluate/bit-population-count.h"
+#include "testing.h"
using Fortran::evaluate::BitPopulationCount;
using Fortran::evaluate::Parity;
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "testing.h"
#include "../../lib/evaluate/integer.h"
+#include "testing.h"
#include <cstdio>
using Fortran::evaluate::Integer;
MATCH(0, zero.ToInt64())(desc);
for (std::uint64_t x{0}; x <= maxUnsignedValue; ++x) {
+ unsigned long long ullx = x;
INT a{x};
MATCH(x, a.ToUInt64())(desc);
INT copy{a};
copy = a;
MATCH(x, copy.ToUInt64())(desc);
MATCH(x == 0, a.IsZero())("%s, x=0x%llx", desc, x);
+ char buffer[64];
+ std::snprintf(buffer, sizeof buffer, " %llu", ullx);
+ const char *p{buffer};
+ auto readcheck{INT::ReadUnsigned(p)};
+ TEST(!readcheck.overflow)("%s, x=0x%llx", desc, x);
+ MATCH(x, readcheck.value.ToUInt64())("%s, x=0x%llx", desc, x);
+ TEST(!*p)("%s, x=0x%llx", desc, x);
+ std::snprintf(buffer, sizeof buffer, "%llx", ullx);
+ p = buffer;
+ readcheck = INT::ReadUnsigned(p, 16);
+ TEST(!readcheck.overflow)("%s, x=0x%llx", desc, x);
+ MATCH(x, readcheck.value.ToUInt64())("%s, x=0x%llx", desc, x);
+ TEST(!*p)("%s, x=0x%llx", desc, x);
INT t{a.NOT()};
MATCH(x ^ maxUnsignedValue, t.ToUInt64())("%s, x=0x%llx", desc, x);
auto negated{a.Negate()};
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "testing.h"
#include "../../lib/evaluate/leading-zero-bit-count.h"
+#include "testing.h"
using Fortran::evaluate::LeadingZeroBitCount;