61 lines
2.0 KiB
C
61 lines
2.0 KiB
C
#ifndef TUMBLER_H
|
|
#define TUMBLER_H
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
typedef struct {
|
|
uint64_t *digits;
|
|
size_t count;
|
|
} tumbler_t;
|
|
|
|
typedef enum {
|
|
TUMBLER_OK = 0,
|
|
TUMBLER_ERR_NULL,
|
|
TUMBLER_ERR_INVALID,
|
|
TUMBLER_ERR_NOMEM,
|
|
TUMBLER_ERR_OVERFLOW,
|
|
TUMBLER_ERR_UNDERFLOW
|
|
} tumbler_error_t;
|
|
|
|
typedef struct {
|
|
tumbler_error_t code;
|
|
const char *msg;
|
|
} tumbler_result_t;
|
|
|
|
/* Parse the dotted decimal representation into a heap-owned tumbler.
|
|
* On success, caller owns out->digits and must call tumbler_free(). */
|
|
tumbler_result_t tumbler_parse(const char *text, tumbler_t *out);
|
|
void tumbler_free(tumbler_t *t);
|
|
|
|
/* Format a tumbler as a newly allocated dotted decimal string.
|
|
* Caller frees the returned string. */
|
|
tumbler_result_t tumbler_to_string(const tumbler_t *t, char **out);
|
|
|
|
/* Whole-tumbler numeric ordering. Missing fields compare as zero, so
|
|
* 1 < 1.1 < 1.1.1 and trailing zero fields do not affect ordering. */
|
|
int tumbler_compare(const tumbler_t *a, const tumbler_t *b);
|
|
|
|
/* Xanadu tumbler addition: position + offset. */
|
|
tumbler_result_t tumbler_add(const tumbler_t *position,
|
|
const tumbler_t *offset,
|
|
tumbler_t *out);
|
|
|
|
/* Strong and weak tumbler subtraction, as described in the historical
|
|
* Xanadu material. Both require non-negative results at their first
|
|
* differing field. */
|
|
tumbler_result_t tumbler_subtract_strong(const tumbler_t *position,
|
|
const tumbler_t *offset,
|
|
tumbler_t *out);
|
|
tumbler_result_t tumbler_subtract_weak(const tumbler_t *position,
|
|
const tumbler_t *offset,
|
|
tumbler_t *out);
|
|
|
|
/* Generalized tumbler difference used by the Xanadu system:
|
|
* if a > b, strong-subtract b from a; otherwise weak-subtract a from b. */
|
|
tumbler_result_t tumbler_subtract(const tumbler_t *a,
|
|
const tumbler_t *b,
|
|
tumbler_t *out);
|
|
|
|
#endif /* TUMBLER_H */
|