Skip to content

Commit

Permalink
WIP: Clang ARM appears to alias long double to double
Browse files Browse the repository at this point in the history
  • Loading branch information
Ravenwater committed Oct 8, 2024
1 parent 4cdf801 commit 32539ad
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 8 deletions.
8 changes: 7 additions & 1 deletion elastic/decimal/api/example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,13 @@ try {
std::cout << "max unsigned long long f : " << f << '\n';
std::cout << " d : " << d << std::endl;

return EXIT_SUCCESS;
long double ld{std::pow(2.0l, 2000.0l)};
auto tpl = ieee_components(ld);
std::cout << "sign : " << (get<0>(tpl) ? "1" : "0") << '\n';
std::cout << "exponent : " << get<1>(tpl) << '\n';
std::cout << "fraction : " << to_binary(get<2>(tpl)) << '\n';

return EXIT_SUCCESS;

}
catch (const char* msg) {
Expand Down
16 changes: 9 additions & 7 deletions include/universal/native/nonconstexpr/clang_long_double.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ namespace sw { namespace universal {
/// not POWER, and not X86
/// could be ARM or RISC-V

// TODO: we need to determine what "long double" format this environment supports

// generate a hex string for a native long double precision IEEE floating point
inline std::string to_hex(long double number, bool nibbleMarker = false, bool hexPrefix = true) {
Expand Down Expand Up @@ -336,17 +337,18 @@ namespace sw { namespace universal {
}

// ieee_components returns a tuple of sign, exponent, and fraction
inline std::tuple<bool, int, std::uint64_t> ieee_components(long double fp) {
static_assert(std::numeric_limits<double>::is_iec559,
inline std::tuple<bool, int, std::uint64_t> ieee_components(long double number) {
static_assert(std::numeric_limits<long double>::is_iec559,
"This function only works when double complies with IEC 559 (IEEE 754)");
static_assert(sizeof(double) == 8, "This function only works when double is 64 bit.");
static_assert(sizeof(long double) == 8, "This function only works when long double is cast to a 64 bit double");

double_decoder dd{ fp }; // initializes the first member of the union
double_decoder decoder;
decoder.d = number; // implicit cast to double
// Reading inactive union parts is forbidden in constexpr :-(
return std::make_tuple<bool, int, std::uint64_t>(
static_cast<bool>(dd.parts.sign),
static_cast<int>(dd.parts.exponent),
static_cast<std::uint64_t>(dd.parts.fraction)
static_cast<bool>(decoder.parts.sign),
static_cast<int>(decoder.parts.exponent),
static_cast<std::uint64_t>(decoder.parts.fraction)
);
}

Expand Down

0 comments on commit 32539ad

Please sign in to comment.