src/util/pm_integer.c in prism-0.28.0 vs src/util/pm_integer.c in prism-0.30.0
- old
+ new
@@ -46,11 +46,11 @@
*destination = (pm_integer_t) { 0, length, values, false };
}
/**
* Internal use for karatsuba_multiply. Calculates `a - b - c` with the given
- * base. Assume a, b, c, a - b - c all to be poitive.
+ * base. Assume a, b, c, a - b - c all to be positive.
* Return pm_integer_t with values allocated. Not normalized.
*/
static void
big_sub2(pm_integer_t *destination, pm_integer_t *a, pm_integer_t *b, pm_integer_t *c, uint64_t base) {
size_t a_length;
@@ -469,19 +469,22 @@
/**
* Parse an integer from a string. This assumes that the format of the integer
* has already been validated, as internal validation checks are not performed
* here.
*/
-PRISM_EXPORTED_FUNCTION void
+void
pm_integer_parse(pm_integer_t *integer, pm_integer_base_t base, const uint8_t *start, const uint8_t *end) {
- // Ignore unary +. Unary + is parsed differently and will not end up here.
+ // Ignore unary +. Unary - is parsed differently and will not end up here.
// Instead, it will modify the parsed integer later.
if (*start == '+') start++;
// Determine the multiplier from the base, and skip past any prefixes.
uint32_t multiplier = 10;
switch (base) {
+ case PM_INTEGER_BASE_DEFAULT:
+ while (*start == '0') start++; // 01 -> 1
+ break;
case PM_INTEGER_BASE_BINARY:
start += 2; // 0b
multiplier = 2;
break;
case PM_INTEGER_BASE_OCTAL:
@@ -532,18 +535,10 @@
integer->value = (uint32_t) value;
}
/**
- * Return the memory size of the integer.
- */
-size_t
-pm_integer_memsize(const pm_integer_t *integer) {
- return sizeof(pm_integer_t) + integer->length * sizeof(uint32_t);
-}
-
-/**
* Compare two integers. This function returns -1 if the left integer is less
* than the right integer, 0 if they are equal, and 1 if the left integer is
* greater than the right integer.
*/
int
@@ -568,9 +563,42 @@
if (left_value < right_value) return -1 * negative;
if (left_value > right_value) return 1 * negative;
}
return 0;
+}
+
+/**
+ * Reduce a ratio of integers to its simplest form.
+ */
+void pm_integers_reduce(pm_integer_t *numerator, pm_integer_t *denominator) {
+ // If either the numerator or denominator do not fit into a 32-bit integer,
+ // then this function is a no-op. In the future, we may consider reducing
+ // even the larger numbers, but for now we're going to keep it simple.
+ if (
+ // If the numerator doesn't fit into a 32-bit integer, return early.
+ numerator->length != 0 ||
+ // If the denominator doesn't fit into a 32-bit integer, return early.
+ denominator->length != 0 ||
+ // If the numerator is 0, then return early.
+ numerator->value == 0 ||
+ // If the denominator is 1, then return early.
+ denominator->value == 1
+ ) return;
+
+ // Find the greatest common divisor of the numerator and denominator.
+ uint32_t divisor = numerator->value;
+ uint32_t remainder = denominator->value;
+
+ while (remainder != 0) {
+ uint32_t temporary = remainder;
+ remainder = divisor % remainder;
+ divisor = temporary;
+ }
+
+ // Divide the numerator and denominator by the greatest common divisor.
+ numerator->value /= divisor;
+ denominator->value /= divisor;
}
/**
* Convert an integer to a decimal string.
*/