LMCAS
Lamina Computer Algebra System
Toggle main menu visibility
载入中...
搜索中...
未找到
numeric_literal.hpp
浏览该文件的文档.
1
#pragma once
2
3
#include "
result.hpp
"
4
#include <cmath>
5
#include <string_view>
6
#ifdef __APPLE__
7
#include <cstdlib>
8
#include <locale.h>
9
#include <string>
10
#else
11
#include <charconv>
12
#include <system_error>
13
#endif
14
15
namespace
LMCAS::detail
{
16
17
inline
bool
consume_decimal_digits
(std::string_view token, std::size_t& pos)
noexcept
{
18
const
auto
start = pos;
19
while
(pos < token.size() && token[pos] >=
'0'
&& token[pos] <=
'9'
) {
20
++pos;
21
}
22
return
pos != start;
23
}
24
25
inline
bool
consume_decimal_mantissa
(std::string_view token, std::size_t& pos)
noexcept
{
26
bool
has_digits =
consume_decimal_digits
(token, pos);
27
if
(pos < token.size() && token[pos] ==
'.'
) {
28
++pos;
29
has_digits =
consume_decimal_digits
(token, pos) || has_digits;
30
}
31
return
has_digits;
32
}
33
34
inline
void
consume_decimal_sign
(std::string_view token, std::size_t& pos)
noexcept
{
35
if
(pos < token.size() && (token[pos] ==
'+'
|| token[pos] ==
'-'
)) {
36
++pos;
37
}
38
}
39
40
inline
bool
consume_decimal_exponent
(std::string_view token, std::size_t& pos)
noexcept
{
41
if
(pos < token.size() && (token[pos] ==
'e'
|| token[pos] ==
'E'
)) {
42
++pos;
43
consume_decimal_sign
(token, pos);
44
return
consume_decimal_digits
(token, pos);
45
}
46
return
true
;
47
}
48
49
inline
bool
is_signed_decimal_token
(std::string_view token)
noexcept
{
50
std::size_t pos = 0;
51
consume_decimal_sign
(token, pos);
52
if
(!
consume_decimal_mantissa
(token, pos)) {
return
false
; }
53
if
(!
consume_decimal_exponent
(token, pos)) {
return
false
; }
54
return
pos == token.size();
55
}
56
57
inline
Result<double>
parse_finite_decimal
(std::string_view token) {
58
const
auto
invalid = [] {
59
return
Result<double>::failure
(
CasErrc::ParseError
,
60
"expected a representable finite decimal"
,
"LMCAS.numeric_literal"
);
61
};
62
if
(!
is_signed_decimal_token
(token)) {
return
invalid(); }
63
if
(token.front() ==
'+'
) { token.remove_prefix(1); }
64
double
value
= 0;
65
#ifdef __APPLE__
66
// Xcode 16 uses strtod_l with a fixed C locale for decimal conversion.
67
static
const
locale_t c_locale = newlocale(LC_NUMERIC_MASK,
"C"
,
nullptr
);
68
if
(!c_locale) {
return
invalid(); }
69
std::string text(token);
70
char
* end =
nullptr
;
71
value
= strtod_l(text.c_str(), &end, c_locale);
72
const
bool
converted = end == text.c_str() + text.size();
73
#else
74
const
auto
parsed = std::from_chars(token.data(), token.data() + token.size(),
75
value
, std::chars_format::general);
76
const
bool
converted = parsed.ec == std::errc{} &&
77
parsed.ptr == token.data() + token.size();
78
#endif
79
if
(!converted || !std::isfinite(
value
)) {
return
invalid(); }
80
if
(
value
== 0) {
81
for
(
char
c
: token) {
82
if
(
c
==
'e'
||
c
==
'E'
) {
break
; }
83
if
(
c
>=
'1'
&&
c
<=
'9'
) {
return
invalid(); }
84
}
85
if
(token.front() ==
'-'
) {
value
= -0.0; }
86
}
87
return
value
;
88
}
89
90
}
LMCAS::Result
定义
result.hpp:39
LMCAS::Result::failure
static Result failure(CasErrc code, std::string message, std::string operation={})
定义
result.hpp:52
LMCAS::detail
多元 Hensel 提升(单变量步)
定义
assumption_context.hpp:31
LMCAS::detail::parse_finite_decimal
Result< double > parse_finite_decimal(std::string_view token)
定义
numeric_literal.hpp:57
LMCAS::detail::consume_decimal_mantissa
bool consume_decimal_mantissa(std::string_view token, std::size_t &pos) noexcept
定义
numeric_literal.hpp:25
LMCAS::detail::consume_decimal_exponent
bool consume_decimal_exponent(std::string_view token, std::size_t &pos) noexcept
定义
numeric_literal.hpp:40
LMCAS::detail::consume_decimal_digits
bool consume_decimal_digits(std::string_view token, std::size_t &pos) noexcept
定义
numeric_literal.hpp:17
LMCAS::detail::is_signed_decimal_token
bool is_signed_decimal_token(std::string_view token) noexcept
定义
numeric_literal.hpp:49
LMCAS::detail::consume_decimal_sign
void consume_decimal_sign(std::string_view token, std::size_t &pos) noexcept
定义
numeric_literal.hpp:34
LMCAS::c
const VectorField const VectorField & c
定义
vector_calculus_vectors.hpp:60
LMCAS::CasErrc::ParseError
@ ParseError
定义
result.hpp:14
LMCAS::value
const std::string const ExprPtr & value
定义
expr.hpp:293
result.hpp
src
internal
numeric_literal.hpp
生成于
, 为 LMCAS使用
1.18.0