| 145 | } |
| 146 | |
| 147 | inline std::string FormatFloat(float value) |
| 148 | { |
| 149 | if (value == 0.0f) |
| 150 | return std::signbit(value) ? "-0.0" : "0.0"; |
| 151 | |
| 152 | char full[64]; |
| 153 | snprintf(full, sizeof(full), "%.15f", (double)value); |
| 154 | |
| 155 | const char* dot = strchr(full, '.'); |
| 156 | if (!dot) |
| 157 | return std::string(full) + ".0"; |
| 158 | |
| 159 | int dotIdx = (int)(dot - full); |
| 160 | int fullLen = (int)strlen(full); |
| 161 | char candidate[64]; |
| 162 | |
| 163 | for (int decimals = 1; decimals <= 6; decimals++) |
| 164 | { |
| 165 | int truncLen = dotIdx + 1 + decimals; |
| 166 | if (truncLen <= fullLen) |
| 167 | { |
| 168 | memcpy(candidate, full, truncLen); |
| 169 | candidate[truncLen] = '\0'; |
| 170 | if (strtof(candidate, nullptr) == value) |
| 171 | return candidate; |
| 172 | } |
| 173 | |
| 174 | snprintf(candidate, sizeof(candidate), "%.*f", decimals, (double)value); |
| 175 | if (strtof(candidate, nullptr) == value) |
| 176 | return candidate; |
| 177 | } |
| 178 | |
| 179 | snprintf(candidate, sizeof(candidate), "%.6f", (double)value); |
| 180 | std::string str(candidate); |
| 181 | size_t dotPos = str.find('.'); |
| 182 | if (dotPos != std::string::npos) |
| 183 | { |
| 184 | size_t lastNonZero = str.find_last_not_of('0'); |
| 185 | if (lastNonZero != std::string::npos && lastNonZero > dotPos) |
| 186 | { |
| 187 | str.erase(lastNonZero + 1); |
| 188 | } |
| 189 | else |
| 190 | { |
| 191 | str.erase(dotPos + 2); |
| 192 | } |
| 193 | } |
| 194 | return str; |
| 195 | } |
| 196 | |
| 197 | inline bool IsNumericFloat(const char* str, float* outValue = nullptr) |
| 198 | { |
no outgoing calls
no test coverage detected