27 {
"EPSILON_0", (
lmmc_real_t)8.8541878128e-12,
"F*m^-1"},
31 {
"FARADAY", (
lmmc_real_t)9.648533212e4,
"C*mol^-1"},
33 {
"MOLAR_VOLUME_IDEAL", (
lmmc_real_t)0.024465,
"m^3*mol^-1"},
38static size_t lmmc_std_constants_length(
void)
40 return sizeof(lmmc_std_constants) /
sizeof(lmmc_std_constants[0]);
44lmmc_std_find_constant(
const char* name)
46 if (!name) {
return NULL; }
47 for (
size_t i = 0; i < lmmc_std_constants_length(); ++i) {
48 if (strcmp(lmmc_std_constants[i].name, name) == 0) {
49 return &lmmc_std_constants[i];
72 {
"1", 1.0, {0, 0, 0, 0, 0, 0, 0}},
73 {
"m", 1.0, {1, 0, 0, 0, 0, 0, 0}},
74 {
"km", 1000.0, {1, 0, 0, 0, 0, 0, 0}},
75 {
"s", 1.0, {0, 0, 1, 0, 0, 0, 0}},
76 {
"h", 3600.0, {0, 0, 1, 0, 0, 0, 0}},
77 {
"kg", 1.0, {0, 1, 0, 0, 0, 0, 0}},
78 {
"g", 0.001, {0, 1, 0, 0, 0, 0, 0}},
79 {
"A", 1.0, {0, 0, 0, 1, 0, 0, 0}},
80 {
"K", 1.0, {0, 0, 0, 0, 1, 0, 0}},
81 {
"mol", 1.0, {0, 0, 0, 0, 0, 1, 0}},
82 {
"cd", 1.0, {0, 0, 0, 0, 0, 0, 1}},
83 {
"N", 1.0, {1, 1, -2, 0, 0, 0, 0}},
84 {
"Pa", 1.0, {-1, 1, -2, 0, 0, 0, 0}},
85 {
"J", 1.0, {2, 1, -2, 0, 0, 0, 0}},
86 {
"C", 1.0, {0, 0, 1, 1, 0, 0, 0}},
87 {
"F", 1.0, {-2, -1, 4, 2, 0, 0, 0}},
88 {
"H", 1.0, {2, 1, -2, -2, 0, 0, 0}},
89 {
"score", 1.0, {0, 0, 0, 0, 0, 0, 0, 1, 0}},
90 {
"token", 1.0, {0, 0, 0, 0, 0, 0, 0, 0, 1}},
96 for (
size_t i = 0; i <
sizeof(lmmc_std_units) /
sizeof(lmmc_std_units[0]);
98 if (strlen(lmmc_std_units[i].name) == length &&
99 strncmp(lmmc_std_units[i].name, name, length) == 0) {
100 return &lmmc_std_units[i];
112static int lmmc_std_parse_int(
const char** cursor,
int* out)
117 if (**cursor ==
'+') {
119 }
else if (**cursor ==
'-') {
123 while (isdigit((
unsigned char)**cursor)) {
124 int digit = **cursor -
'0';
129 value = value * 10 + digit;
132 if (!have_digit) {
return 0; }
141static int lmmc_std_accumulate_unit(
144 out->
scale *= pow(unit->
scale, (
double)exponent);
145 if (!isfinite(out->
scale)) {
return 0; }
147 out->
dims[i] += unit->
dims[i] * exponent;
156static int lmmc_std_parse_unit_factor(
159 const char* cursor = *position;
160 const char* name_begin = cursor;
162 while (isalpha((
unsigned char)*cursor) || *cursor ==
'_') ++cursor;
163 if (cursor == name_begin) {
return 0; }
165 lmmc_std_find_unit(name_begin, (
size_t)(cursor - name_begin));
166 if (!unit) {
return 0; }
167 if (*cursor ==
'^') {
169 if (!lmmc_std_parse_int(&cursor, &exponent)) {
return 0; }
172 if (!lmmc_std_accumulate_unit(unit, exponent, out)) {
179static int lmmc_std_parse_unit_expr(
const char* text,
182 const char* cursor = text;
184 lmmc_std_unit_identity(out);
185 if (!text || !*text) {
return 0; }
186 if (strcmp(text,
"1") == 0) {
return 1; }
188 if (!lmmc_std_parse_unit_factor(&cursor, op_sign, out)) {
191 if (*cursor ==
'\0') {
break; }
192 if (*cursor ==
'*') {
194 }
else if (*cursor ==
'/') {
200 if (*cursor ==
'\0') {
return 0; }
209 if (lhs->
dims[i] != rhs->
dims[i]) {
return 0; }
217 if (sig->
dims[i] != 0) {
return 0; }
228 return lmmc_std_store_real((
lmmc_real_t)2.71828182845904523536, out);
233 return lmmc_std_store_real((
lmmc_real_t)1.61803398874989484820, out);
238 return lmmc_std_constants_length();
243 if (index >= lmmc_std_constants_length()) {
return NULL; }
244 return lmmc_std_constants[index].name;
258 return entry ? entry->
unit : NULL;
262 const char** out_name,
264 const char** out_unit)
266 if (!out_name || !out_value || !out_unit) {
269 if (index >= lmmc_std_constants_length()) {
272 *out_name = lmmc_std_constants[index].name;
273 *out_value = lmmc_std_constants[index].value;
274 *out_unit = lmmc_std_constants[index].unit;
283 const char* from_unit,
292 if (!lmmc_std_parse_unit_expr(from_unit, &from_sig) ||
293 !lmmc_std_parse_unit_expr(to_unit, &to_sig)) {
296 if (!lmmc_std_same_dimension(&from_sig, &to_sig)) {
299 converted = (double)x * from_sig.
scale / to_sig.
scale;
300 return lmmc_std_store_finite_real((
lmmc_real_t)converted, out);
311 if (!lmmc_std_parse_unit_expr(to_unit, &to_sig)) {
314 converted = (double)x / to_sig.
scale;
315 return lmmc_std_store_finite_real((
lmmc_real_t)converted, out);
340 if (strstr(unit,
"num<") != NULL || strstr(unit,
"scalar<") != NULL) {
344 if (!lmmc_std_parse_unit_expr(unit, &sig)) {
347 value = (double)x * sig.
scale;
350 lmmc_std_store_finite_real((
lmmc_real_t)value, out);
377 if (!lmmc_std_parse_unit_expr(unit, &sig)) {
380 *out = lmmc_std_dimensionless_sig(&sig);
lmmc_status_t lmmc_complex_create(lmmc_real_t real, lmmc_real_t imag, lmmc_complex_t *out)
从笛卡尔坐标构造复数.
double lmmc_real_t
Public and internal LMMC real type.
#define LMMC_CONST_PI
圆周率常数 。
lmmc_status_t
LMMC 库统一返回的状态码.
@ LMMC_STATUS_UNIT_STRIP_LEGACY_SYNTAX
@ LMMC_STATUS_NUMERICAL_FAILURE
@ LMMC_STATUS_DIMENSION_MISMATCH
@ LMMC_STATUS_UNIT_STRIP_INVALID
@ LMMC_STATUS_INVALID_ARGUMENT
@ LMMC_STATUS_UNIT_STRIP_OVERFLOW
const char * lmmc_std_constants_name(size_t index)
按索引返回 LSR 规范的 std.constants 条目名;索引越界时返回 NULL。
lmmc_status_t lmmc_std_constants_get(const char *name, lmmc_real_t *out)
按名称返回 LSR 规范的 std.constants 数值。
lmmc_status_t lmmc_std_math_e(lmmc_real_t *out)
返回 LSR 规范的 std.math 常量 e。
lmmc_status_t lmmc_std_constants_entry(size_t index, const char **out_name, lmmc_real_t *out_value, const char **out_unit)
按索引返回完整的 LSR 规范 std.constants 条目。
lmmc_status_t lmmc_std_units_strip(lmmc_real_t x, lmmc_real_t *out)
lmmc_status_t lmmc_std_units_convert(lmmc_real_t x, const char *from_unit, const char *to_unit, lmmc_real_t *out)
lmmc_status_t lmmc_std_units_strip_scalar(lmmc_real_t x, lmmc_real_t *out)
lmmc_status_t lmmc_std_math_i(lmmc_complex_t *out)
返回虚数单位 std.math.I。
lmmc_status_t lmmc_std_math_phi(lmmc_real_t *out)
返回 LSR 规范的 std.math 常量 phi。
lmmc_status_t lmmc_std_units_convert_num(lmmc_real_t x, const char *to_unit, lmmc_real_t *out)
lmmc_status_t lmmc_std_units_is_dimensionless(const char *unit, int *out)
lmmc_status_t lmmc_std_units_is_dimensionless_num(lmmc_real_t x, int *out)
lmmc_status_t lmmc_std_units_strip_num(lmmc_real_t x, const char *unit, lmmc_real_t *out)
lmmc_status_t lmmc_std_units_convert_from_si(lmmc_real_t x, const char *to_unit, lmmc_real_t *out)
lmmc_status_t lmmc_std_math_pi(lmmc_real_t *out)
返回 LSR 规范的 std.math 常量 pi。
size_t lmmc_std_constants_count(void)
返回 LSR 规范的 std.constants 条目数。
const char * lmmc_std_constants_unit(const char *name)
按名称返回 LSR 规范的 std.constants 单位字符串;条目无单位时返回 NULL。
@ LMMC_STD_MAX_UNIT_EXPONENT
@ LMMC_STD_UNIT_DIM_COUNT