Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
human_readable.hpp
Go to the documentation of this file.
1// -------------------------------------------------------//
2//
3// SHAMROCK code for hydrodynamics
4// Copyright (c) 2021-2026 Timothée David--Cléris <tim.shamrock@proton.me>
5// SPDX-License-Identifier: CeCILL Free Software License Agreement v2.1
6// Shamrock is licensed under the CeCILL 2.1 License, see LICENSE for more information
7//
8// -------------------------------------------------------//
9
10#pragma once
11
17
18#include <array>
19#include <cmath>
20#include <utility>
21
22namespace sham {
23
24 namespace details {
25
33 template<bool allow_below_1>
34 consteval auto make_si_pairs() {
35 if constexpr (allow_below_1) {
36 return std::array<std::pair<const char *, double>, 12>{
37 {{"n", 1e-9},
38 {"u", 1e-6},
39 {"m", 1e-3},
40 {"", 1.0},
41 {"k", 1e3},
42 {"M", 1e6},
43 {"G", 1e9},
44 {"T", 1e12},
45 {"P", 1e15},
46 {"E", 1e18},
47 {"Z", 1e21},
48 {"Y", 1e24}}};
49 } else {
50 return std::array<std::pair<const char *, double>, 9>{
51 {{"", 1.0},
52 {"k", 1e3},
53 {"M", 1e6},
54 {"G", 1e9},
55 {"T", 1e12},
56 {"P", 1e15},
57 {"E", 1e18},
58 {"Z", 1e21},
59 {"Y", 1e24}}};
60 }
61 }
62
63 } // namespace details
64
73 double value;
74 const char *prefix;
75 double ratio;
76 };
77
91 template<bool allow_below_1 = true>
92 inline human_readable_t to_human_readable(double value) {
93 static constexpr auto si = details::make_si_pairs<allow_below_1>();
94
95 double ax = std::fabs(value);
96
97 // zero: no prefix
98 if (ax == 0.0) {
99 return {.value = 0.0, .prefix = "", .ratio = 1.0};
100 }
101
102 // too large, clamp to largest unit
103 const auto &largest = si.back();
104 if (ax >= largest.second) {
105 return {
106 .value = value / largest.second, .prefix = largest.first, .ratio = largest.second};
107 }
108
109 for (int i = static_cast<int>(si.size()) - 2; i >= 0; --i) {
110 if (ax >= si[i].second) {
111 return {
112 .value = value / si[i].second, .prefix = si[i].first, .ratio = si[i].second};
113 }
114 }
115
116 // too small, clamp to smallest unit
117 const auto &smallest = si.front();
118 return {
119 .value = value / smallest.second, .prefix = smallest.first, .ratio = smallest.second};
120 }
121
122} // namespace sham
consteval auto make_si_pairs()
Generate a compile-time table of SI prefixes and their magnitudes.
namespace for backends this one is named only sham since shambackends is too long to write
human_readable_t to_human_readable(double value)
Convert a raw value to a human-readable scaled form with an SI prefix.
Struct holding a scaled value with its SI prefix.