Giter VIP home page Giter VIP logo

grisu-exact's People

Contributors

jk-jeon avatar yumeyao avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

grisu-exact's Issues

Crash with MSVC caused by adcx (Intel ADX)

I've made some tests with MSVC and got a crash on ADCX instruction. My CPU predates Intel ADX (introduced in Broadwell). But it seems like ADC can be used instead.

diff --git a/grisu_exact.h b/grisu_exact.h
index 4d99f8a89..d8b69fcea 100644
--- a/grisu_exact.h
+++ b/grisu_exact.h
@@ -145,8 +145,8 @@ namespace jkj {
 
 #if defined(_MSC_VER) && defined(_M_X64)
 			std::uint64_t high, low;
-			auto carry = _addcarryx_u64(0, g0.low(), g10, &low);
-			_addcarryx_u64(carry, g0.high(), 0, &high);
+			auto carry = _addcarry_u64(0, g0.low(), g10, &low);
+			_addcarry_u64(carry, g0.high(), 0, &high);
 			return high;
 #elif (defined(__GNUC__) || defined(__clang__)) && defined(__SIZEOF_INT128__) && defined(__x86_64__)
 			return uint128{ g0.internal_ + g10 }.high();

Build error with GCC -m32

There are two small problems when trying to build with gcc -m32. The diff below fixes both.

diff --git a/grisu_exact.h b/grisu_exact.h
index eb7801e7e..4d99f8a89 100644
--- a/grisu_exact.h
+++ b/grisu_exact.h
@@ -53,7 +53,7 @@ namespace jkj {
 		struct uint128 {
 			uint128() = default;
 
-#if defined(__GNUC__) || defined(__clang__) && defined(__SIZEOF_INT128__) && defined(__x86_64__)
+#if (defined(__GNUC__) || defined(__clang__)) && defined(__SIZEOF_INT128__) && defined(__x86_64__)
 			unsigned __int128	internal_;
 
 			constexpr uint128(std::uint64_t high, std::uint64_t low) noexcept :
@@ -204,7 +204,7 @@ namespace jkj {
 			if (exp >= int(sizeof(UInt) * 8)) {
 				return false;
 			}
-			return f == ((f >> exp) << exp); 
+			return x == ((x >> exp) << exp);
 #endif
 		}

Otherwise, this is great work, it's very easy to use and it works very well, thank you :)

Build problems with clang/MSVC (clang-cl) on Windows

Sorry for the spam, I think it'll be all after this one...

There are two sorts of problems when trying to build with Clang/MSVC (clang-cl) on Windows.

First, in some cases, you test for _MSC_VER (and _M_X64) first, and sometimes for Clang/GCC (and 64-bit) first. Problem is, with Clang/MSVC, both code paths match because it defines __clang__, _MSC_VER and _M_X64. To make sure Clang uses the GCC/Clang code paths, they should come first. I've done that in the patch below.

More importantly, for some reason, Clang/MSVC has problems on line 1743 with the definition of power_of_10. It does not like the auto return type there. Replacing auto with extended_significand_type fixes the problem. This change is in the patch below, at the end. I don't know why that is, and I use a very C-with-classes kind of C++ in my own code so I won't try to speculate on this kind of modern C++ thing.

This patch comes after the one I posted in #10.

diff --git a/grisu_exact.h b/grisu_exact.h
index d8b69fcea..08737036f 100644
--- a/grisu_exact.h
+++ b/grisu_exact.h
@@ -85,12 +85,12 @@ namespace jkj {

        JKJ_GRISU_EXACT_SAFEBUFFERS
        inline uint128 umul128(std::uint64_t x, std::uint64_t y) noexcept {
-#if defined(_MSC_VER) && defined(_M_X64)
+#if (defined(__GNUC__) || defined(__clang__)) && defined(__SIZEOF_INT128__) && defined(__x86_64__)
+           return (unsigned __int128)(x) * (unsigned __int128)(y);
+#elif defined(_MSC_VER) && defined(_M_X64)
            uint128 result;
            result.low_ = _umul128(x, y, &result.high_);
            return result;
-#elif (defined(__GNUC__) || defined(__clang__)) && defined(__SIZEOF_INT128__) && defined(__x86_64__)
-           return (unsigned __int128)(x) * (unsigned __int128)(y);
 #else
            constexpr auto mask = (std::uint64_t(1) << 32) - std::uint64_t(1);

@@ -113,11 +113,11 @@ namespace jkj {

        JKJ_GRISU_EXACT_SAFEBUFFERS
        inline std::uint64_t umul128_upper64(std::uint64_t x, std::uint64_t y) noexcept {
-#if defined(_MSC_VER) && defined(_M_X64)
-           return __umulh(x, y);
-#elif (defined(__GNUC__) || defined(__clang__)) && defined(__SIZEOF_INT128__) && defined(__x86_64__)
+#if (defined(__GNUC__) || defined(__clang__)) && defined(__SIZEOF_INT128__) && defined(__x86_64__)
            auto p = (unsigned __int128)(x) * (unsigned __int128)(y);
            return std::uint64_t(p >> 64);
+#elif defined(_MSC_VER) && defined(_M_X64)
+           return __umulh(x, y);
 #else
            constexpr auto mask = (std::uint64_t(1) << 32) - std::uint64_t(1);

@@ -143,13 +143,13 @@ namespace jkj {
            auto g0 = umul128(x, y.high());
            auto g10 = umul128_upper64(x, y.low());

-#if defined(_MSC_VER) && defined(_M_X64)
+#if (defined(__GNUC__) || defined(__clang__)) && defined(__SIZEOF_INT128__) && defined(__x86_64__)
+           return uint128{ g0.internal_ + g10 }.high();
+#elif defined(_MSC_VER) && defined(_M_X64)
            std::uint64_t high, low;
            auto carry = _addcarry_u64(0, g0.low(), g10, &low);
            _addcarry_u64(carry, g0.high(), 0, &high);
            return high;
-#elif (defined(__GNUC__) || defined(__clang__)) && defined(__SIZEOF_INT128__) && defined(__x86_64__)
-           return uint128{ g0.internal_ + g10 }.high();
 #else
            auto intermediate = g0.low() + g10;
            return g0.high() + (intermediate < g10);
@@ -178,16 +178,7 @@ namespace jkj {
            static_assert(std::is_same_v<UInt, std::uint32_t> || std::is_same_v<UInt, std::uint64_t>);
            assert(exp >= 1);
            assert(x != 0);
-#if defined(_MSC_VER) && defined(_M_X64)
-           unsigned long index;
-           if constexpr (std::is_same_v<UInt, std::uint32_t>) {
-               _BitScanForward(&index, x);
-           }
-           else {
-               _BitScanForward64(&index, x);
-           }
-           return int(index) >= exp;
-#elif (defined(__GNUC__) || defined(__clang__)) && defined(__x86_64__)
+#if (defined(__GNUC__) || defined(__clang__)) && defined(__x86_64__)
            int index;
            if constexpr (std::is_same_v<UInt, std::uint32_t>) {
                static_assert(sizeof(unsigned long) == 4,
@@ -200,6 +191,15 @@ namespace jkj {
                index = __builtin_ctzll((unsigned long long)x);
            }
            return index >= exp;
+#elif defined(_MSC_VER) && defined(_M_X64)
+           unsigned long index;
+           if constexpr (std::is_same_v<UInt, std::uint32_t>) {
+               _BitScanForward(&index, x);
+           }
+           else {
+               _BitScanForward64(&index, x);
+           }
+           return int(index) >= exp;
 #else
            if (exp >= int(sizeof(UInt) * 8)) {
                return false;
@@ -1748,8 +1748,9 @@ namespace jkj {
            using common_info<Float>::integer_check_exponent_upper_bound_for_p_p2;
            using common_info<Float>::integer_check_exponent_upper_bound_for_p_p1;

+           // Clang/MSVC (clang-cl) fails when return type is set to auto for some reason
            template <unsigned int e>
-           static constexpr auto power_of_10 = compute_power(extended_significand_type(10), e);
+           static constexpr extended_significand_type power_of_10 = compute_power(extended_significand_type(10), e);


            //// The main algorithm assumes the input is a normal/subnormal finite number

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.