Add files via upload
This commit is contained in:
137
types.c
Normal file
137
types.c
Normal file
@@ -0,0 +1,137 @@
|
||||
#include "types.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
// ----------------- INT -----------------
|
||||
static void int_copy(void *dest, const void *src) {
|
||||
*(int *) dest = *(const int *) src;
|
||||
}
|
||||
|
||||
static int int_compare(const void *a, const void *b) {
|
||||
const int va = *(const int *) a;
|
||||
const int vb = *(const int *) b;
|
||||
|
||||
return (va > vb) - (va < vb);
|
||||
}
|
||||
|
||||
static void int_print(const void *elem) {
|
||||
printf("%d", *(const int *) elem);
|
||||
}
|
||||
|
||||
static bool int_parse(void *dest, const char *str) {
|
||||
char *end;
|
||||
const long val = strtol(str, &end, 10);
|
||||
if (end == str || *end != '\0') return false;
|
||||
|
||||
*(int *) dest = (int) val;
|
||||
return true;
|
||||
}
|
||||
|
||||
static TypeInfo INT_TYPE_INFO = {
|
||||
.element_size = sizeof(int),
|
||||
.copy = int_copy,
|
||||
.destroy = NULL,
|
||||
.compare = int_compare,
|
||||
.print = int_print,
|
||||
.parse = int_parse,
|
||||
.type_name = "int"
|
||||
};
|
||||
|
||||
const TypeInfo *get_int_type(void) {
|
||||
return &INT_TYPE_INFO;
|
||||
}
|
||||
|
||||
// ----------------- DOUBLE -----------------
|
||||
static void double_copy(void *dest, const void *src) {
|
||||
*(double *) dest = *(const double *) src;
|
||||
}
|
||||
|
||||
static int double_compare(const void *a, const void *b) {
|
||||
const double va = *(const double *) a;
|
||||
const double vb = *(const double *) b;
|
||||
const double error = 1e-12;
|
||||
|
||||
if (fabs(va - vb) < error) return 0;
|
||||
return (va > vb) ? 1 : -1;
|
||||
}
|
||||
|
||||
static void double_print(const void *elem) {
|
||||
printf("%.4f", *(const double *) elem);
|
||||
}
|
||||
|
||||
static bool double_parse(void *dest, const char *str) {
|
||||
char *end;
|
||||
const double val = strtod(str, &end);
|
||||
if (end == str || *end != '\0') return false;
|
||||
|
||||
*(double *) dest = val;
|
||||
return true;
|
||||
}
|
||||
|
||||
static TypeInfo DOUBLE_TYPE_INFO = {
|
||||
.element_size = sizeof(double),
|
||||
.copy = double_copy,
|
||||
.destroy = NULL,
|
||||
.compare = double_compare,
|
||||
.print = double_print,
|
||||
.parse = double_parse,
|
||||
.type_name = "double"
|
||||
};
|
||||
|
||||
const TypeInfo *get_double_type(void) {
|
||||
return &DOUBLE_TYPE_INFO;
|
||||
}
|
||||
|
||||
// ----------------- COMPLEX -----------------
|
||||
static void complex_copy(void *dest, const void *src) {
|
||||
*(Complex *) dest = *(const Complex *) src;
|
||||
}
|
||||
|
||||
static int complex_compare(const void *a, const void *b) {
|
||||
const Complex *ca = (const Complex *) a;
|
||||
const Complex *cb = (const Complex *) b;
|
||||
const double error = 1e-12;
|
||||
|
||||
const double ma = ca->re * ca->re + ca->im * ca->im;
|
||||
const double mb = cb->re * cb->re + cb->im * cb->im;
|
||||
|
||||
if (fabs(ma - mb) < error) return 0;
|
||||
return (ma > mb) ? 1 : -1;
|
||||
}
|
||||
|
||||
static void complex_print(const void *elem) {
|
||||
const Complex *c = (Complex*)elem;
|
||||
if (c->im > 0)
|
||||
printf("%.4f+%.4fi", c->re, c->im);
|
||||
else if (c->im == 0)
|
||||
printf("%.4f", c->re);
|
||||
else
|
||||
printf("%.4f%.4fi", c->re, c->im);
|
||||
}
|
||||
|
||||
static bool complex_parse(void *dest, const char *str) {
|
||||
Complex *c = (Complex *)dest;
|
||||
// Формат: "re im"
|
||||
if (sscanf(str, "%lf %lf", &c->re, &c->im) == 2)
|
||||
return true;
|
||||
// Попробуем только re
|
||||
c->im = 0;
|
||||
if (sscanf(str, "%lf", &c->re) == 1)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static TypeInfo COMPLEX_TYPE_INFO = {
|
||||
.element_size = sizeof(Complex),
|
||||
.copy = complex_copy,
|
||||
.destroy = NULL,
|
||||
.compare = complex_compare,
|
||||
.print = complex_print,
|
||||
.parse = complex_parse,
|
||||
.type_name = "complex"
|
||||
};
|
||||
|
||||
const TypeInfo *get_complex_type(void) {
|
||||
return &COMPLEX_TYPE_INFO;
|
||||
}
|
||||
Reference in New Issue
Block a user