| 905 | { |
| 906 | |
| 907 | std::optional<rational> parseRational(std::string const& _value) |
| 908 | { |
| 909 | rational value; |
| 910 | try |
| 911 | { |
| 912 | auto radixPoint = find(_value.begin(), _value.end(), '.'); |
| 913 | |
| 914 | if (radixPoint != _value.end()) |
| 915 | { |
| 916 | if ( |
| 917 | !all_of(radixPoint + 1, _value.end(), util::isDigit) || |
| 918 | !all_of(_value.begin(), radixPoint, util::isDigit) |
| 919 | ) |
| 920 | return std::nullopt; |
| 921 | |
| 922 | // Only decimal notation allowed here, leading zeros would switch to octal. |
| 923 | auto fractionalBegin = find_if_not( |
| 924 | radixPoint + 1, |
| 925 | _value.end(), |
| 926 | [](char const& a) { return a == '0'; } |
| 927 | ); |
| 928 | |
| 929 | rational numerator; |
| 930 | rational denominator(1); |
| 931 | |
| 932 | denominator = bigint(std::string(fractionalBegin, _value.end())); |
| 933 | denominator /= boost::multiprecision::pow( |
| 934 | bigint(10), |
| 935 | static_cast<unsigned>(distance(radixPoint + 1, _value.end())) |
| 936 | ); |
| 937 | numerator = bigint(std::string(_value.begin(), radixPoint)); |
| 938 | value = numerator + denominator; |
| 939 | } |
| 940 | else |
| 941 | value = bigint(_value); |
| 942 | return value; |
| 943 | } |
| 944 | catch (...) |
| 945 | { |
| 946 | return std::nullopt; |
| 947 | } |
| 948 | } |
| 949 | |
| 950 | /// Checks whether _mantissa * (10 ** _expBase10) fits into 4096 bits. |
| 951 | bool fitsPrecisionBase10(bigint const& _mantissa, uint32_t _expBase10) |
no test coverage detected