| 1362 | |
| 1363 | template <typename Real> |
| 1364 | static Result<Decimal256> FromPositiveRealApprox(Real real, int32_t precision, |
| 1365 | int32_t scale) { |
| 1366 | auto x = std::nearbyint(real * PowerOfTen<double>(scale)); |
| 1367 | const auto max_abs = PowerOfTen<double>(precision); |
| 1368 | if (x >= max_abs) { |
| 1369 | return OverflowError(real, precision, scale); |
| 1370 | } |
| 1371 | // Extract parts |
| 1372 | const auto part3 = std::floor(std::ldexp(x, -192)); |
| 1373 | x -= std::ldexp(part3, 192); |
| 1374 | const auto part2 = std::floor(std::ldexp(x, -128)); |
| 1375 | x -= std::ldexp(part2, 128); |
| 1376 | const auto part1 = std::floor(std::ldexp(x, -64)); |
| 1377 | x -= std::ldexp(part1, 64); |
| 1378 | const auto part0 = x; |
| 1379 | |
| 1380 | DCHECK_GE(part3, 0); |
| 1381 | DCHECK_LT(part3, 9.223372036854776e+18); // 2**63 |
| 1382 | DCHECK_GE(part2, 0); |
| 1383 | DCHECK_LT(part2, 1.8446744073709552e+19); // 2**64 |
| 1384 | DCHECK_GE(part1, 0); |
| 1385 | DCHECK_LT(part1, 1.8446744073709552e+19); // 2**64 |
| 1386 | DCHECK_GE(part0, 0); |
| 1387 | DCHECK_LT(part0, 1.8446744073709552e+19); // 2**64 |
| 1388 | return Decimal256(Decimal256::LittleEndianArray, |
| 1389 | {static_cast<uint64_t>(part0), static_cast<uint64_t>(part1), |
| 1390 | static_cast<uint64_t>(part2), static_cast<uint64_t>(part3)}); |
| 1391 | } |
| 1392 | |
| 1393 | template <typename Real> |
| 1394 | static Real ToRealPositiveNoSplit(const Decimal256& decimal, int32_t scale) { |
nothing calls this directly
no test coverage detected