From 51a191600dbb8e79694457ef946494d0d7559ca7 Mon Sep 17 00:00:00 2001 From: Taromati2 Date: Fri, 29 Sep 2023 00:58:23 +0000 Subject: [PATCH] files update~ --- files/all | 126 +++++++++++++++++----------- files/base | 110 ++++++++++++++---------- files/base_defs | 91 +++++++++++--------- files/base_exception | 91 +++++++++++--------- files/base_stream | 110 ++++++++++++++---------- files/bignum | 126 +++++++++++++++++----------- files/code_realm | 91 +++++++++++--------- files/core | 110 ++++++++++++++---------- files/lib_loader | 126 +++++++++++++++++----------- files/log | 110 ++++++++++++++---------- files/namespace | 110 ++++++++++++++---------- files/numerical_representation | 126 +++++++++++++++++----------- files/package_symbol_loader | 126 +++++++++++++++++----------- files/random | 91 +++++++++++--------- files/resolve_global_name_conflicts | 91 +++++++++++--------- files/stream | 126 +++++++++++++++++----------- files/string | 110 ++++++++++++++---------- 17 files changed, 1113 insertions(+), 758 deletions(-) diff --git a/files/all b/files/all index 69b22a2..cd0072b 100644 --- a/files/all +++ b/files/all @@ -2845,37 +2845,43 @@ namespace math{ template requires(has_epsilon) [[nodiscard]]force_inline constexpr T sqrt(const T&v)noexcept; template + inline constexpr T sqrt_to_new_epsilon(T&num,const T&v,const to_unsigned_t&epsilon)noexcept{ + //newton-raphson + floop{ + auto next_ret=(num+v/num)/2u; + const bool end=abs(next_ret-num) + [[nodiscard]]inline constexpr T quick_sqrt(const T&v)noexcept{ + if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking + if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 + if constexpr(type_info == type_info) + return union_cast(0x5F375A86-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + #if defined(_MSC_VER)//msvc上long double就是double + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + #elif defined(ELC_BASE_ENV_HAS_INT128) + return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); + #else + do_nothing;//可以寄了 + #endif + elseif constexpr(is_big_type) + return sqrt(static_cast(v)); + return v/2u; + } + template [[nodiscard]]inline constexpr T sqrt(const T&v,const to_unsigned_t&epsilon)noexcept{ if constexpr(has_NaN && has_inf) if(v < 0u || v >= arithmetic_type_info_prover::Inf()) return arithmetic_type_info_prover::NaN(); - T aret=exlambda()->T{ - if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking - if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 - if constexpr(type_info == type_info) - return union_cast(0x5F375A86-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - #if defined(_MSC_VER)//msvc上long double就是double - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - #elif defined(ELC_BASE_ENV_HAS_INT128) - return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); - #else - do_nothing;//可以寄了 - #endif - elseif constexpr(is_big_type) - return sqrt(static_cast(v)); - return v/2u; - }(); - //newton-raphson - floop{ - auto next_ret=(aret+v/aret)/2u; - if(abs(next_ret-aret) requires(has_epsilon) @@ -2889,13 +2895,13 @@ namespace math{ /*! 判断某数是否是素数,无预先检查以供其他素数相关函数快速调用. */ template [[nodiscard]]inline constexpr bool is_prime_num_no_pre_check(T a)noexcept{ - #line 415 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 421 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" T b=safe_arithmetic_cast(sqrt(a));//若一个数可以分解为两因数之积,其中一个因数必定≤其开方:反指数式减少遍历范围. - #line 427 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 433 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" for(T c=5u;c<=b;c+=6u)//遍历判断是否能被因数分解——不会有人看不懂吧? if((!mod(a,c))||(!mod(a,(c+2u)))) return false; - #line 436 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 442 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return true; } /*! 判断某数是否是素数 */ @@ -2908,10 +2914,10 @@ namespace math{ if(b<4) return true;//1和0也是prime,我不管. - #line 458 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 464 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if(mod(mod(b,6)-1u,4u)) return false; - #line 463 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 469 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return is_prime_num_no_pre_check(b); } /// 求小于或等于某数的素数 @@ -2970,13 +2976,13 @@ namespace math{ /// 已知当前array的size,求下一个合适的提前分配大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_array(size_T size)noexcept{ - #line 524 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 530 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(size*magic_number::gold_of_resize); } /// 已知当前hash table的size,求下一个合适的桶大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_hash(size_T size)noexcept{ - #line 533 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 539 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(get_prime_num_big_or_eq_than(size*magic_number::gold_of_resize)); } pop_msvc_warning(); @@ -3250,6 +3256,8 @@ using math::integer_log; using math::pow; using math::ceil; using math::floor; +using math::sqrt_to_new_epsilon; +using math::quick_sqrt; using math::sqrt; using math::trunc; using math::is_prime_num; @@ -3352,7 +3360,7 @@ namespace magic_number{ //我们可以将result看作Ai*sqrt_640320的和. auto magic_number = sqrt_640320; //计算新的sqrt_640320. - sqrt_640320 = sqrt(ufloat_t{640320u},new_epsilon); + sqrt_to_new_epsilon(sqrt_640320,ufloat_t{640320u},new_epsilon); magic_number /= sqrt_640320; //去除旧数据的影响. result /= magic_number; @@ -3395,9 +3403,9 @@ namespace math{ template [[nodiscard]]constexpr T arctan(T num, const to_unsigned_t&epsilon)noexcept{ - #line 955 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 963 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if constexpr(signed_type) - if (num < 0) return copy_as_negative(arctan(abs(num), epsilon)); + if (num < 0) return -arctan(abs(num), epsilon); if (num > 1) return pi_with_epsilon(epsilon)/2u - arctan(reciprocal(move(num)), epsilon); size_t i = 1; bool negation = false; // 取反 @@ -6120,7 +6128,7 @@ namespace note_n{ force_inline constexpr name##_t(T a)noexcept:value(a){}\ template\ force_inline constexpr name##_t(name##_ta)noexcept:value(a.value){}\ - force_inline constexpr operator T()noexcept{return value;}\ + force_inline explicit constexpr operator T()noexcept{return value;}\ force_inline constexpr T operator()()noexcept{return value;}\ };\ template\ @@ -6151,7 +6159,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr size_t size_of_array_like(T(&)[N])noexcept{return N;} template - [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list&a)noexcept{return a.size();} + [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list>&a)noexcept{return a.size();} enable_adl(begin_of_array_like); template @@ -6159,7 +6167,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr auto begin_of_array_like(T(&a)[N])noexcept{return addressof(a[0]);} template - [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list&a)noexcept{return a.begin();} + [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list>&a)noexcept{return a.begin();} enable_adl(end_of_array_like); template @@ -6188,6 +6196,8 @@ namespace array_like_n{ template constexpr bool is_array_like_for=strict_is_array_like_for||strict_is_array_like_for; + static_assert(is_array_like_for>); + template struct array_like_view_t{ typedef T* iterator; @@ -6218,6 +6228,7 @@ namespace array_like_n{ size_t _size=0; public: constexpr explicit array_like_view_t(T*a,size_t b)noexcept:_begin(a),_size(b){} + constexpr explicit array_like_view_t(T*a,note::size_t b)noexcept:array_like_view_t(a,b()){} template requires strict_is_array_like_for explicit constexpr_as_auto array_like_view_t(U&&a)noexcept_as(begin_of_array_like(a),size_of_array_like(a)):array_like_view_t(begin_of_array_like(a),size_of_array_like(a)){} constexpr array_like_view_t(const this_t&)noexcept=default; @@ -17623,7 +17634,16 @@ namespace array_n{ explicit array_t(note::size_t size,const T&elem)noexcept(get.nothrow<>){ _m=get[size.value](elem); } - #line 60 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base/container/array/defs.hpp" + // ::std::initializer_list的构造 + array_t(::std::initializer_list&&list)noexcept(get.as_array.nothrow<::std::initializer_list>){ + _m=get.as_array(array_like_view_t{list}); + } + // T[N]的构造 + template + array_t(T(&a)[N])noexcept(get.as_array.nothrow){ + _m=get.as_array(a); + } + #line 69 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base/container/array/defs.hpp" //template.as_array.able> U> template requires(get.as_array.able && type_info>!=type_info) array_t(U&&a)noexcept(get.as_array.nothrow){ @@ -17827,12 +17847,12 @@ namespace array_n{ template - [[nodiscard]]iterator find(U&&a)noexcept requires was_not_an_ill_form(in_range(declvalue(this_t),a)){ - return in_range(*this,a); + [[nodiscard]]iterator find(U&&a)noexcept{ + return in_range(a,array_like_view_t{*this}); } template - [[nodiscard]]const_iterator find(U&&a)const noexcept requires was_not_an_ill_form(in_range(declvalue(this_t),a)){ - return in_range(*this,a); + [[nodiscard]]const_iterator find(U&&a)const noexcept{ + return in_range(a,array_like_view_t{*this}); } }; template @@ -34174,8 +34194,8 @@ public: [[nodiscard]]friend ubigfloat reciprocal(const ubigfloat& a)noexcept{ return ubigfloat{a._denominator,a._numerator}; } - [[nodiscard]]friend ubigfloat reciprocal(ubigfloat&& a)noexcept{ - return ubigfloat{move(a._denominator),move(a._numerator)}; + [[nodiscard]]friend ubigfloat&& reciprocal(ubigfloat&& a)noexcept{ + return swap(a._denominator,a._numerator),move(a); } //friend get_numerator [[nodiscard]]friend const ubigint& get_numerator(const ubigfloat& a)noexcept{ @@ -34517,6 +34537,9 @@ class bigfloat; [[nodiscard]]bigfloat copy_as_negative(ubigfloat&&,bool sign=true)noexcept; using math::copy_as_negative;//避免可能的符号覆盖 +[[nodiscard]]inline bigfloat operator-(const ubigfloat&num)noexcept; +[[nodiscard]]inline bigfloat operator-(ubigfloat&&num)noexcept; + class bigfloat{ bool _is_negative=false; ubigfloat _num; @@ -34626,7 +34649,7 @@ public: return bigfloat{reciprocal(a._num), a._is_negative}; } [[nodiscard]]friend bigfloat&& reciprocal(bigfloat&& a)noexcept{ - a._num=reciprocal(move(a._num)); + discard=reciprocal(move(a._num));//swap it! return move(a); } //friend trunc @@ -34831,6 +34854,13 @@ public: } }; +[[nodiscard]]inline bigfloat operator-(const ubigfloat&num)noexcept{ + return copy_as_negative(num); +} +[[nodiscard]]inline bigfloat operator-(ubigfloat&&num)noexcept{ + return copy_as_negative(move(num)); +} + template concept bigfloat_cvref=type_info> == type_info; diff --git a/files/base b/files/base index 5c9f284..5290b20 100644 --- a/files/base +++ b/files/base @@ -2805,37 +2805,43 @@ namespace math{ template requires(has_epsilon) [[nodiscard]]force_inline constexpr T sqrt(const T&v)noexcept; template + inline constexpr T sqrt_to_new_epsilon(T&num,const T&v,const to_unsigned_t&epsilon)noexcept{ + //newton-raphson + floop{ + auto next_ret=(num+v/num)/2u; + const bool end=abs(next_ret-num) + [[nodiscard]]inline constexpr T quick_sqrt(const T&v)noexcept{ + if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking + if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 + if constexpr(type_info == type_info) + return union_cast(0x5F375A86-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + #if defined(_MSC_VER)//msvc上long double就是double + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + #elif defined(ELC_BASE_ENV_HAS_INT128) + return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); + #else + do_nothing;//可以寄了 + #endif + elseif constexpr(is_big_type) + return sqrt(static_cast(v)); + return v/2u; + } + template [[nodiscard]]inline constexpr T sqrt(const T&v,const to_unsigned_t&epsilon)noexcept{ if constexpr(has_NaN && has_inf) if(v < 0u || v >= arithmetic_type_info_prover::Inf()) return arithmetic_type_info_prover::NaN(); - T aret=exlambda()->T{ - if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking - if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 - if constexpr(type_info == type_info) - return union_cast(0x5F375A86-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - #if defined(_MSC_VER)//msvc上long double就是double - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - #elif defined(ELC_BASE_ENV_HAS_INT128) - return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); - #else - do_nothing;//可以寄了 - #endif - elseif constexpr(is_big_type) - return sqrt(static_cast(v)); - return v/2u; - }(); - //newton-raphson - floop{ - auto next_ret=(aret+v/aret)/2u; - if(abs(next_ret-aret) requires(has_epsilon) @@ -2849,13 +2855,13 @@ namespace math{ /*! 判断某数是否是素数,无预先检查以供其他素数相关函数快速调用. */ template [[nodiscard]]inline constexpr bool is_prime_num_no_pre_check(T a)noexcept{ - #line 415 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 421 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" T b=safe_arithmetic_cast(sqrt(a));//若一个数可以分解为两因数之积,其中一个因数必定≤其开方:反指数式减少遍历范围. - #line 427 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 433 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" for(T c=5u;c<=b;c+=6u)//遍历判断是否能被因数分解——不会有人看不懂吧? if((!mod(a,c))||(!mod(a,(c+2u)))) return false; - #line 436 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 442 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return true; } /*! 判断某数是否是素数 */ @@ -2868,10 +2874,10 @@ namespace math{ if(b<4) return true;//1和0也是prime,我不管. - #line 458 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 464 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if(mod(mod(b,6)-1u,4u)) return false; - #line 463 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 469 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return is_prime_num_no_pre_check(b); } /// 求小于或等于某数的素数 @@ -2930,13 +2936,13 @@ namespace math{ /// 已知当前array的size,求下一个合适的提前分配大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_array(size_T size)noexcept{ - #line 524 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 530 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(size*magic_number::gold_of_resize); } /// 已知当前hash table的size,求下一个合适的桶大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_hash(size_T size)noexcept{ - #line 533 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 539 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(get_prime_num_big_or_eq_than(size*magic_number::gold_of_resize)); } pop_msvc_warning(); @@ -3210,6 +3216,8 @@ using math::integer_log; using math::pow; using math::ceil; using math::floor; +using math::sqrt_to_new_epsilon; +using math::quick_sqrt; using math::sqrt; using math::trunc; using math::is_prime_num; @@ -3312,7 +3320,7 @@ namespace magic_number{ //我们可以将result看作Ai*sqrt_640320的和. auto magic_number = sqrt_640320; //计算新的sqrt_640320. - sqrt_640320 = sqrt(ufloat_t{640320u},new_epsilon); + sqrt_to_new_epsilon(sqrt_640320,ufloat_t{640320u},new_epsilon); magic_number /= sqrt_640320; //去除旧数据的影响. result /= magic_number; @@ -3355,9 +3363,9 @@ namespace math{ template [[nodiscard]]constexpr T arctan(T num, const to_unsigned_t&epsilon)noexcept{ - #line 955 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 963 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if constexpr(signed_type) - if (num < 0) return copy_as_negative(arctan(abs(num), epsilon)); + if (num < 0) return -arctan(abs(num), epsilon); if (num > 1) return pi_with_epsilon(epsilon)/2u - arctan(reciprocal(move(num)), epsilon); size_t i = 1; bool negation = false; // 取反 @@ -6080,7 +6088,7 @@ namespace note_n{ force_inline constexpr name##_t(T a)noexcept:value(a){}\ template\ force_inline constexpr name##_t(name##_ta)noexcept:value(a.value){}\ - force_inline constexpr operator T()noexcept{return value;}\ + force_inline explicit constexpr operator T()noexcept{return value;}\ force_inline constexpr T operator()()noexcept{return value;}\ };\ template\ @@ -6111,7 +6119,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr size_t size_of_array_like(T(&)[N])noexcept{return N;} template - [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list&a)noexcept{return a.size();} + [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list>&a)noexcept{return a.size();} enable_adl(begin_of_array_like); template @@ -6119,7 +6127,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr auto begin_of_array_like(T(&a)[N])noexcept{return addressof(a[0]);} template - [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list&a)noexcept{return a.begin();} + [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list>&a)noexcept{return a.begin();} enable_adl(end_of_array_like); template @@ -6148,6 +6156,8 @@ namespace array_like_n{ template constexpr bool is_array_like_for=strict_is_array_like_for||strict_is_array_like_for; + static_assert(is_array_like_for>); + template struct array_like_view_t{ typedef T* iterator; @@ -6178,6 +6188,7 @@ namespace array_like_n{ size_t _size=0; public: constexpr explicit array_like_view_t(T*a,size_t b)noexcept:_begin(a),_size(b){} + constexpr explicit array_like_view_t(T*a,note::size_t b)noexcept:array_like_view_t(a,b()){} template requires strict_is_array_like_for explicit constexpr_as_auto array_like_view_t(U&&a)noexcept_as(begin_of_array_like(a),size_of_array_like(a)):array_like_view_t(begin_of_array_like(a),size_of_array_like(a)){} constexpr array_like_view_t(const this_t&)noexcept=default; @@ -17583,7 +17594,16 @@ namespace array_n{ explicit array_t(note::size_t size,const T&elem)noexcept(get.nothrow<>){ _m=get[size.value](elem); } - #line 60 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base/container/array/defs.hpp" + // ::std::initializer_list的构造 + array_t(::std::initializer_list&&list)noexcept(get.as_array.nothrow<::std::initializer_list>){ + _m=get.as_array(array_like_view_t{list}); + } + // T[N]的构造 + template + array_t(T(&a)[N])noexcept(get.as_array.nothrow){ + _m=get.as_array(a); + } + #line 69 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base/container/array/defs.hpp" //template.as_array.able> U> template requires(get.as_array.able && type_info>!=type_info) array_t(U&&a)noexcept(get.as_array.nothrow){ @@ -17787,12 +17807,12 @@ namespace array_n{ template - [[nodiscard]]iterator find(U&&a)noexcept requires was_not_an_ill_form(in_range(declvalue(this_t),a)){ - return in_range(*this,a); + [[nodiscard]]iterator find(U&&a)noexcept{ + return in_range(a,array_like_view_t{*this}); } template - [[nodiscard]]const_iterator find(U&&a)const noexcept requires was_not_an_ill_form(in_range(declvalue(this_t),a)){ - return in_range(*this,a); + [[nodiscard]]const_iterator find(U&&a)const noexcept{ + return in_range(a,array_like_view_t{*this}); } }; template diff --git a/files/base_defs b/files/base_defs index 62a778c..973661b 100644 --- a/files/base_defs +++ b/files/base_defs @@ -2765,37 +2765,43 @@ namespace math{ template requires(has_epsilon) [[nodiscard]]force_inline constexpr T sqrt(const T&v)noexcept; template + inline constexpr T sqrt_to_new_epsilon(T&num,const T&v,const to_unsigned_t&epsilon)noexcept{ + //newton-raphson + floop{ + auto next_ret=(num+v/num)/2u; + const bool end=abs(next_ret-num) + [[nodiscard]]inline constexpr T quick_sqrt(const T&v)noexcept{ + if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking + if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 + if constexpr(type_info == type_info) + return union_cast(0x5F375A86-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + #if defined(_MSC_VER)//msvc上long double就是double + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + #elif defined(ELC_BASE_ENV_HAS_INT128) + return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); + #else + do_nothing;//可以寄了 + #endif + elseif constexpr(is_big_type) + return sqrt(static_cast(v)); + return v/2u; + } + template [[nodiscard]]inline constexpr T sqrt(const T&v,const to_unsigned_t&epsilon)noexcept{ if constexpr(has_NaN && has_inf) if(v < 0u || v >= arithmetic_type_info_prover::Inf()) return arithmetic_type_info_prover::NaN(); - T aret=exlambda()->T{ - if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking - if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 - if constexpr(type_info == type_info) - return union_cast(0x5F375A86-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - #if defined(_MSC_VER)//msvc上long double就是double - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - #elif defined(ELC_BASE_ENV_HAS_INT128) - return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); - #else - do_nothing;//可以寄了 - #endif - elseif constexpr(is_big_type) - return sqrt(static_cast(v)); - return v/2u; - }(); - //newton-raphson - floop{ - auto next_ret=(aret+v/aret)/2u; - if(abs(next_ret-aret) requires(has_epsilon) @@ -2809,13 +2815,13 @@ namespace math{ /*! 判断某数是否是素数,无预先检查以供其他素数相关函数快速调用. */ template [[nodiscard]]inline constexpr bool is_prime_num_no_pre_check(T a)noexcept{ - #line 415 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 421 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" T b=safe_arithmetic_cast(sqrt(a));//若一个数可以分解为两因数之积,其中一个因数必定≤其开方:反指数式减少遍历范围. - #line 427 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 433 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" for(T c=5u;c<=b;c+=6u)//遍历判断是否能被因数分解——不会有人看不懂吧? if((!mod(a,c))||(!mod(a,(c+2u)))) return false; - #line 436 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 442 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return true; } /*! 判断某数是否是素数 */ @@ -2828,10 +2834,10 @@ namespace math{ if(b<4) return true;//1和0也是prime,我不管. - #line 458 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 464 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if(mod(mod(b,6)-1u,4u)) return false; - #line 463 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 469 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return is_prime_num_no_pre_check(b); } /// 求小于或等于某数的素数 @@ -2890,13 +2896,13 @@ namespace math{ /// 已知当前array的size,求下一个合适的提前分配大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_array(size_T size)noexcept{ - #line 524 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 530 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(size*magic_number::gold_of_resize); } /// 已知当前hash table的size,求下一个合适的桶大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_hash(size_T size)noexcept{ - #line 533 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 539 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(get_prime_num_big_or_eq_than(size*magic_number::gold_of_resize)); } pop_msvc_warning(); @@ -3170,6 +3176,8 @@ using math::integer_log; using math::pow; using math::ceil; using math::floor; +using math::sqrt_to_new_epsilon; +using math::quick_sqrt; using math::sqrt; using math::trunc; using math::is_prime_num; @@ -3272,7 +3280,7 @@ namespace magic_number{ //我们可以将result看作Ai*sqrt_640320的和. auto magic_number = sqrt_640320; //计算新的sqrt_640320. - sqrt_640320 = sqrt(ufloat_t{640320u},new_epsilon); + sqrt_to_new_epsilon(sqrt_640320,ufloat_t{640320u},new_epsilon); magic_number /= sqrt_640320; //去除旧数据的影响. result /= magic_number; @@ -3315,9 +3323,9 @@ namespace math{ template [[nodiscard]]constexpr T arctan(T num, const to_unsigned_t&epsilon)noexcept{ - #line 955 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 963 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if constexpr(signed_type) - if (num < 0) return copy_as_negative(arctan(abs(num), epsilon)); + if (num < 0) return -arctan(abs(num), epsilon); if (num > 1) return pi_with_epsilon(epsilon)/2u - arctan(reciprocal(move(num)), epsilon); size_t i = 1; bool negation = false; // 取反 @@ -6040,7 +6048,7 @@ namespace note_n{ force_inline constexpr name##_t(T a)noexcept:value(a){}\ template\ force_inline constexpr name##_t(name##_ta)noexcept:value(a.value){}\ - force_inline constexpr operator T()noexcept{return value;}\ + force_inline explicit constexpr operator T()noexcept{return value;}\ force_inline constexpr T operator()()noexcept{return value;}\ };\ template\ @@ -6071,7 +6079,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr size_t size_of_array_like(T(&)[N])noexcept{return N;} template - [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list&a)noexcept{return a.size();} + [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list>&a)noexcept{return a.size();} enable_adl(begin_of_array_like); template @@ -6079,7 +6087,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr auto begin_of_array_like(T(&a)[N])noexcept{return addressof(a[0]);} template - [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list&a)noexcept{return a.begin();} + [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list>&a)noexcept{return a.begin();} enable_adl(end_of_array_like); template @@ -6108,6 +6116,8 @@ namespace array_like_n{ template constexpr bool is_array_like_for=strict_is_array_like_for||strict_is_array_like_for; + static_assert(is_array_like_for>); + template struct array_like_view_t{ typedef T* iterator; @@ -6138,6 +6148,7 @@ namespace array_like_n{ size_t _size=0; public: constexpr explicit array_like_view_t(T*a,size_t b)noexcept:_begin(a),_size(b){} + constexpr explicit array_like_view_t(T*a,note::size_t b)noexcept:array_like_view_t(a,b()){} template requires strict_is_array_like_for explicit constexpr_as_auto array_like_view_t(U&&a)noexcept_as(begin_of_array_like(a),size_of_array_like(a)):array_like_view_t(begin_of_array_like(a),size_of_array_like(a)){} constexpr array_like_view_t(const this_t&)noexcept=default; diff --git a/files/base_exception b/files/base_exception index a1754ce..1aa2cbb 100644 --- a/files/base_exception +++ b/files/base_exception @@ -2811,37 +2811,43 @@ namespace math{ template requires(has_epsilon) [[nodiscard]]force_inline constexpr T sqrt(const T&v)noexcept; template + inline constexpr T sqrt_to_new_epsilon(T&num,const T&v,const to_unsigned_t&epsilon)noexcept{ + //newton-raphson + floop{ + auto next_ret=(num+v/num)/2u; + const bool end=abs(next_ret-num) + [[nodiscard]]inline constexpr T quick_sqrt(const T&v)noexcept{ + if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking + if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 + if constexpr(type_info == type_info) + return union_cast(0x5F375A86-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + #if defined(_MSC_VER)//msvc上long double就是double + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + #elif defined(ELC_BASE_ENV_HAS_INT128) + return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); + #else + do_nothing;//可以寄了 + #endif + elseif constexpr(is_big_type) + return sqrt(static_cast(v)); + return v/2u; + } + template [[nodiscard]]inline constexpr T sqrt(const T&v,const to_unsigned_t&epsilon)noexcept{ if constexpr(has_NaN && has_inf) if(v < 0u || v >= arithmetic_type_info_prover::Inf()) return arithmetic_type_info_prover::NaN(); - T aret=exlambda()->T{ - if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking - if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 - if constexpr(type_info == type_info) - return union_cast(0x5F375A86-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - #if defined(_MSC_VER)//msvc上long double就是double - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - #elif defined(ELC_BASE_ENV_HAS_INT128) - return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); - #else - do_nothing;//可以寄了 - #endif - elseif constexpr(is_big_type) - return sqrt(static_cast(v)); - return v/2u; - }(); - //newton-raphson - floop{ - auto next_ret=(aret+v/aret)/2u; - if(abs(next_ret-aret) requires(has_epsilon) @@ -2855,13 +2861,13 @@ namespace math{ /*! 判断某数是否是素数,无预先检查以供其他素数相关函数快速调用. */ template [[nodiscard]]inline constexpr bool is_prime_num_no_pre_check(T a)noexcept{ - #line 415 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 421 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" T b=safe_arithmetic_cast(sqrt(a));//若一个数可以分解为两因数之积,其中一个因数必定≤其开方:反指数式减少遍历范围. - #line 427 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 433 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" for(T c=5u;c<=b;c+=6u)//遍历判断是否能被因数分解——不会有人看不懂吧? if((!mod(a,c))||(!mod(a,(c+2u)))) return false; - #line 436 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 442 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return true; } /*! 判断某数是否是素数 */ @@ -2874,10 +2880,10 @@ namespace math{ if(b<4) return true;//1和0也是prime,我不管. - #line 458 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 464 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if(mod(mod(b,6)-1u,4u)) return false; - #line 463 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 469 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return is_prime_num_no_pre_check(b); } /// 求小于或等于某数的素数 @@ -2936,13 +2942,13 @@ namespace math{ /// 已知当前array的size,求下一个合适的提前分配大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_array(size_T size)noexcept{ - #line 524 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 530 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(size*magic_number::gold_of_resize); } /// 已知当前hash table的size,求下一个合适的桶大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_hash(size_T size)noexcept{ - #line 533 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 539 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(get_prime_num_big_or_eq_than(size*magic_number::gold_of_resize)); } pop_msvc_warning(); @@ -3216,6 +3222,8 @@ using math::integer_log; using math::pow; using math::ceil; using math::floor; +using math::sqrt_to_new_epsilon; +using math::quick_sqrt; using math::sqrt; using math::trunc; using math::is_prime_num; @@ -3318,7 +3326,7 @@ namespace magic_number{ //我们可以将result看作Ai*sqrt_640320的和. auto magic_number = sqrt_640320; //计算新的sqrt_640320. - sqrt_640320 = sqrt(ufloat_t{640320u},new_epsilon); + sqrt_to_new_epsilon(sqrt_640320,ufloat_t{640320u},new_epsilon); magic_number /= sqrt_640320; //去除旧数据的影响. result /= magic_number; @@ -3361,9 +3369,9 @@ namespace math{ template [[nodiscard]]constexpr T arctan(T num, const to_unsigned_t&epsilon)noexcept{ - #line 955 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 963 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if constexpr(signed_type) - if (num < 0) return copy_as_negative(arctan(abs(num), epsilon)); + if (num < 0) return -arctan(abs(num), epsilon); if (num > 1) return pi_with_epsilon(epsilon)/2u - arctan(reciprocal(move(num)), epsilon); size_t i = 1; bool negation = false; // 取反 @@ -6086,7 +6094,7 @@ namespace note_n{ force_inline constexpr name##_t(T a)noexcept:value(a){}\ template\ force_inline constexpr name##_t(name##_ta)noexcept:value(a.value){}\ - force_inline constexpr operator T()noexcept{return value;}\ + force_inline explicit constexpr operator T()noexcept{return value;}\ force_inline constexpr T operator()()noexcept{return value;}\ };\ template\ @@ -6117,7 +6125,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr size_t size_of_array_like(T(&)[N])noexcept{return N;} template - [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list&a)noexcept{return a.size();} + [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list>&a)noexcept{return a.size();} enable_adl(begin_of_array_like); template @@ -6125,7 +6133,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr auto begin_of_array_like(T(&a)[N])noexcept{return addressof(a[0]);} template - [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list&a)noexcept{return a.begin();} + [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list>&a)noexcept{return a.begin();} enable_adl(end_of_array_like); template @@ -6154,6 +6162,8 @@ namespace array_like_n{ template constexpr bool is_array_like_for=strict_is_array_like_for||strict_is_array_like_for; + static_assert(is_array_like_for>); + template struct array_like_view_t{ typedef T* iterator; @@ -6184,6 +6194,7 @@ namespace array_like_n{ size_t _size=0; public: constexpr explicit array_like_view_t(T*a,size_t b)noexcept:_begin(a),_size(b){} + constexpr explicit array_like_view_t(T*a,note::size_t b)noexcept:array_like_view_t(a,b()){} template requires strict_is_array_like_for explicit constexpr_as_auto array_like_view_t(U&&a)noexcept_as(begin_of_array_like(a),size_of_array_like(a)):array_like_view_t(begin_of_array_like(a),size_of_array_like(a)){} constexpr array_like_view_t(const this_t&)noexcept=default; diff --git a/files/base_stream b/files/base_stream index f94873e..6039ec2 100644 --- a/files/base_stream +++ b/files/base_stream @@ -2845,37 +2845,43 @@ namespace math{ template requires(has_epsilon) [[nodiscard]]force_inline constexpr T sqrt(const T&v)noexcept; template + inline constexpr T sqrt_to_new_epsilon(T&num,const T&v,const to_unsigned_t&epsilon)noexcept{ + //newton-raphson + floop{ + auto next_ret=(num+v/num)/2u; + const bool end=abs(next_ret-num) + [[nodiscard]]inline constexpr T quick_sqrt(const T&v)noexcept{ + if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking + if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 + if constexpr(type_info == type_info) + return union_cast(0x5F375A86-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + #if defined(_MSC_VER)//msvc上long double就是double + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + #elif defined(ELC_BASE_ENV_HAS_INT128) + return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); + #else + do_nothing;//可以寄了 + #endif + elseif constexpr(is_big_type) + return sqrt(static_cast(v)); + return v/2u; + } + template [[nodiscard]]inline constexpr T sqrt(const T&v,const to_unsigned_t&epsilon)noexcept{ if constexpr(has_NaN && has_inf) if(v < 0u || v >= arithmetic_type_info_prover::Inf()) return arithmetic_type_info_prover::NaN(); - T aret=exlambda()->T{ - if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking - if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 - if constexpr(type_info == type_info) - return union_cast(0x5F375A86-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - #if defined(_MSC_VER)//msvc上long double就是double - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - #elif defined(ELC_BASE_ENV_HAS_INT128) - return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); - #else - do_nothing;//可以寄了 - #endif - elseif constexpr(is_big_type) - return sqrt(static_cast(v)); - return v/2u; - }(); - //newton-raphson - floop{ - auto next_ret=(aret+v/aret)/2u; - if(abs(next_ret-aret) requires(has_epsilon) @@ -2889,13 +2895,13 @@ namespace math{ /*! 判断某数是否是素数,无预先检查以供其他素数相关函数快速调用. */ template [[nodiscard]]inline constexpr bool is_prime_num_no_pre_check(T a)noexcept{ - #line 415 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 421 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" T b=safe_arithmetic_cast(sqrt(a));//若一个数可以分解为两因数之积,其中一个因数必定≤其开方:反指数式减少遍历范围. - #line 427 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 433 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" for(T c=5u;c<=b;c+=6u)//遍历判断是否能被因数分解——不会有人看不懂吧? if((!mod(a,c))||(!mod(a,(c+2u)))) return false; - #line 436 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 442 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return true; } /*! 判断某数是否是素数 */ @@ -2908,10 +2914,10 @@ namespace math{ if(b<4) return true;//1和0也是prime,我不管. - #line 458 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 464 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if(mod(mod(b,6)-1u,4u)) return false; - #line 463 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 469 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return is_prime_num_no_pre_check(b); } /// 求小于或等于某数的素数 @@ -2970,13 +2976,13 @@ namespace math{ /// 已知当前array的size,求下一个合适的提前分配大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_array(size_T size)noexcept{ - #line 524 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 530 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(size*magic_number::gold_of_resize); } /// 已知当前hash table的size,求下一个合适的桶大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_hash(size_T size)noexcept{ - #line 533 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 539 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(get_prime_num_big_or_eq_than(size*magic_number::gold_of_resize)); } pop_msvc_warning(); @@ -3250,6 +3256,8 @@ using math::integer_log; using math::pow; using math::ceil; using math::floor; +using math::sqrt_to_new_epsilon; +using math::quick_sqrt; using math::sqrt; using math::trunc; using math::is_prime_num; @@ -3352,7 +3360,7 @@ namespace magic_number{ //我们可以将result看作Ai*sqrt_640320的和. auto magic_number = sqrt_640320; //计算新的sqrt_640320. - sqrt_640320 = sqrt(ufloat_t{640320u},new_epsilon); + sqrt_to_new_epsilon(sqrt_640320,ufloat_t{640320u},new_epsilon); magic_number /= sqrt_640320; //去除旧数据的影响. result /= magic_number; @@ -3395,9 +3403,9 @@ namespace math{ template [[nodiscard]]constexpr T arctan(T num, const to_unsigned_t&epsilon)noexcept{ - #line 955 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 963 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if constexpr(signed_type) - if (num < 0) return copy_as_negative(arctan(abs(num), epsilon)); + if (num < 0) return -arctan(abs(num), epsilon); if (num > 1) return pi_with_epsilon(epsilon)/2u - arctan(reciprocal(move(num)), epsilon); size_t i = 1; bool negation = false; // 取反 @@ -6120,7 +6128,7 @@ namespace note_n{ force_inline constexpr name##_t(T a)noexcept:value(a){}\ template\ force_inline constexpr name##_t(name##_ta)noexcept:value(a.value){}\ - force_inline constexpr operator T()noexcept{return value;}\ + force_inline explicit constexpr operator T()noexcept{return value;}\ force_inline constexpr T operator()()noexcept{return value;}\ };\ template\ @@ -6151,7 +6159,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr size_t size_of_array_like(T(&)[N])noexcept{return N;} template - [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list&a)noexcept{return a.size();} + [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list>&a)noexcept{return a.size();} enable_adl(begin_of_array_like); template @@ -6159,7 +6167,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr auto begin_of_array_like(T(&a)[N])noexcept{return addressof(a[0]);} template - [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list&a)noexcept{return a.begin();} + [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list>&a)noexcept{return a.begin();} enable_adl(end_of_array_like); template @@ -6188,6 +6196,8 @@ namespace array_like_n{ template constexpr bool is_array_like_for=strict_is_array_like_for||strict_is_array_like_for; + static_assert(is_array_like_for>); + template struct array_like_view_t{ typedef T* iterator; @@ -6218,6 +6228,7 @@ namespace array_like_n{ size_t _size=0; public: constexpr explicit array_like_view_t(T*a,size_t b)noexcept:_begin(a),_size(b){} + constexpr explicit array_like_view_t(T*a,note::size_t b)noexcept:array_like_view_t(a,b()){} template requires strict_is_array_like_for explicit constexpr_as_auto array_like_view_t(U&&a)noexcept_as(begin_of_array_like(a),size_of_array_like(a)):array_like_view_t(begin_of_array_like(a),size_of_array_like(a)){} constexpr array_like_view_t(const this_t&)noexcept=default; @@ -17623,7 +17634,16 @@ namespace array_n{ explicit array_t(note::size_t size,const T&elem)noexcept(get.nothrow<>){ _m=get[size.value](elem); } - #line 60 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base/container/array/defs.hpp" + // ::std::initializer_list的构造 + array_t(::std::initializer_list&&list)noexcept(get.as_array.nothrow<::std::initializer_list>){ + _m=get.as_array(array_like_view_t{list}); + } + // T[N]的构造 + template + array_t(T(&a)[N])noexcept(get.as_array.nothrow){ + _m=get.as_array(a); + } + #line 69 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base/container/array/defs.hpp" //template.as_array.able> U> template requires(get.as_array.able && type_info>!=type_info) array_t(U&&a)noexcept(get.as_array.nothrow){ @@ -17827,12 +17847,12 @@ namespace array_n{ template - [[nodiscard]]iterator find(U&&a)noexcept requires was_not_an_ill_form(in_range(declvalue(this_t),a)){ - return in_range(*this,a); + [[nodiscard]]iterator find(U&&a)noexcept{ + return in_range(a,array_like_view_t{*this}); } template - [[nodiscard]]const_iterator find(U&&a)const noexcept requires was_not_an_ill_form(in_range(declvalue(this_t),a)){ - return in_range(*this,a); + [[nodiscard]]const_iterator find(U&&a)const noexcept{ + return in_range(a,array_like_view_t{*this}); } }; template diff --git a/files/bignum b/files/bignum index df7f4e9..de94fc1 100644 --- a/files/bignum +++ b/files/bignum @@ -2844,37 +2844,43 @@ namespace math{ template requires(has_epsilon) [[nodiscard]]force_inline constexpr T sqrt(const T&v)noexcept; template + inline constexpr T sqrt_to_new_epsilon(T&num,const T&v,const to_unsigned_t&epsilon)noexcept{ + //newton-raphson + floop{ + auto next_ret=(num+v/num)/2u; + const bool end=abs(next_ret-num) + [[nodiscard]]inline constexpr T quick_sqrt(const T&v)noexcept{ + if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking + if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 + if constexpr(type_info == type_info) + return union_cast(0x5F375A86-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + #if defined(_MSC_VER)//msvc上long double就是double + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + #elif defined(ELC_BASE_ENV_HAS_INT128) + return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); + #else + do_nothing;//可以寄了 + #endif + elseif constexpr(is_big_type) + return sqrt(static_cast(v)); + return v/2u; + } + template [[nodiscard]]inline constexpr T sqrt(const T&v,const to_unsigned_t&epsilon)noexcept{ if constexpr(has_NaN && has_inf) if(v < 0u || v >= arithmetic_type_info_prover::Inf()) return arithmetic_type_info_prover::NaN(); - T aret=exlambda()->T{ - if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking - if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 - if constexpr(type_info == type_info) - return union_cast(0x5F375A86-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - #if defined(_MSC_VER)//msvc上long double就是double - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - #elif defined(ELC_BASE_ENV_HAS_INT128) - return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); - #else - do_nothing;//可以寄了 - #endif - elseif constexpr(is_big_type) - return sqrt(static_cast(v)); - return v/2u; - }(); - //newton-raphson - floop{ - auto next_ret=(aret+v/aret)/2u; - if(abs(next_ret-aret) requires(has_epsilon) @@ -2888,13 +2894,13 @@ namespace math{ /*! 判断某数是否是素数,无预先检查以供其他素数相关函数快速调用. */ template [[nodiscard]]inline constexpr bool is_prime_num_no_pre_check(T a)noexcept{ - #line 415 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 421 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" T b=safe_arithmetic_cast(sqrt(a));//若一个数可以分解为两因数之积,其中一个因数必定≤其开方:反指数式减少遍历范围. - #line 427 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 433 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" for(T c=5u;c<=b;c+=6u)//遍历判断是否能被因数分解——不会有人看不懂吧? if((!mod(a,c))||(!mod(a,(c+2u)))) return false; - #line 436 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 442 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return true; } /*! 判断某数是否是素数 */ @@ -2907,10 +2913,10 @@ namespace math{ if(b<4) return true;//1和0也是prime,我不管. - #line 458 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 464 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if(mod(mod(b,6)-1u,4u)) return false; - #line 463 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 469 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return is_prime_num_no_pre_check(b); } /// 求小于或等于某数的素数 @@ -2969,13 +2975,13 @@ namespace math{ /// 已知当前array的size,求下一个合适的提前分配大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_array(size_T size)noexcept{ - #line 524 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 530 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(size*magic_number::gold_of_resize); } /// 已知当前hash table的size,求下一个合适的桶大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_hash(size_T size)noexcept{ - #line 533 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 539 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(get_prime_num_big_or_eq_than(size*magic_number::gold_of_resize)); } pop_msvc_warning(); @@ -3249,6 +3255,8 @@ using math::integer_log; using math::pow; using math::ceil; using math::floor; +using math::sqrt_to_new_epsilon; +using math::quick_sqrt; using math::sqrt; using math::trunc; using math::is_prime_num; @@ -3351,7 +3359,7 @@ namespace magic_number{ //我们可以将result看作Ai*sqrt_640320的和. auto magic_number = sqrt_640320; //计算新的sqrt_640320. - sqrt_640320 = sqrt(ufloat_t{640320u},new_epsilon); + sqrt_to_new_epsilon(sqrt_640320,ufloat_t{640320u},new_epsilon); magic_number /= sqrt_640320; //去除旧数据的影响. result /= magic_number; @@ -3394,9 +3402,9 @@ namespace math{ template [[nodiscard]]constexpr T arctan(T num, const to_unsigned_t&epsilon)noexcept{ - #line 955 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 963 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if constexpr(signed_type) - if (num < 0) return copy_as_negative(arctan(abs(num), epsilon)); + if (num < 0) return -arctan(abs(num), epsilon); if (num > 1) return pi_with_epsilon(epsilon)/2u - arctan(reciprocal(move(num)), epsilon); size_t i = 1; bool negation = false; // 取反 @@ -6119,7 +6127,7 @@ namespace note_n{ force_inline constexpr name##_t(T a)noexcept:value(a){}\ template\ force_inline constexpr name##_t(name##_ta)noexcept:value(a.value){}\ - force_inline constexpr operator T()noexcept{return value;}\ + force_inline explicit constexpr operator T()noexcept{return value;}\ force_inline constexpr T operator()()noexcept{return value;}\ };\ template\ @@ -6150,7 +6158,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr size_t size_of_array_like(T(&)[N])noexcept{return N;} template - [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list&a)noexcept{return a.size();} + [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list>&a)noexcept{return a.size();} enable_adl(begin_of_array_like); template @@ -6158,7 +6166,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr auto begin_of_array_like(T(&a)[N])noexcept{return addressof(a[0]);} template - [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list&a)noexcept{return a.begin();} + [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list>&a)noexcept{return a.begin();} enable_adl(end_of_array_like); template @@ -6187,6 +6195,8 @@ namespace array_like_n{ template constexpr bool is_array_like_for=strict_is_array_like_for||strict_is_array_like_for; + static_assert(is_array_like_for>); + template struct array_like_view_t{ typedef T* iterator; @@ -6217,6 +6227,7 @@ namespace array_like_n{ size_t _size=0; public: constexpr explicit array_like_view_t(T*a,size_t b)noexcept:_begin(a),_size(b){} + constexpr explicit array_like_view_t(T*a,note::size_t b)noexcept:array_like_view_t(a,b()){} template requires strict_is_array_like_for explicit constexpr_as_auto array_like_view_t(U&&a)noexcept_as(begin_of_array_like(a),size_of_array_like(a)):array_like_view_t(begin_of_array_like(a),size_of_array_like(a)){} constexpr array_like_view_t(const this_t&)noexcept=default; @@ -17622,7 +17633,16 @@ namespace array_n{ explicit array_t(note::size_t size,const T&elem)noexcept(get.nothrow<>){ _m=get[size.value](elem); } - #line 60 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base/container/array/defs.hpp" + // ::std::initializer_list的构造 + array_t(::std::initializer_list&&list)noexcept(get.as_array.nothrow<::std::initializer_list>){ + _m=get.as_array(array_like_view_t{list}); + } + // T[N]的构造 + template + array_t(T(&a)[N])noexcept(get.as_array.nothrow){ + _m=get.as_array(a); + } + #line 69 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base/container/array/defs.hpp" //template.as_array.able> U> template requires(get.as_array.able && type_info>!=type_info) array_t(U&&a)noexcept(get.as_array.nothrow){ @@ -17826,12 +17846,12 @@ namespace array_n{ template - [[nodiscard]]iterator find(U&&a)noexcept requires was_not_an_ill_form(in_range(declvalue(this_t),a)){ - return in_range(*this,a); + [[nodiscard]]iterator find(U&&a)noexcept{ + return in_range(a,array_like_view_t{*this}); } template - [[nodiscard]]const_iterator find(U&&a)const noexcept requires was_not_an_ill_form(in_range(declvalue(this_t),a)){ - return in_range(*this,a); + [[nodiscard]]const_iterator find(U&&a)const noexcept{ + return in_range(a,array_like_view_t{*this}); } }; template @@ -22115,8 +22135,8 @@ public: [[nodiscard]]friend ubigfloat reciprocal(const ubigfloat& a)noexcept{ return ubigfloat{a._denominator,a._numerator}; } - [[nodiscard]]friend ubigfloat reciprocal(ubigfloat&& a)noexcept{ - return ubigfloat{move(a._denominator),move(a._numerator)}; + [[nodiscard]]friend ubigfloat&& reciprocal(ubigfloat&& a)noexcept{ + return swap(a._denominator,a._numerator),move(a); } //friend get_numerator [[nodiscard]]friend const ubigint& get_numerator(const ubigfloat& a)noexcept{ @@ -22458,6 +22478,9 @@ class bigfloat; [[nodiscard]]bigfloat copy_as_negative(ubigfloat&&,bool sign=true)noexcept; using math::copy_as_negative;//避免可能的符号覆盖 +[[nodiscard]]inline bigfloat operator-(const ubigfloat&num)noexcept; +[[nodiscard]]inline bigfloat operator-(ubigfloat&&num)noexcept; + class bigfloat{ bool _is_negative=false; ubigfloat _num; @@ -22567,7 +22590,7 @@ public: return bigfloat{reciprocal(a._num), a._is_negative}; } [[nodiscard]]friend bigfloat&& reciprocal(bigfloat&& a)noexcept{ - a._num=reciprocal(move(a._num)); + discard=reciprocal(move(a._num));//swap it! return move(a); } //friend trunc @@ -22772,6 +22795,13 @@ public: } }; +[[nodiscard]]inline bigfloat operator-(const ubigfloat&num)noexcept{ + return copy_as_negative(num); +} +[[nodiscard]]inline bigfloat operator-(ubigfloat&&num)noexcept{ + return copy_as_negative(move(num)); +} + template concept bigfloat_cvref=type_info> == type_info; diff --git a/files/code_realm b/files/code_realm index 8a66726..42b4be7 100644 --- a/files/code_realm +++ b/files/code_realm @@ -2888,37 +2888,43 @@ namespace math{ template requires(has_epsilon) [[nodiscard]]force_inline constexpr T sqrt(const T&v)noexcept; template + inline constexpr T sqrt_to_new_epsilon(T&num,const T&v,const to_unsigned_t&epsilon)noexcept{ + //newton-raphson + floop{ + auto next_ret=(num+v/num)/2u; + const bool end=abs(next_ret-num) + [[nodiscard]]inline constexpr T quick_sqrt(const T&v)noexcept{ + if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking + if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 + if constexpr(type_info == type_info) + return union_cast(0x5F375A86-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + #if defined(_MSC_VER)//msvc上long double就是double + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + #elif defined(ELC_BASE_ENV_HAS_INT128) + return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); + #else + do_nothing;//可以寄了 + #endif + elseif constexpr(is_big_type) + return sqrt(static_cast(v)); + return v/2u; + } + template [[nodiscard]]inline constexpr T sqrt(const T&v,const to_unsigned_t&epsilon)noexcept{ if constexpr(has_NaN && has_inf) if(v < 0u || v >= arithmetic_type_info_prover::Inf()) return arithmetic_type_info_prover::NaN(); - T aret=exlambda()->T{ - if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking - if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 - if constexpr(type_info == type_info) - return union_cast(0x5F375A86-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - #if defined(_MSC_VER)//msvc上long double就是double - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - #elif defined(ELC_BASE_ENV_HAS_INT128) - return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); - #else - do_nothing;//可以寄了 - #endif - elseif constexpr(is_big_type) - return sqrt(static_cast(v)); - return v/2u; - }(); - //newton-raphson - floop{ - auto next_ret=(aret+v/aret)/2u; - if(abs(next_ret-aret) requires(has_epsilon) @@ -2932,13 +2938,13 @@ namespace math{ /*! 判断某数是否是素数,无预先检查以供其他素数相关函数快速调用. */ template [[nodiscard]]inline constexpr bool is_prime_num_no_pre_check(T a)noexcept{ - #line 415 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 421 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" T b=safe_arithmetic_cast(sqrt(a));//若一个数可以分解为两因数之积,其中一个因数必定≤其开方:反指数式减少遍历范围. - #line 427 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 433 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" for(T c=5u;c<=b;c+=6u)//遍历判断是否能被因数分解——不会有人看不懂吧? if((!mod(a,c))||(!mod(a,(c+2u)))) return false; - #line 436 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 442 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return true; } /*! 判断某数是否是素数 */ @@ -2951,10 +2957,10 @@ namespace math{ if(b<4) return true;//1和0也是prime,我不管. - #line 458 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 464 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if(mod(mod(b,6)-1u,4u)) return false; - #line 463 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 469 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return is_prime_num_no_pre_check(b); } /// 求小于或等于某数的素数 @@ -3013,13 +3019,13 @@ namespace math{ /// 已知当前array的size,求下一个合适的提前分配大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_array(size_T size)noexcept{ - #line 524 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 530 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(size*magic_number::gold_of_resize); } /// 已知当前hash table的size,求下一个合适的桶大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_hash(size_T size)noexcept{ - #line 533 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 539 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(get_prime_num_big_or_eq_than(size*magic_number::gold_of_resize)); } pop_msvc_warning(); @@ -3293,6 +3299,8 @@ using math::integer_log; using math::pow; using math::ceil; using math::floor; +using math::sqrt_to_new_epsilon; +using math::quick_sqrt; using math::sqrt; using math::trunc; using math::is_prime_num; @@ -3395,7 +3403,7 @@ namespace magic_number{ //我们可以将result看作Ai*sqrt_640320的和. auto magic_number = sqrt_640320; //计算新的sqrt_640320. - sqrt_640320 = sqrt(ufloat_t{640320u},new_epsilon); + sqrt_to_new_epsilon(sqrt_640320,ufloat_t{640320u},new_epsilon); magic_number /= sqrt_640320; //去除旧数据的影响. result /= magic_number; @@ -3438,9 +3446,9 @@ namespace math{ template [[nodiscard]]constexpr T arctan(T num, const to_unsigned_t&epsilon)noexcept{ - #line 955 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 963 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if constexpr(signed_type) - if (num < 0) return copy_as_negative(arctan(abs(num), epsilon)); + if (num < 0) return -arctan(abs(num), epsilon); if (num > 1) return pi_with_epsilon(epsilon)/2u - arctan(reciprocal(move(num)), epsilon); size_t i = 1; bool negation = false; // 取反 @@ -6163,7 +6171,7 @@ namespace note_n{ force_inline constexpr name##_t(T a)noexcept:value(a){}\ template\ force_inline constexpr name##_t(name##_ta)noexcept:value(a.value){}\ - force_inline constexpr operator T()noexcept{return value;}\ + force_inline explicit constexpr operator T()noexcept{return value;}\ force_inline constexpr T operator()()noexcept{return value;}\ };\ template\ @@ -6194,7 +6202,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr size_t size_of_array_like(T(&)[N])noexcept{return N;} template - [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list&a)noexcept{return a.size();} + [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list>&a)noexcept{return a.size();} enable_adl(begin_of_array_like); template @@ -6202,7 +6210,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr auto begin_of_array_like(T(&a)[N])noexcept{return addressof(a[0]);} template - [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list&a)noexcept{return a.begin();} + [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list>&a)noexcept{return a.begin();} enable_adl(end_of_array_like); template @@ -6231,6 +6239,8 @@ namespace array_like_n{ template constexpr bool is_array_like_for=strict_is_array_like_for||strict_is_array_like_for; + static_assert(is_array_like_for>); + template struct array_like_view_t{ typedef T* iterator; @@ -6261,6 +6271,7 @@ namespace array_like_n{ size_t _size=0; public: constexpr explicit array_like_view_t(T*a,size_t b)noexcept:_begin(a),_size(b){} + constexpr explicit array_like_view_t(T*a,note::size_t b)noexcept:array_like_view_t(a,b()){} template requires strict_is_array_like_for explicit constexpr_as_auto array_like_view_t(U&&a)noexcept_as(begin_of_array_like(a),size_of_array_like(a)):array_like_view_t(begin_of_array_like(a),size_of_array_like(a)){} constexpr array_like_view_t(const this_t&)noexcept=default; diff --git a/files/core b/files/core index 9cf8c54..0081884 100644 --- a/files/core +++ b/files/core @@ -2844,37 +2844,43 @@ namespace math{ template requires(has_epsilon) [[nodiscard]]force_inline constexpr T sqrt(const T&v)noexcept; template + inline constexpr T sqrt_to_new_epsilon(T&num,const T&v,const to_unsigned_t&epsilon)noexcept{ + //newton-raphson + floop{ + auto next_ret=(num+v/num)/2u; + const bool end=abs(next_ret-num) + [[nodiscard]]inline constexpr T quick_sqrt(const T&v)noexcept{ + if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking + if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 + if constexpr(type_info == type_info) + return union_cast(0x5F375A86-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + #if defined(_MSC_VER)//msvc上long double就是double + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + #elif defined(ELC_BASE_ENV_HAS_INT128) + return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); + #else + do_nothing;//可以寄了 + #endif + elseif constexpr(is_big_type) + return sqrt(static_cast(v)); + return v/2u; + } + template [[nodiscard]]inline constexpr T sqrt(const T&v,const to_unsigned_t&epsilon)noexcept{ if constexpr(has_NaN && has_inf) if(v < 0u || v >= arithmetic_type_info_prover::Inf()) return arithmetic_type_info_prover::NaN(); - T aret=exlambda()->T{ - if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking - if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 - if constexpr(type_info == type_info) - return union_cast(0x5F375A86-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - #if defined(_MSC_VER)//msvc上long double就是double - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - #elif defined(ELC_BASE_ENV_HAS_INT128) - return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); - #else - do_nothing;//可以寄了 - #endif - elseif constexpr(is_big_type) - return sqrt(static_cast(v)); - return v/2u; - }(); - //newton-raphson - floop{ - auto next_ret=(aret+v/aret)/2u; - if(abs(next_ret-aret) requires(has_epsilon) @@ -2888,13 +2894,13 @@ namespace math{ /*! 判断某数是否是素数,无预先检查以供其他素数相关函数快速调用. */ template [[nodiscard]]inline constexpr bool is_prime_num_no_pre_check(T a)noexcept{ - #line 415 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 421 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" T b=safe_arithmetic_cast(sqrt(a));//若一个数可以分解为两因数之积,其中一个因数必定≤其开方:反指数式减少遍历范围. - #line 427 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 433 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" for(T c=5u;c<=b;c+=6u)//遍历判断是否能被因数分解——不会有人看不懂吧? if((!mod(a,c))||(!mod(a,(c+2u)))) return false; - #line 436 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 442 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return true; } /*! 判断某数是否是素数 */ @@ -2907,10 +2913,10 @@ namespace math{ if(b<4) return true;//1和0也是prime,我不管. - #line 458 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 464 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if(mod(mod(b,6)-1u,4u)) return false; - #line 463 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 469 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return is_prime_num_no_pre_check(b); } /// 求小于或等于某数的素数 @@ -2969,13 +2975,13 @@ namespace math{ /// 已知当前array的size,求下一个合适的提前分配大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_array(size_T size)noexcept{ - #line 524 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 530 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(size*magic_number::gold_of_resize); } /// 已知当前hash table的size,求下一个合适的桶大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_hash(size_T size)noexcept{ - #line 533 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 539 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(get_prime_num_big_or_eq_than(size*magic_number::gold_of_resize)); } pop_msvc_warning(); @@ -3249,6 +3255,8 @@ using math::integer_log; using math::pow; using math::ceil; using math::floor; +using math::sqrt_to_new_epsilon; +using math::quick_sqrt; using math::sqrt; using math::trunc; using math::is_prime_num; @@ -3351,7 +3359,7 @@ namespace magic_number{ //我们可以将result看作Ai*sqrt_640320的和. auto magic_number = sqrt_640320; //计算新的sqrt_640320. - sqrt_640320 = sqrt(ufloat_t{640320u},new_epsilon); + sqrt_to_new_epsilon(sqrt_640320,ufloat_t{640320u},new_epsilon); magic_number /= sqrt_640320; //去除旧数据的影响. result /= magic_number; @@ -3394,9 +3402,9 @@ namespace math{ template [[nodiscard]]constexpr T arctan(T num, const to_unsigned_t&epsilon)noexcept{ - #line 955 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 963 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if constexpr(signed_type) - if (num < 0) return copy_as_negative(arctan(abs(num), epsilon)); + if (num < 0) return -arctan(abs(num), epsilon); if (num > 1) return pi_with_epsilon(epsilon)/2u - arctan(reciprocal(move(num)), epsilon); size_t i = 1; bool negation = false; // 取反 @@ -6119,7 +6127,7 @@ namespace note_n{ force_inline constexpr name##_t(T a)noexcept:value(a){}\ template\ force_inline constexpr name##_t(name##_ta)noexcept:value(a.value){}\ - force_inline constexpr operator T()noexcept{return value;}\ + force_inline explicit constexpr operator T()noexcept{return value;}\ force_inline constexpr T operator()()noexcept{return value;}\ };\ template\ @@ -6150,7 +6158,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr size_t size_of_array_like(T(&)[N])noexcept{return N;} template - [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list&a)noexcept{return a.size();} + [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list>&a)noexcept{return a.size();} enable_adl(begin_of_array_like); template @@ -6158,7 +6166,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr auto begin_of_array_like(T(&a)[N])noexcept{return addressof(a[0]);} template - [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list&a)noexcept{return a.begin();} + [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list>&a)noexcept{return a.begin();} enable_adl(end_of_array_like); template @@ -6187,6 +6195,8 @@ namespace array_like_n{ template constexpr bool is_array_like_for=strict_is_array_like_for||strict_is_array_like_for; + static_assert(is_array_like_for>); + template struct array_like_view_t{ typedef T* iterator; @@ -6217,6 +6227,7 @@ namespace array_like_n{ size_t _size=0; public: constexpr explicit array_like_view_t(T*a,size_t b)noexcept:_begin(a),_size(b){} + constexpr explicit array_like_view_t(T*a,note::size_t b)noexcept:array_like_view_t(a,b()){} template requires strict_is_array_like_for explicit constexpr_as_auto array_like_view_t(U&&a)noexcept_as(begin_of_array_like(a),size_of_array_like(a)):array_like_view_t(begin_of_array_like(a),size_of_array_like(a)){} constexpr array_like_view_t(const this_t&)noexcept=default; @@ -17622,7 +17633,16 @@ namespace array_n{ explicit array_t(note::size_t size,const T&elem)noexcept(get.nothrow<>){ _m=get[size.value](elem); } - #line 60 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base/container/array/defs.hpp" + // ::std::initializer_list的构造 + array_t(::std::initializer_list&&list)noexcept(get.as_array.nothrow<::std::initializer_list>){ + _m=get.as_array(array_like_view_t{list}); + } + // T[N]的构造 + template + array_t(T(&a)[N])noexcept(get.as_array.nothrow){ + _m=get.as_array(a); + } + #line 69 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base/container/array/defs.hpp" //template.as_array.able> U> template requires(get.as_array.able && type_info>!=type_info) array_t(U&&a)noexcept(get.as_array.nothrow){ @@ -17826,12 +17846,12 @@ namespace array_n{ template - [[nodiscard]]iterator find(U&&a)noexcept requires was_not_an_ill_form(in_range(declvalue(this_t),a)){ - return in_range(*this,a); + [[nodiscard]]iterator find(U&&a)noexcept{ + return in_range(a,array_like_view_t{*this}); } template - [[nodiscard]]const_iterator find(U&&a)const noexcept requires was_not_an_ill_form(in_range(declvalue(this_t),a)){ - return in_range(*this,a); + [[nodiscard]]const_iterator find(U&&a)const noexcept{ + return in_range(a,array_like_view_t{*this}); } }; template diff --git a/files/lib_loader b/files/lib_loader index 219785c..5bebbf3 100644 --- a/files/lib_loader +++ b/files/lib_loader @@ -2883,37 +2883,43 @@ namespace math{ template requires(has_epsilon) [[nodiscard]]force_inline constexpr T sqrt(const T&v)noexcept; template + inline constexpr T sqrt_to_new_epsilon(T&num,const T&v,const to_unsigned_t&epsilon)noexcept{ + //newton-raphson + floop{ + auto next_ret=(num+v/num)/2u; + const bool end=abs(next_ret-num) + [[nodiscard]]inline constexpr T quick_sqrt(const T&v)noexcept{ + if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking + if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 + if constexpr(type_info == type_info) + return union_cast(0x5F375A86-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + #if defined(_MSC_VER)//msvc上long double就是double + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + #elif defined(ELC_BASE_ENV_HAS_INT128) + return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); + #else + do_nothing;//可以寄了 + #endif + elseif constexpr(is_big_type) + return sqrt(static_cast(v)); + return v/2u; + } + template [[nodiscard]]inline constexpr T sqrt(const T&v,const to_unsigned_t&epsilon)noexcept{ if constexpr(has_NaN && has_inf) if(v < 0u || v >= arithmetic_type_info_prover::Inf()) return arithmetic_type_info_prover::NaN(); - T aret=exlambda()->T{ - if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking - if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 - if constexpr(type_info == type_info) - return union_cast(0x5F375A86-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - #if defined(_MSC_VER)//msvc上long double就是double - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - #elif defined(ELC_BASE_ENV_HAS_INT128) - return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); - #else - do_nothing;//可以寄了 - #endif - elseif constexpr(is_big_type) - return sqrt(static_cast(v)); - return v/2u; - }(); - //newton-raphson - floop{ - auto next_ret=(aret+v/aret)/2u; - if(abs(next_ret-aret) requires(has_epsilon) @@ -2927,13 +2933,13 @@ namespace math{ /*! 判断某数是否是素数,无预先检查以供其他素数相关函数快速调用. */ template [[nodiscard]]inline constexpr bool is_prime_num_no_pre_check(T a)noexcept{ - #line 415 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 421 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" T b=safe_arithmetic_cast(sqrt(a));//若一个数可以分解为两因数之积,其中一个因数必定≤其开方:反指数式减少遍历范围. - #line 427 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 433 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" for(T c=5u;c<=b;c+=6u)//遍历判断是否能被因数分解——不会有人看不懂吧? if((!mod(a,c))||(!mod(a,(c+2u)))) return false; - #line 436 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 442 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return true; } /*! 判断某数是否是素数 */ @@ -2946,10 +2952,10 @@ namespace math{ if(b<4) return true;//1和0也是prime,我不管. - #line 458 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 464 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if(mod(mod(b,6)-1u,4u)) return false; - #line 463 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 469 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return is_prime_num_no_pre_check(b); } /// 求小于或等于某数的素数 @@ -3008,13 +3014,13 @@ namespace math{ /// 已知当前array的size,求下一个合适的提前分配大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_array(size_T size)noexcept{ - #line 524 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 530 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(size*magic_number::gold_of_resize); } /// 已知当前hash table的size,求下一个合适的桶大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_hash(size_T size)noexcept{ - #line 533 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 539 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(get_prime_num_big_or_eq_than(size*magic_number::gold_of_resize)); } pop_msvc_warning(); @@ -3288,6 +3294,8 @@ using math::integer_log; using math::pow; using math::ceil; using math::floor; +using math::sqrt_to_new_epsilon; +using math::quick_sqrt; using math::sqrt; using math::trunc; using math::is_prime_num; @@ -3390,7 +3398,7 @@ namespace magic_number{ //我们可以将result看作Ai*sqrt_640320的和. auto magic_number = sqrt_640320; //计算新的sqrt_640320. - sqrt_640320 = sqrt(ufloat_t{640320u},new_epsilon); + sqrt_to_new_epsilon(sqrt_640320,ufloat_t{640320u},new_epsilon); magic_number /= sqrt_640320; //去除旧数据的影响. result /= magic_number; @@ -3433,9 +3441,9 @@ namespace math{ template [[nodiscard]]constexpr T arctan(T num, const to_unsigned_t&epsilon)noexcept{ - #line 955 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 963 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if constexpr(signed_type) - if (num < 0) return copy_as_negative(arctan(abs(num), epsilon)); + if (num < 0) return -arctan(abs(num), epsilon); if (num > 1) return pi_with_epsilon(epsilon)/2u - arctan(reciprocal(move(num)), epsilon); size_t i = 1; bool negation = false; // 取反 @@ -6158,7 +6166,7 @@ namespace note_n{ force_inline constexpr name##_t(T a)noexcept:value(a){}\ template\ force_inline constexpr name##_t(name##_ta)noexcept:value(a.value){}\ - force_inline constexpr operator T()noexcept{return value;}\ + force_inline explicit constexpr operator T()noexcept{return value;}\ force_inline constexpr T operator()()noexcept{return value;}\ };\ template\ @@ -6189,7 +6197,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr size_t size_of_array_like(T(&)[N])noexcept{return N;} template - [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list&a)noexcept{return a.size();} + [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list>&a)noexcept{return a.size();} enable_adl(begin_of_array_like); template @@ -6197,7 +6205,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr auto begin_of_array_like(T(&a)[N])noexcept{return addressof(a[0]);} template - [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list&a)noexcept{return a.begin();} + [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list>&a)noexcept{return a.begin();} enable_adl(end_of_array_like); template @@ -6226,6 +6234,8 @@ namespace array_like_n{ template constexpr bool is_array_like_for=strict_is_array_like_for||strict_is_array_like_for; + static_assert(is_array_like_for>); + template struct array_like_view_t{ typedef T* iterator; @@ -6256,6 +6266,7 @@ namespace array_like_n{ size_t _size=0; public: constexpr explicit array_like_view_t(T*a,size_t b)noexcept:_begin(a),_size(b){} + constexpr explicit array_like_view_t(T*a,note::size_t b)noexcept:array_like_view_t(a,b()){} template requires strict_is_array_like_for explicit constexpr_as_auto array_like_view_t(U&&a)noexcept_as(begin_of_array_like(a),size_of_array_like(a)):array_like_view_t(begin_of_array_like(a),size_of_array_like(a)){} constexpr array_like_view_t(const this_t&)noexcept=default; @@ -17661,7 +17672,16 @@ namespace array_n{ explicit array_t(note::size_t size,const T&elem)noexcept(get.nothrow<>){ _m=get[size.value](elem); } - #line 60 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base/container/array/defs.hpp" + // ::std::initializer_list的构造 + array_t(::std::initializer_list&&list)noexcept(get.as_array.nothrow<::std::initializer_list>){ + _m=get.as_array(array_like_view_t{list}); + } + // T[N]的构造 + template + array_t(T(&a)[N])noexcept(get.as_array.nothrow){ + _m=get.as_array(a); + } + #line 69 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base/container/array/defs.hpp" //template.as_array.able> U> template requires(get.as_array.able && type_info>!=type_info) array_t(U&&a)noexcept(get.as_array.nothrow){ @@ -17865,12 +17885,12 @@ namespace array_n{ template - [[nodiscard]]iterator find(U&&a)noexcept requires was_not_an_ill_form(in_range(declvalue(this_t),a)){ - return in_range(*this,a); + [[nodiscard]]iterator find(U&&a)noexcept{ + return in_range(a,array_like_view_t{*this}); } template - [[nodiscard]]const_iterator find(U&&a)const noexcept requires was_not_an_ill_form(in_range(declvalue(this_t),a)){ - return in_range(*this,a); + [[nodiscard]]const_iterator find(U&&a)const noexcept{ + return in_range(a,array_like_view_t{*this}); } }; template @@ -31255,8 +31275,8 @@ public: [[nodiscard]]friend ubigfloat reciprocal(const ubigfloat& a)noexcept{ return ubigfloat{a._denominator,a._numerator}; } - [[nodiscard]]friend ubigfloat reciprocal(ubigfloat&& a)noexcept{ - return ubigfloat{move(a._denominator),move(a._numerator)}; + [[nodiscard]]friend ubigfloat&& reciprocal(ubigfloat&& a)noexcept{ + return swap(a._denominator,a._numerator),move(a); } //friend get_numerator [[nodiscard]]friend const ubigint& get_numerator(const ubigfloat& a)noexcept{ @@ -31598,6 +31618,9 @@ class bigfloat; [[nodiscard]]bigfloat copy_as_negative(ubigfloat&&,bool sign=true)noexcept; using math::copy_as_negative;//避免可能的符号覆盖 +[[nodiscard]]inline bigfloat operator-(const ubigfloat&num)noexcept; +[[nodiscard]]inline bigfloat operator-(ubigfloat&&num)noexcept; + class bigfloat{ bool _is_negative=false; ubigfloat _num; @@ -31707,7 +31730,7 @@ public: return bigfloat{reciprocal(a._num), a._is_negative}; } [[nodiscard]]friend bigfloat&& reciprocal(bigfloat&& a)noexcept{ - a._num=reciprocal(move(a._num)); + discard=reciprocal(move(a._num));//swap it! return move(a); } //friend trunc @@ -31912,6 +31935,13 @@ public: } }; +[[nodiscard]]inline bigfloat operator-(const ubigfloat&num)noexcept{ + return copy_as_negative(num); +} +[[nodiscard]]inline bigfloat operator-(ubigfloat&&num)noexcept{ + return copy_as_negative(move(num)); +} + template concept bigfloat_cvref=type_info> == type_info; diff --git a/files/log b/files/log index 84fee06..f78b7d6 100644 --- a/files/log +++ b/files/log @@ -2884,37 +2884,43 @@ namespace math{ template requires(has_epsilon) [[nodiscard]]force_inline constexpr T sqrt(const T&v)noexcept; template + inline constexpr T sqrt_to_new_epsilon(T&num,const T&v,const to_unsigned_t&epsilon)noexcept{ + //newton-raphson + floop{ + auto next_ret=(num+v/num)/2u; + const bool end=abs(next_ret-num) + [[nodiscard]]inline constexpr T quick_sqrt(const T&v)noexcept{ + if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking + if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 + if constexpr(type_info == type_info) + return union_cast(0x5F375A86-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + #if defined(_MSC_VER)//msvc上long double就是double + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + #elif defined(ELC_BASE_ENV_HAS_INT128) + return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); + #else + do_nothing;//可以寄了 + #endif + elseif constexpr(is_big_type) + return sqrt(static_cast(v)); + return v/2u; + } + template [[nodiscard]]inline constexpr T sqrt(const T&v,const to_unsigned_t&epsilon)noexcept{ if constexpr(has_NaN && has_inf) if(v < 0u || v >= arithmetic_type_info_prover::Inf()) return arithmetic_type_info_prover::NaN(); - T aret=exlambda()->T{ - if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking - if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 - if constexpr(type_info == type_info) - return union_cast(0x5F375A86-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - #if defined(_MSC_VER)//msvc上long double就是double - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - #elif defined(ELC_BASE_ENV_HAS_INT128) - return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); - #else - do_nothing;//可以寄了 - #endif - elseif constexpr(is_big_type) - return sqrt(static_cast(v)); - return v/2u; - }(); - //newton-raphson - floop{ - auto next_ret=(aret+v/aret)/2u; - if(abs(next_ret-aret) requires(has_epsilon) @@ -2928,13 +2934,13 @@ namespace math{ /*! 判断某数是否是素数,无预先检查以供其他素数相关函数快速调用. */ template [[nodiscard]]inline constexpr bool is_prime_num_no_pre_check(T a)noexcept{ - #line 415 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 421 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" T b=safe_arithmetic_cast(sqrt(a));//若一个数可以分解为两因数之积,其中一个因数必定≤其开方:反指数式减少遍历范围. - #line 427 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 433 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" for(T c=5u;c<=b;c+=6u)//遍历判断是否能被因数分解——不会有人看不懂吧? if((!mod(a,c))||(!mod(a,(c+2u)))) return false; - #line 436 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 442 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return true; } /*! 判断某数是否是素数 */ @@ -2947,10 +2953,10 @@ namespace math{ if(b<4) return true;//1和0也是prime,我不管. - #line 458 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 464 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if(mod(mod(b,6)-1u,4u)) return false; - #line 463 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 469 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return is_prime_num_no_pre_check(b); } /// 求小于或等于某数的素数 @@ -3009,13 +3015,13 @@ namespace math{ /// 已知当前array的size,求下一个合适的提前分配大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_array(size_T size)noexcept{ - #line 524 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 530 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(size*magic_number::gold_of_resize); } /// 已知当前hash table的size,求下一个合适的桶大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_hash(size_T size)noexcept{ - #line 533 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 539 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(get_prime_num_big_or_eq_than(size*magic_number::gold_of_resize)); } pop_msvc_warning(); @@ -3289,6 +3295,8 @@ using math::integer_log; using math::pow; using math::ceil; using math::floor; +using math::sqrt_to_new_epsilon; +using math::quick_sqrt; using math::sqrt; using math::trunc; using math::is_prime_num; @@ -3391,7 +3399,7 @@ namespace magic_number{ //我们可以将result看作Ai*sqrt_640320的和. auto magic_number = sqrt_640320; //计算新的sqrt_640320. - sqrt_640320 = sqrt(ufloat_t{640320u},new_epsilon); + sqrt_to_new_epsilon(sqrt_640320,ufloat_t{640320u},new_epsilon); magic_number /= sqrt_640320; //去除旧数据的影响. result /= magic_number; @@ -3434,9 +3442,9 @@ namespace math{ template [[nodiscard]]constexpr T arctan(T num, const to_unsigned_t&epsilon)noexcept{ - #line 955 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 963 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if constexpr(signed_type) - if (num < 0) return copy_as_negative(arctan(abs(num), epsilon)); + if (num < 0) return -arctan(abs(num), epsilon); if (num > 1) return pi_with_epsilon(epsilon)/2u - arctan(reciprocal(move(num)), epsilon); size_t i = 1; bool negation = false; // 取反 @@ -6159,7 +6167,7 @@ namespace note_n{ force_inline constexpr name##_t(T a)noexcept:value(a){}\ template\ force_inline constexpr name##_t(name##_ta)noexcept:value(a.value){}\ - force_inline constexpr operator T()noexcept{return value;}\ + force_inline explicit constexpr operator T()noexcept{return value;}\ force_inline constexpr T operator()()noexcept{return value;}\ };\ template\ @@ -6190,7 +6198,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr size_t size_of_array_like(T(&)[N])noexcept{return N;} template - [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list&a)noexcept{return a.size();} + [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list>&a)noexcept{return a.size();} enable_adl(begin_of_array_like); template @@ -6198,7 +6206,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr auto begin_of_array_like(T(&a)[N])noexcept{return addressof(a[0]);} template - [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list&a)noexcept{return a.begin();} + [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list>&a)noexcept{return a.begin();} enable_adl(end_of_array_like); template @@ -6227,6 +6235,8 @@ namespace array_like_n{ template constexpr bool is_array_like_for=strict_is_array_like_for||strict_is_array_like_for; + static_assert(is_array_like_for>); + template struct array_like_view_t{ typedef T* iterator; @@ -6257,6 +6267,7 @@ namespace array_like_n{ size_t _size=0; public: constexpr explicit array_like_view_t(T*a,size_t b)noexcept:_begin(a),_size(b){} + constexpr explicit array_like_view_t(T*a,note::size_t b)noexcept:array_like_view_t(a,b()){} template requires strict_is_array_like_for explicit constexpr_as_auto array_like_view_t(U&&a)noexcept_as(begin_of_array_like(a),size_of_array_like(a)):array_like_view_t(begin_of_array_like(a),size_of_array_like(a)){} constexpr array_like_view_t(const this_t&)noexcept=default; @@ -17662,7 +17673,16 @@ namespace array_n{ explicit array_t(note::size_t size,const T&elem)noexcept(get.nothrow<>){ _m=get[size.value](elem); } - #line 60 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base/container/array/defs.hpp" + // ::std::initializer_list的构造 + array_t(::std::initializer_list&&list)noexcept(get.as_array.nothrow<::std::initializer_list>){ + _m=get.as_array(array_like_view_t{list}); + } + // T[N]的构造 + template + array_t(T(&a)[N])noexcept(get.as_array.nothrow){ + _m=get.as_array(a); + } + #line 69 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base/container/array/defs.hpp" //template.as_array.able> U> template requires(get.as_array.able && type_info>!=type_info) array_t(U&&a)noexcept(get.as_array.nothrow){ @@ -17866,12 +17886,12 @@ namespace array_n{ template - [[nodiscard]]iterator find(U&&a)noexcept requires was_not_an_ill_form(in_range(declvalue(this_t),a)){ - return in_range(*this,a); + [[nodiscard]]iterator find(U&&a)noexcept{ + return in_range(a,array_like_view_t{*this}); } template - [[nodiscard]]const_iterator find(U&&a)const noexcept requires was_not_an_ill_form(in_range(declvalue(this_t),a)){ - return in_range(*this,a); + [[nodiscard]]const_iterator find(U&&a)const noexcept{ + return in_range(a,array_like_view_t{*this}); } }; template diff --git a/files/namespace b/files/namespace index 817f219..39e5f2f 100644 --- a/files/namespace +++ b/files/namespace @@ -2883,37 +2883,43 @@ namespace math{ template requires(has_epsilon) [[nodiscard]]force_inline constexpr T sqrt(const T&v)noexcept; template + inline constexpr T sqrt_to_new_epsilon(T&num,const T&v,const to_unsigned_t&epsilon)noexcept{ + //newton-raphson + floop{ + auto next_ret=(num+v/num)/2u; + const bool end=abs(next_ret-num) + [[nodiscard]]inline constexpr T quick_sqrt(const T&v)noexcept{ + if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking + if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 + if constexpr(type_info == type_info) + return union_cast(0x5F375A86-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + #if defined(_MSC_VER)//msvc上long double就是double + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + #elif defined(ELC_BASE_ENV_HAS_INT128) + return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); + #else + do_nothing;//可以寄了 + #endif + elseif constexpr(is_big_type) + return sqrt(static_cast(v)); + return v/2u; + } + template [[nodiscard]]inline constexpr T sqrt(const T&v,const to_unsigned_t&epsilon)noexcept{ if constexpr(has_NaN && has_inf) if(v < 0u || v >= arithmetic_type_info_prover::Inf()) return arithmetic_type_info_prover::NaN(); - T aret=exlambda()->T{ - if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking - if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 - if constexpr(type_info == type_info) - return union_cast(0x5F375A86-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - #if defined(_MSC_VER)//msvc上long double就是double - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - #elif defined(ELC_BASE_ENV_HAS_INT128) - return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); - #else - do_nothing;//可以寄了 - #endif - elseif constexpr(is_big_type) - return sqrt(static_cast(v)); - return v/2u; - }(); - //newton-raphson - floop{ - auto next_ret=(aret+v/aret)/2u; - if(abs(next_ret-aret) requires(has_epsilon) @@ -2927,13 +2933,13 @@ namespace math{ /*! 判断某数是否是素数,无预先检查以供其他素数相关函数快速调用. */ template [[nodiscard]]inline constexpr bool is_prime_num_no_pre_check(T a)noexcept{ - #line 415 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 421 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" T b=safe_arithmetic_cast(sqrt(a));//若一个数可以分解为两因数之积,其中一个因数必定≤其开方:反指数式减少遍历范围. - #line 427 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 433 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" for(T c=5u;c<=b;c+=6u)//遍历判断是否能被因数分解——不会有人看不懂吧? if((!mod(a,c))||(!mod(a,(c+2u)))) return false; - #line 436 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 442 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return true; } /*! 判断某数是否是素数 */ @@ -2946,10 +2952,10 @@ namespace math{ if(b<4) return true;//1和0也是prime,我不管. - #line 458 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 464 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if(mod(mod(b,6)-1u,4u)) return false; - #line 463 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 469 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return is_prime_num_no_pre_check(b); } /// 求小于或等于某数的素数 @@ -3008,13 +3014,13 @@ namespace math{ /// 已知当前array的size,求下一个合适的提前分配大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_array(size_T size)noexcept{ - #line 524 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 530 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(size*magic_number::gold_of_resize); } /// 已知当前hash table的size,求下一个合适的桶大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_hash(size_T size)noexcept{ - #line 533 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 539 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(get_prime_num_big_or_eq_than(size*magic_number::gold_of_resize)); } pop_msvc_warning(); @@ -3288,6 +3294,8 @@ using math::integer_log; using math::pow; using math::ceil; using math::floor; +using math::sqrt_to_new_epsilon; +using math::quick_sqrt; using math::sqrt; using math::trunc; using math::is_prime_num; @@ -3390,7 +3398,7 @@ namespace magic_number{ //我们可以将result看作Ai*sqrt_640320的和. auto magic_number = sqrt_640320; //计算新的sqrt_640320. - sqrt_640320 = sqrt(ufloat_t{640320u},new_epsilon); + sqrt_to_new_epsilon(sqrt_640320,ufloat_t{640320u},new_epsilon); magic_number /= sqrt_640320; //去除旧数据的影响. result /= magic_number; @@ -3433,9 +3441,9 @@ namespace math{ template [[nodiscard]]constexpr T arctan(T num, const to_unsigned_t&epsilon)noexcept{ - #line 955 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 963 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if constexpr(signed_type) - if (num < 0) return copy_as_negative(arctan(abs(num), epsilon)); + if (num < 0) return -arctan(abs(num), epsilon); if (num > 1) return pi_with_epsilon(epsilon)/2u - arctan(reciprocal(move(num)), epsilon); size_t i = 1; bool negation = false; // 取反 @@ -6158,7 +6166,7 @@ namespace note_n{ force_inline constexpr name##_t(T a)noexcept:value(a){}\ template\ force_inline constexpr name##_t(name##_ta)noexcept:value(a.value){}\ - force_inline constexpr operator T()noexcept{return value;}\ + force_inline explicit constexpr operator T()noexcept{return value;}\ force_inline constexpr T operator()()noexcept{return value;}\ };\ template\ @@ -6189,7 +6197,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr size_t size_of_array_like(T(&)[N])noexcept{return N;} template - [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list&a)noexcept{return a.size();} + [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list>&a)noexcept{return a.size();} enable_adl(begin_of_array_like); template @@ -6197,7 +6205,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr auto begin_of_array_like(T(&a)[N])noexcept{return addressof(a[0]);} template - [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list&a)noexcept{return a.begin();} + [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list>&a)noexcept{return a.begin();} enable_adl(end_of_array_like); template @@ -6226,6 +6234,8 @@ namespace array_like_n{ template constexpr bool is_array_like_for=strict_is_array_like_for||strict_is_array_like_for; + static_assert(is_array_like_for>); + template struct array_like_view_t{ typedef T* iterator; @@ -6256,6 +6266,7 @@ namespace array_like_n{ size_t _size=0; public: constexpr explicit array_like_view_t(T*a,size_t b)noexcept:_begin(a),_size(b){} + constexpr explicit array_like_view_t(T*a,note::size_t b)noexcept:array_like_view_t(a,b()){} template requires strict_is_array_like_for explicit constexpr_as_auto array_like_view_t(U&&a)noexcept_as(begin_of_array_like(a),size_of_array_like(a)):array_like_view_t(begin_of_array_like(a),size_of_array_like(a)){} constexpr array_like_view_t(const this_t&)noexcept=default; @@ -17661,7 +17672,16 @@ namespace array_n{ explicit array_t(note::size_t size,const T&elem)noexcept(get.nothrow<>){ _m=get[size.value](elem); } - #line 60 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base/container/array/defs.hpp" + // ::std::initializer_list的构造 + array_t(::std::initializer_list&&list)noexcept(get.as_array.nothrow<::std::initializer_list>){ + _m=get.as_array(array_like_view_t{list}); + } + // T[N]的构造 + template + array_t(T(&a)[N])noexcept(get.as_array.nothrow){ + _m=get.as_array(a); + } + #line 69 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base/container/array/defs.hpp" //template.as_array.able> U> template requires(get.as_array.able && type_info>!=type_info) array_t(U&&a)noexcept(get.as_array.nothrow){ @@ -17865,12 +17885,12 @@ namespace array_n{ template - [[nodiscard]]iterator find(U&&a)noexcept requires was_not_an_ill_form(in_range(declvalue(this_t),a)){ - return in_range(*this,a); + [[nodiscard]]iterator find(U&&a)noexcept{ + return in_range(a,array_like_view_t{*this}); } template - [[nodiscard]]const_iterator find(U&&a)const noexcept requires was_not_an_ill_form(in_range(declvalue(this_t),a)){ - return in_range(*this,a); + [[nodiscard]]const_iterator find(U&&a)const noexcept{ + return in_range(a,array_like_view_t{*this}); } }; template diff --git a/files/numerical_representation b/files/numerical_representation index bee4815..d7fa70a 100644 --- a/files/numerical_representation +++ b/files/numerical_representation @@ -2883,37 +2883,43 @@ namespace math{ template requires(has_epsilon) [[nodiscard]]force_inline constexpr T sqrt(const T&v)noexcept; template + inline constexpr T sqrt_to_new_epsilon(T&num,const T&v,const to_unsigned_t&epsilon)noexcept{ + //newton-raphson + floop{ + auto next_ret=(num+v/num)/2u; + const bool end=abs(next_ret-num) + [[nodiscard]]inline constexpr T quick_sqrt(const T&v)noexcept{ + if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking + if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 + if constexpr(type_info == type_info) + return union_cast(0x5F375A86-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + #if defined(_MSC_VER)//msvc上long double就是double + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + #elif defined(ELC_BASE_ENV_HAS_INT128) + return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); + #else + do_nothing;//可以寄了 + #endif + elseif constexpr(is_big_type) + return sqrt(static_cast(v)); + return v/2u; + } + template [[nodiscard]]inline constexpr T sqrt(const T&v,const to_unsigned_t&epsilon)noexcept{ if constexpr(has_NaN && has_inf) if(v < 0u || v >= arithmetic_type_info_prover::Inf()) return arithmetic_type_info_prover::NaN(); - T aret=exlambda()->T{ - if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking - if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 - if constexpr(type_info == type_info) - return union_cast(0x5F375A86-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - #if defined(_MSC_VER)//msvc上long double就是double - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - #elif defined(ELC_BASE_ENV_HAS_INT128) - return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); - #else - do_nothing;//可以寄了 - #endif - elseif constexpr(is_big_type) - return sqrt(static_cast(v)); - return v/2u; - }(); - //newton-raphson - floop{ - auto next_ret=(aret+v/aret)/2u; - if(abs(next_ret-aret) requires(has_epsilon) @@ -2927,13 +2933,13 @@ namespace math{ /*! 判断某数是否是素数,无预先检查以供其他素数相关函数快速调用. */ template [[nodiscard]]inline constexpr bool is_prime_num_no_pre_check(T a)noexcept{ - #line 415 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 421 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" T b=safe_arithmetic_cast(sqrt(a));//若一个数可以分解为两因数之积,其中一个因数必定≤其开方:反指数式减少遍历范围. - #line 427 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 433 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" for(T c=5u;c<=b;c+=6u)//遍历判断是否能被因数分解——不会有人看不懂吧? if((!mod(a,c))||(!mod(a,(c+2u)))) return false; - #line 436 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 442 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return true; } /*! 判断某数是否是素数 */ @@ -2946,10 +2952,10 @@ namespace math{ if(b<4) return true;//1和0也是prime,我不管. - #line 458 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 464 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if(mod(mod(b,6)-1u,4u)) return false; - #line 463 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 469 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return is_prime_num_no_pre_check(b); } /// 求小于或等于某数的素数 @@ -3008,13 +3014,13 @@ namespace math{ /// 已知当前array的size,求下一个合适的提前分配大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_array(size_T size)noexcept{ - #line 524 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 530 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(size*magic_number::gold_of_resize); } /// 已知当前hash table的size,求下一个合适的桶大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_hash(size_T size)noexcept{ - #line 533 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 539 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(get_prime_num_big_or_eq_than(size*magic_number::gold_of_resize)); } pop_msvc_warning(); @@ -3288,6 +3294,8 @@ using math::integer_log; using math::pow; using math::ceil; using math::floor; +using math::sqrt_to_new_epsilon; +using math::quick_sqrt; using math::sqrt; using math::trunc; using math::is_prime_num; @@ -3390,7 +3398,7 @@ namespace magic_number{ //我们可以将result看作Ai*sqrt_640320的和. auto magic_number = sqrt_640320; //计算新的sqrt_640320. - sqrt_640320 = sqrt(ufloat_t{640320u},new_epsilon); + sqrt_to_new_epsilon(sqrt_640320,ufloat_t{640320u},new_epsilon); magic_number /= sqrt_640320; //去除旧数据的影响. result /= magic_number; @@ -3433,9 +3441,9 @@ namespace math{ template [[nodiscard]]constexpr T arctan(T num, const to_unsigned_t&epsilon)noexcept{ - #line 955 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 963 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if constexpr(signed_type) - if (num < 0) return copy_as_negative(arctan(abs(num), epsilon)); + if (num < 0) return -arctan(abs(num), epsilon); if (num > 1) return pi_with_epsilon(epsilon)/2u - arctan(reciprocal(move(num)), epsilon); size_t i = 1; bool negation = false; // 取反 @@ -6158,7 +6166,7 @@ namespace note_n{ force_inline constexpr name##_t(T a)noexcept:value(a){}\ template\ force_inline constexpr name##_t(name##_ta)noexcept:value(a.value){}\ - force_inline constexpr operator T()noexcept{return value;}\ + force_inline explicit constexpr operator T()noexcept{return value;}\ force_inline constexpr T operator()()noexcept{return value;}\ };\ template\ @@ -6189,7 +6197,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr size_t size_of_array_like(T(&)[N])noexcept{return N;} template - [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list&a)noexcept{return a.size();} + [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list>&a)noexcept{return a.size();} enable_adl(begin_of_array_like); template @@ -6197,7 +6205,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr auto begin_of_array_like(T(&a)[N])noexcept{return addressof(a[0]);} template - [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list&a)noexcept{return a.begin();} + [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list>&a)noexcept{return a.begin();} enable_adl(end_of_array_like); template @@ -6226,6 +6234,8 @@ namespace array_like_n{ template constexpr bool is_array_like_for=strict_is_array_like_for||strict_is_array_like_for; + static_assert(is_array_like_for>); + template struct array_like_view_t{ typedef T* iterator; @@ -6256,6 +6266,7 @@ namespace array_like_n{ size_t _size=0; public: constexpr explicit array_like_view_t(T*a,size_t b)noexcept:_begin(a),_size(b){} + constexpr explicit array_like_view_t(T*a,note::size_t b)noexcept:array_like_view_t(a,b()){} template requires strict_is_array_like_for explicit constexpr_as_auto array_like_view_t(U&&a)noexcept_as(begin_of_array_like(a),size_of_array_like(a)):array_like_view_t(begin_of_array_like(a),size_of_array_like(a)){} constexpr array_like_view_t(const this_t&)noexcept=default; @@ -17661,7 +17672,16 @@ namespace array_n{ explicit array_t(note::size_t size,const T&elem)noexcept(get.nothrow<>){ _m=get[size.value](elem); } - #line 60 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base/container/array/defs.hpp" + // ::std::initializer_list的构造 + array_t(::std::initializer_list&&list)noexcept(get.as_array.nothrow<::std::initializer_list>){ + _m=get.as_array(array_like_view_t{list}); + } + // T[N]的构造 + template + array_t(T(&a)[N])noexcept(get.as_array.nothrow){ + _m=get.as_array(a); + } + #line 69 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base/container/array/defs.hpp" //template.as_array.able> U> template requires(get.as_array.able && type_info>!=type_info) array_t(U&&a)noexcept(get.as_array.nothrow){ @@ -17865,12 +17885,12 @@ namespace array_n{ template - [[nodiscard]]iterator find(U&&a)noexcept requires was_not_an_ill_form(in_range(declvalue(this_t),a)){ - return in_range(*this,a); + [[nodiscard]]iterator find(U&&a)noexcept{ + return in_range(a,array_like_view_t{*this}); } template - [[nodiscard]]const_iterator find(U&&a)const noexcept requires was_not_an_ill_form(in_range(declvalue(this_t),a)){ - return in_range(*this,a); + [[nodiscard]]const_iterator find(U&&a)const noexcept{ + return in_range(a,array_like_view_t{*this}); } }; template @@ -31081,8 +31101,8 @@ public: [[nodiscard]]friend ubigfloat reciprocal(const ubigfloat& a)noexcept{ return ubigfloat{a._denominator,a._numerator}; } - [[nodiscard]]friend ubigfloat reciprocal(ubigfloat&& a)noexcept{ - return ubigfloat{move(a._denominator),move(a._numerator)}; + [[nodiscard]]friend ubigfloat&& reciprocal(ubigfloat&& a)noexcept{ + return swap(a._denominator,a._numerator),move(a); } //friend get_numerator [[nodiscard]]friend const ubigint& get_numerator(const ubigfloat& a)noexcept{ @@ -31424,6 +31444,9 @@ class bigfloat; [[nodiscard]]bigfloat copy_as_negative(ubigfloat&&,bool sign=true)noexcept; using math::copy_as_negative;//避免可能的符号覆盖 +[[nodiscard]]inline bigfloat operator-(const ubigfloat&num)noexcept; +[[nodiscard]]inline bigfloat operator-(ubigfloat&&num)noexcept; + class bigfloat{ bool _is_negative=false; ubigfloat _num; @@ -31533,7 +31556,7 @@ public: return bigfloat{reciprocal(a._num), a._is_negative}; } [[nodiscard]]friend bigfloat&& reciprocal(bigfloat&& a)noexcept{ - a._num=reciprocal(move(a._num)); + discard=reciprocal(move(a._num));//swap it! return move(a); } //friend trunc @@ -31738,6 +31761,13 @@ public: } }; +[[nodiscard]]inline bigfloat operator-(const ubigfloat&num)noexcept{ + return copy_as_negative(num); +} +[[nodiscard]]inline bigfloat operator-(ubigfloat&&num)noexcept{ + return copy_as_negative(move(num)); +} + template concept bigfloat_cvref=type_info> == type_info; diff --git a/files/package_symbol_loader b/files/package_symbol_loader index c4c4712..f9f217f 100644 --- a/files/package_symbol_loader +++ b/files/package_symbol_loader @@ -2883,37 +2883,43 @@ namespace math{ template requires(has_epsilon) [[nodiscard]]force_inline constexpr T sqrt(const T&v)noexcept; template + inline constexpr T sqrt_to_new_epsilon(T&num,const T&v,const to_unsigned_t&epsilon)noexcept{ + //newton-raphson + floop{ + auto next_ret=(num+v/num)/2u; + const bool end=abs(next_ret-num) + [[nodiscard]]inline constexpr T quick_sqrt(const T&v)noexcept{ + if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking + if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 + if constexpr(type_info == type_info) + return union_cast(0x5F375A86-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + #if defined(_MSC_VER)//msvc上long double就是double + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + #elif defined(ELC_BASE_ENV_HAS_INT128) + return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); + #else + do_nothing;//可以寄了 + #endif + elseif constexpr(is_big_type) + return sqrt(static_cast(v)); + return v/2u; + } + template [[nodiscard]]inline constexpr T sqrt(const T&v,const to_unsigned_t&epsilon)noexcept{ if constexpr(has_NaN && has_inf) if(v < 0u || v >= arithmetic_type_info_prover::Inf()) return arithmetic_type_info_prover::NaN(); - T aret=exlambda()->T{ - if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking - if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 - if constexpr(type_info == type_info) - return union_cast(0x5F375A86-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - #if defined(_MSC_VER)//msvc上long double就是double - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - #elif defined(ELC_BASE_ENV_HAS_INT128) - return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); - #else - do_nothing;//可以寄了 - #endif - elseif constexpr(is_big_type) - return sqrt(static_cast(v)); - return v/2u; - }(); - //newton-raphson - floop{ - auto next_ret=(aret+v/aret)/2u; - if(abs(next_ret-aret) requires(has_epsilon) @@ -2927,13 +2933,13 @@ namespace math{ /*! 判断某数是否是素数,无预先检查以供其他素数相关函数快速调用. */ template [[nodiscard]]inline constexpr bool is_prime_num_no_pre_check(T a)noexcept{ - #line 415 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 421 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" T b=safe_arithmetic_cast(sqrt(a));//若一个数可以分解为两因数之积,其中一个因数必定≤其开方:反指数式减少遍历范围. - #line 427 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 433 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" for(T c=5u;c<=b;c+=6u)//遍历判断是否能被因数分解——不会有人看不懂吧? if((!mod(a,c))||(!mod(a,(c+2u)))) return false; - #line 436 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 442 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return true; } /*! 判断某数是否是素数 */ @@ -2946,10 +2952,10 @@ namespace math{ if(b<4) return true;//1和0也是prime,我不管. - #line 458 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 464 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if(mod(mod(b,6)-1u,4u)) return false; - #line 463 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 469 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return is_prime_num_no_pre_check(b); } /// 求小于或等于某数的素数 @@ -3008,13 +3014,13 @@ namespace math{ /// 已知当前array的size,求下一个合适的提前分配大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_array(size_T size)noexcept{ - #line 524 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 530 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(size*magic_number::gold_of_resize); } /// 已知当前hash table的size,求下一个合适的桶大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_hash(size_T size)noexcept{ - #line 533 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 539 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(get_prime_num_big_or_eq_than(size*magic_number::gold_of_resize)); } pop_msvc_warning(); @@ -3288,6 +3294,8 @@ using math::integer_log; using math::pow; using math::ceil; using math::floor; +using math::sqrt_to_new_epsilon; +using math::quick_sqrt; using math::sqrt; using math::trunc; using math::is_prime_num; @@ -3390,7 +3398,7 @@ namespace magic_number{ //我们可以将result看作Ai*sqrt_640320的和. auto magic_number = sqrt_640320; //计算新的sqrt_640320. - sqrt_640320 = sqrt(ufloat_t{640320u},new_epsilon); + sqrt_to_new_epsilon(sqrt_640320,ufloat_t{640320u},new_epsilon); magic_number /= sqrt_640320; //去除旧数据的影响. result /= magic_number; @@ -3433,9 +3441,9 @@ namespace math{ template [[nodiscard]]constexpr T arctan(T num, const to_unsigned_t&epsilon)noexcept{ - #line 955 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 963 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if constexpr(signed_type) - if (num < 0) return copy_as_negative(arctan(abs(num), epsilon)); + if (num < 0) return -arctan(abs(num), epsilon); if (num > 1) return pi_with_epsilon(epsilon)/2u - arctan(reciprocal(move(num)), epsilon); size_t i = 1; bool negation = false; // 取反 @@ -6158,7 +6166,7 @@ namespace note_n{ force_inline constexpr name##_t(T a)noexcept:value(a){}\ template\ force_inline constexpr name##_t(name##_ta)noexcept:value(a.value){}\ - force_inline constexpr operator T()noexcept{return value;}\ + force_inline explicit constexpr operator T()noexcept{return value;}\ force_inline constexpr T operator()()noexcept{return value;}\ };\ template\ @@ -6189,7 +6197,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr size_t size_of_array_like(T(&)[N])noexcept{return N;} template - [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list&a)noexcept{return a.size();} + [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list>&a)noexcept{return a.size();} enable_adl(begin_of_array_like); template @@ -6197,7 +6205,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr auto begin_of_array_like(T(&a)[N])noexcept{return addressof(a[0]);} template - [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list&a)noexcept{return a.begin();} + [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list>&a)noexcept{return a.begin();} enable_adl(end_of_array_like); template @@ -6226,6 +6234,8 @@ namespace array_like_n{ template constexpr bool is_array_like_for=strict_is_array_like_for||strict_is_array_like_for; + static_assert(is_array_like_for>); + template struct array_like_view_t{ typedef T* iterator; @@ -6256,6 +6266,7 @@ namespace array_like_n{ size_t _size=0; public: constexpr explicit array_like_view_t(T*a,size_t b)noexcept:_begin(a),_size(b){} + constexpr explicit array_like_view_t(T*a,note::size_t b)noexcept:array_like_view_t(a,b()){} template requires strict_is_array_like_for explicit constexpr_as_auto array_like_view_t(U&&a)noexcept_as(begin_of_array_like(a),size_of_array_like(a)):array_like_view_t(begin_of_array_like(a),size_of_array_like(a)){} constexpr array_like_view_t(const this_t&)noexcept=default; @@ -17661,7 +17672,16 @@ namespace array_n{ explicit array_t(note::size_t size,const T&elem)noexcept(get.nothrow<>){ _m=get[size.value](elem); } - #line 60 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base/container/array/defs.hpp" + // ::std::initializer_list的构造 + array_t(::std::initializer_list&&list)noexcept(get.as_array.nothrow<::std::initializer_list>){ + _m=get.as_array(array_like_view_t{list}); + } + // T[N]的构造 + template + array_t(T(&a)[N])noexcept(get.as_array.nothrow){ + _m=get.as_array(a); + } + #line 69 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base/container/array/defs.hpp" //template.as_array.able> U> template requires(get.as_array.able && type_info>!=type_info) array_t(U&&a)noexcept(get.as_array.nothrow){ @@ -17865,12 +17885,12 @@ namespace array_n{ template - [[nodiscard]]iterator find(U&&a)noexcept requires was_not_an_ill_form(in_range(declvalue(this_t),a)){ - return in_range(*this,a); + [[nodiscard]]iterator find(U&&a)noexcept{ + return in_range(a,array_like_view_t{*this}); } template - [[nodiscard]]const_iterator find(U&&a)const noexcept requires was_not_an_ill_form(in_range(declvalue(this_t),a)){ - return in_range(*this,a); + [[nodiscard]]const_iterator find(U&&a)const noexcept{ + return in_range(a,array_like_view_t{*this}); } }; template @@ -34044,8 +34064,8 @@ public: [[nodiscard]]friend ubigfloat reciprocal(const ubigfloat& a)noexcept{ return ubigfloat{a._denominator,a._numerator}; } - [[nodiscard]]friend ubigfloat reciprocal(ubigfloat&& a)noexcept{ - return ubigfloat{move(a._denominator),move(a._numerator)}; + [[nodiscard]]friend ubigfloat&& reciprocal(ubigfloat&& a)noexcept{ + return swap(a._denominator,a._numerator),move(a); } //friend get_numerator [[nodiscard]]friend const ubigint& get_numerator(const ubigfloat& a)noexcept{ @@ -34387,6 +34407,9 @@ class bigfloat; [[nodiscard]]bigfloat copy_as_negative(ubigfloat&&,bool sign=true)noexcept; using math::copy_as_negative;//避免可能的符号覆盖 +[[nodiscard]]inline bigfloat operator-(const ubigfloat&num)noexcept; +[[nodiscard]]inline bigfloat operator-(ubigfloat&&num)noexcept; + class bigfloat{ bool _is_negative=false; ubigfloat _num; @@ -34496,7 +34519,7 @@ public: return bigfloat{reciprocal(a._num), a._is_negative}; } [[nodiscard]]friend bigfloat&& reciprocal(bigfloat&& a)noexcept{ - a._num=reciprocal(move(a._num)); + discard=reciprocal(move(a._num));//swap it! return move(a); } //friend trunc @@ -34701,6 +34724,13 @@ public: } }; +[[nodiscard]]inline bigfloat operator-(const ubigfloat&num)noexcept{ + return copy_as_negative(num); +} +[[nodiscard]]inline bigfloat operator-(ubigfloat&&num)noexcept{ + return copy_as_negative(move(num)); +} + template concept bigfloat_cvref=type_info> == type_info; diff --git a/files/random b/files/random index e970297..92e1b2e 100644 --- a/files/random +++ b/files/random @@ -2804,37 +2804,43 @@ namespace math{ template requires(has_epsilon) [[nodiscard]]force_inline constexpr T sqrt(const T&v)noexcept; template + inline constexpr T sqrt_to_new_epsilon(T&num,const T&v,const to_unsigned_t&epsilon)noexcept{ + //newton-raphson + floop{ + auto next_ret=(num+v/num)/2u; + const bool end=abs(next_ret-num) + [[nodiscard]]inline constexpr T quick_sqrt(const T&v)noexcept{ + if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking + if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 + if constexpr(type_info == type_info) + return union_cast(0x5F375A86-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + #if defined(_MSC_VER)//msvc上long double就是double + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + #elif defined(ELC_BASE_ENV_HAS_INT128) + return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); + #else + do_nothing;//可以寄了 + #endif + elseif constexpr(is_big_type) + return sqrt(static_cast(v)); + return v/2u; + } + template [[nodiscard]]inline constexpr T sqrt(const T&v,const to_unsigned_t&epsilon)noexcept{ if constexpr(has_NaN && has_inf) if(v < 0u || v >= arithmetic_type_info_prover::Inf()) return arithmetic_type_info_prover::NaN(); - T aret=exlambda()->T{ - if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking - if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 - if constexpr(type_info == type_info) - return union_cast(0x5F375A86-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - #if defined(_MSC_VER)//msvc上long double就是double - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - #elif defined(ELC_BASE_ENV_HAS_INT128) - return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); - #else - do_nothing;//可以寄了 - #endif - elseif constexpr(is_big_type) - return sqrt(static_cast(v)); - return v/2u; - }(); - //newton-raphson - floop{ - auto next_ret=(aret+v/aret)/2u; - if(abs(next_ret-aret) requires(has_epsilon) @@ -2848,13 +2854,13 @@ namespace math{ /*! 判断某数是否是素数,无预先检查以供其他素数相关函数快速调用. */ template [[nodiscard]]inline constexpr bool is_prime_num_no_pre_check(T a)noexcept{ - #line 415 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 421 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" T b=safe_arithmetic_cast(sqrt(a));//若一个数可以分解为两因数之积,其中一个因数必定≤其开方:反指数式减少遍历范围. - #line 427 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 433 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" for(T c=5u;c<=b;c+=6u)//遍历判断是否能被因数分解——不会有人看不懂吧? if((!mod(a,c))||(!mod(a,(c+2u)))) return false; - #line 436 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 442 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return true; } /*! 判断某数是否是素数 */ @@ -2867,10 +2873,10 @@ namespace math{ if(b<4) return true;//1和0也是prime,我不管. - #line 458 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 464 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if(mod(mod(b,6)-1u,4u)) return false; - #line 463 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 469 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return is_prime_num_no_pre_check(b); } /// 求小于或等于某数的素数 @@ -2929,13 +2935,13 @@ namespace math{ /// 已知当前array的size,求下一个合适的提前分配大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_array(size_T size)noexcept{ - #line 524 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 530 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(size*magic_number::gold_of_resize); } /// 已知当前hash table的size,求下一个合适的桶大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_hash(size_T size)noexcept{ - #line 533 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 539 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(get_prime_num_big_or_eq_than(size*magic_number::gold_of_resize)); } pop_msvc_warning(); @@ -3209,6 +3215,8 @@ using math::integer_log; using math::pow; using math::ceil; using math::floor; +using math::sqrt_to_new_epsilon; +using math::quick_sqrt; using math::sqrt; using math::trunc; using math::is_prime_num; @@ -3311,7 +3319,7 @@ namespace magic_number{ //我们可以将result看作Ai*sqrt_640320的和. auto magic_number = sqrt_640320; //计算新的sqrt_640320. - sqrt_640320 = sqrt(ufloat_t{640320u},new_epsilon); + sqrt_to_new_epsilon(sqrt_640320,ufloat_t{640320u},new_epsilon); magic_number /= sqrt_640320; //去除旧数据的影响. result /= magic_number; @@ -3354,9 +3362,9 @@ namespace math{ template [[nodiscard]]constexpr T arctan(T num, const to_unsigned_t&epsilon)noexcept{ - #line 955 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 963 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if constexpr(signed_type) - if (num < 0) return copy_as_negative(arctan(abs(num), epsilon)); + if (num < 0) return -arctan(abs(num), epsilon); if (num > 1) return pi_with_epsilon(epsilon)/2u - arctan(reciprocal(move(num)), epsilon); size_t i = 1; bool negation = false; // 取反 @@ -6079,7 +6087,7 @@ namespace note_n{ force_inline constexpr name##_t(T a)noexcept:value(a){}\ template\ force_inline constexpr name##_t(name##_ta)noexcept:value(a.value){}\ - force_inline constexpr operator T()noexcept{return value;}\ + force_inline explicit constexpr operator T()noexcept{return value;}\ force_inline constexpr T operator()()noexcept{return value;}\ };\ template\ @@ -6110,7 +6118,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr size_t size_of_array_like(T(&)[N])noexcept{return N;} template - [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list&a)noexcept{return a.size();} + [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list>&a)noexcept{return a.size();} enable_adl(begin_of_array_like); template @@ -6118,7 +6126,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr auto begin_of_array_like(T(&a)[N])noexcept{return addressof(a[0]);} template - [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list&a)noexcept{return a.begin();} + [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list>&a)noexcept{return a.begin();} enable_adl(end_of_array_like); template @@ -6147,6 +6155,8 @@ namespace array_like_n{ template constexpr bool is_array_like_for=strict_is_array_like_for||strict_is_array_like_for; + static_assert(is_array_like_for>); + template struct array_like_view_t{ typedef T* iterator; @@ -6177,6 +6187,7 @@ namespace array_like_n{ size_t _size=0; public: constexpr explicit array_like_view_t(T*a,size_t b)noexcept:_begin(a),_size(b){} + constexpr explicit array_like_view_t(T*a,note::size_t b)noexcept:array_like_view_t(a,b()){} template requires strict_is_array_like_for explicit constexpr_as_auto array_like_view_t(U&&a)noexcept_as(begin_of_array_like(a),size_of_array_like(a)):array_like_view_t(begin_of_array_like(a),size_of_array_like(a)){} constexpr array_like_view_t(const this_t&)noexcept=default; diff --git a/files/resolve_global_name_conflicts b/files/resolve_global_name_conflicts index ecc3cc4..b6650ed 100644 --- a/files/resolve_global_name_conflicts +++ b/files/resolve_global_name_conflicts @@ -2845,37 +2845,43 @@ namespace math{ template requires(has_epsilon) [[nodiscard]]force_inline constexpr T sqrt(const T&v)noexcept; template + inline constexpr T sqrt_to_new_epsilon(T&num,const T&v,const to_unsigned_t&epsilon)noexcept{ + //newton-raphson + floop{ + auto next_ret=(num+v/num)/2u; + const bool end=abs(next_ret-num) + [[nodiscard]]inline constexpr T quick_sqrt(const T&v)noexcept{ + if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking + if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 + if constexpr(type_info == type_info) + return union_cast(0x5F375A86-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + #if defined(_MSC_VER)//msvc上long double就是double + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + #elif defined(ELC_BASE_ENV_HAS_INT128) + return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); + #else + do_nothing;//可以寄了 + #endif + elseif constexpr(is_big_type) + return sqrt(static_cast(v)); + return v/2u; + } + template [[nodiscard]]inline constexpr T sqrt(const T&v,const to_unsigned_t&epsilon)noexcept{ if constexpr(has_NaN && has_inf) if(v < 0u || v >= arithmetic_type_info_prover::Inf()) return arithmetic_type_info_prover::NaN(); - T aret=exlambda()->T{ - if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking - if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 - if constexpr(type_info == type_info) - return union_cast(0x5F375A86-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - #if defined(_MSC_VER)//msvc上long double就是double - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - #elif defined(ELC_BASE_ENV_HAS_INT128) - return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); - #else - do_nothing;//可以寄了 - #endif - elseif constexpr(is_big_type) - return sqrt(static_cast(v)); - return v/2u; - }(); - //newton-raphson - floop{ - auto next_ret=(aret+v/aret)/2u; - if(abs(next_ret-aret) requires(has_epsilon) @@ -2889,13 +2895,13 @@ namespace math{ /*! 判断某数是否是素数,无预先检查以供其他素数相关函数快速调用. */ template [[nodiscard]]inline constexpr bool is_prime_num_no_pre_check(T a)noexcept{ - #line 415 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 421 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" T b=safe_arithmetic_cast(sqrt(a));//若一个数可以分解为两因数之积,其中一个因数必定≤其开方:反指数式减少遍历范围. - #line 427 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 433 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" for(T c=5u;c<=b;c+=6u)//遍历判断是否能被因数分解——不会有人看不懂吧? if((!mod(a,c))||(!mod(a,(c+2u)))) return false; - #line 436 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 442 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return true; } /*! 判断某数是否是素数 */ @@ -2908,10 +2914,10 @@ namespace math{ if(b<4) return true;//1和0也是prime,我不管. - #line 458 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 464 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if(mod(mod(b,6)-1u,4u)) return false; - #line 463 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 469 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return is_prime_num_no_pre_check(b); } /// 求小于或等于某数的素数 @@ -2970,13 +2976,13 @@ namespace math{ /// 已知当前array的size,求下一个合适的提前分配大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_array(size_T size)noexcept{ - #line 524 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 530 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(size*magic_number::gold_of_resize); } /// 已知当前hash table的size,求下一个合适的桶大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_hash(size_T size)noexcept{ - #line 533 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 539 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(get_prime_num_big_or_eq_than(size*magic_number::gold_of_resize)); } pop_msvc_warning(); @@ -3250,6 +3256,8 @@ using math::integer_log; using math::pow; using math::ceil; using math::floor; +using math::sqrt_to_new_epsilon; +using math::quick_sqrt; using math::sqrt; using math::trunc; using math::is_prime_num; @@ -3352,7 +3360,7 @@ namespace magic_number{ //我们可以将result看作Ai*sqrt_640320的和. auto magic_number = sqrt_640320; //计算新的sqrt_640320. - sqrt_640320 = sqrt(ufloat_t{640320u},new_epsilon); + sqrt_to_new_epsilon(sqrt_640320,ufloat_t{640320u},new_epsilon); magic_number /= sqrt_640320; //去除旧数据的影响. result /= magic_number; @@ -3395,9 +3403,9 @@ namespace math{ template [[nodiscard]]constexpr T arctan(T num, const to_unsigned_t&epsilon)noexcept{ - #line 955 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 963 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if constexpr(signed_type) - if (num < 0) return copy_as_negative(arctan(abs(num), epsilon)); + if (num < 0) return -arctan(abs(num), epsilon); if (num > 1) return pi_with_epsilon(epsilon)/2u - arctan(reciprocal(move(num)), epsilon); size_t i = 1; bool negation = false; // 取反 @@ -6120,7 +6128,7 @@ namespace note_n{ force_inline constexpr name##_t(T a)noexcept:value(a){}\ template\ force_inline constexpr name##_t(name##_ta)noexcept:value(a.value){}\ - force_inline constexpr operator T()noexcept{return value;}\ + force_inline explicit constexpr operator T()noexcept{return value;}\ force_inline constexpr T operator()()noexcept{return value;}\ };\ template\ @@ -6151,7 +6159,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr size_t size_of_array_like(T(&)[N])noexcept{return N;} template - [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list&a)noexcept{return a.size();} + [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list>&a)noexcept{return a.size();} enable_adl(begin_of_array_like); template @@ -6159,7 +6167,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr auto begin_of_array_like(T(&a)[N])noexcept{return addressof(a[0]);} template - [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list&a)noexcept{return a.begin();} + [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list>&a)noexcept{return a.begin();} enable_adl(end_of_array_like); template @@ -6188,6 +6196,8 @@ namespace array_like_n{ template constexpr bool is_array_like_for=strict_is_array_like_for||strict_is_array_like_for; + static_assert(is_array_like_for>); + template struct array_like_view_t{ typedef T* iterator; @@ -6218,6 +6228,7 @@ namespace array_like_n{ size_t _size=0; public: constexpr explicit array_like_view_t(T*a,size_t b)noexcept:_begin(a),_size(b){} + constexpr explicit array_like_view_t(T*a,note::size_t b)noexcept:array_like_view_t(a,b()){} template requires strict_is_array_like_for explicit constexpr_as_auto array_like_view_t(U&&a)noexcept_as(begin_of_array_like(a),size_of_array_like(a)):array_like_view_t(begin_of_array_like(a),size_of_array_like(a)){} constexpr array_like_view_t(const this_t&)noexcept=default; diff --git a/files/stream b/files/stream index b4ef36c..b355b58 100644 --- a/files/stream +++ b/files/stream @@ -2844,37 +2844,43 @@ namespace math{ template requires(has_epsilon) [[nodiscard]]force_inline constexpr T sqrt(const T&v)noexcept; template + inline constexpr T sqrt_to_new_epsilon(T&num,const T&v,const to_unsigned_t&epsilon)noexcept{ + //newton-raphson + floop{ + auto next_ret=(num+v/num)/2u; + const bool end=abs(next_ret-num) + [[nodiscard]]inline constexpr T quick_sqrt(const T&v)noexcept{ + if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking + if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 + if constexpr(type_info == type_info) + return union_cast(0x5F375A86-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + #if defined(_MSC_VER)//msvc上long double就是double + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + #elif defined(ELC_BASE_ENV_HAS_INT128) + return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); + #else + do_nothing;//可以寄了 + #endif + elseif constexpr(is_big_type) + return sqrt(static_cast(v)); + return v/2u; + } + template [[nodiscard]]inline constexpr T sqrt(const T&v,const to_unsigned_t&epsilon)noexcept{ if constexpr(has_NaN && has_inf) if(v < 0u || v >= arithmetic_type_info_prover::Inf()) return arithmetic_type_info_prover::NaN(); - T aret=exlambda()->T{ - if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking - if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 - if constexpr(type_info == type_info) - return union_cast(0x5F375A86-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - #if defined(_MSC_VER)//msvc上long double就是double - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - #elif defined(ELC_BASE_ENV_HAS_INT128) - return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); - #else - do_nothing;//可以寄了 - #endif - elseif constexpr(is_big_type) - return sqrt(static_cast(v)); - return v/2u; - }(); - //newton-raphson - floop{ - auto next_ret=(aret+v/aret)/2u; - if(abs(next_ret-aret) requires(has_epsilon) @@ -2888,13 +2894,13 @@ namespace math{ /*! 判断某数是否是素数,无预先检查以供其他素数相关函数快速调用. */ template [[nodiscard]]inline constexpr bool is_prime_num_no_pre_check(T a)noexcept{ - #line 415 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 421 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" T b=safe_arithmetic_cast(sqrt(a));//若一个数可以分解为两因数之积,其中一个因数必定≤其开方:反指数式减少遍历范围. - #line 427 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 433 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" for(T c=5u;c<=b;c+=6u)//遍历判断是否能被因数分解——不会有人看不懂吧? if((!mod(a,c))||(!mod(a,(c+2u)))) return false; - #line 436 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 442 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return true; } /*! 判断某数是否是素数 */ @@ -2907,10 +2913,10 @@ namespace math{ if(b<4) return true;//1和0也是prime,我不管. - #line 458 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 464 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if(mod(mod(b,6)-1u,4u)) return false; - #line 463 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 469 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return is_prime_num_no_pre_check(b); } /// 求小于或等于某数的素数 @@ -2969,13 +2975,13 @@ namespace math{ /// 已知当前array的size,求下一个合适的提前分配大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_array(size_T size)noexcept{ - #line 524 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 530 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(size*magic_number::gold_of_resize); } /// 已知当前hash table的size,求下一个合适的桶大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_hash(size_T size)noexcept{ - #line 533 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 539 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(get_prime_num_big_or_eq_than(size*magic_number::gold_of_resize)); } pop_msvc_warning(); @@ -3249,6 +3255,8 @@ using math::integer_log; using math::pow; using math::ceil; using math::floor; +using math::sqrt_to_new_epsilon; +using math::quick_sqrt; using math::sqrt; using math::trunc; using math::is_prime_num; @@ -3351,7 +3359,7 @@ namespace magic_number{ //我们可以将result看作Ai*sqrt_640320的和. auto magic_number = sqrt_640320; //计算新的sqrt_640320. - sqrt_640320 = sqrt(ufloat_t{640320u},new_epsilon); + sqrt_to_new_epsilon(sqrt_640320,ufloat_t{640320u},new_epsilon); magic_number /= sqrt_640320; //去除旧数据的影响. result /= magic_number; @@ -3394,9 +3402,9 @@ namespace math{ template [[nodiscard]]constexpr T arctan(T num, const to_unsigned_t&epsilon)noexcept{ - #line 955 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 963 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if constexpr(signed_type) - if (num < 0) return copy_as_negative(arctan(abs(num), epsilon)); + if (num < 0) return -arctan(abs(num), epsilon); if (num > 1) return pi_with_epsilon(epsilon)/2u - arctan(reciprocal(move(num)), epsilon); size_t i = 1; bool negation = false; // 取反 @@ -6119,7 +6127,7 @@ namespace note_n{ force_inline constexpr name##_t(T a)noexcept:value(a){}\ template\ force_inline constexpr name##_t(name##_ta)noexcept:value(a.value){}\ - force_inline constexpr operator T()noexcept{return value;}\ + force_inline explicit constexpr operator T()noexcept{return value;}\ force_inline constexpr T operator()()noexcept{return value;}\ };\ template\ @@ -6150,7 +6158,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr size_t size_of_array_like(T(&)[N])noexcept{return N;} template - [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list&a)noexcept{return a.size();} + [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list>&a)noexcept{return a.size();} enable_adl(begin_of_array_like); template @@ -6158,7 +6166,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr auto begin_of_array_like(T(&a)[N])noexcept{return addressof(a[0]);} template - [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list&a)noexcept{return a.begin();} + [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list>&a)noexcept{return a.begin();} enable_adl(end_of_array_like); template @@ -6187,6 +6195,8 @@ namespace array_like_n{ template constexpr bool is_array_like_for=strict_is_array_like_for||strict_is_array_like_for; + static_assert(is_array_like_for>); + template struct array_like_view_t{ typedef T* iterator; @@ -6217,6 +6227,7 @@ namespace array_like_n{ size_t _size=0; public: constexpr explicit array_like_view_t(T*a,size_t b)noexcept:_begin(a),_size(b){} + constexpr explicit array_like_view_t(T*a,note::size_t b)noexcept:array_like_view_t(a,b()){} template requires strict_is_array_like_for explicit constexpr_as_auto array_like_view_t(U&&a)noexcept_as(begin_of_array_like(a),size_of_array_like(a)):array_like_view_t(begin_of_array_like(a),size_of_array_like(a)){} constexpr array_like_view_t(const this_t&)noexcept=default; @@ -17622,7 +17633,16 @@ namespace array_n{ explicit array_t(note::size_t size,const T&elem)noexcept(get.nothrow<>){ _m=get[size.value](elem); } - #line 60 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base/container/array/defs.hpp" + // ::std::initializer_list的构造 + array_t(::std::initializer_list&&list)noexcept(get.as_array.nothrow<::std::initializer_list>){ + _m=get.as_array(array_like_view_t{list}); + } + // T[N]的构造 + template + array_t(T(&a)[N])noexcept(get.as_array.nothrow){ + _m=get.as_array(a); + } + #line 69 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base/container/array/defs.hpp" //template.as_array.able> U> template requires(get.as_array.able && type_info>!=type_info) array_t(U&&a)noexcept(get.as_array.nothrow){ @@ -17826,12 +17846,12 @@ namespace array_n{ template - [[nodiscard]]iterator find(U&&a)noexcept requires was_not_an_ill_form(in_range(declvalue(this_t),a)){ - return in_range(*this,a); + [[nodiscard]]iterator find(U&&a)noexcept{ + return in_range(a,array_like_view_t{*this}); } template - [[nodiscard]]const_iterator find(U&&a)const noexcept requires was_not_an_ill_form(in_range(declvalue(this_t),a)){ - return in_range(*this,a); + [[nodiscard]]const_iterator find(U&&a)const noexcept{ + return in_range(a,array_like_view_t{*this}); } }; template @@ -31249,8 +31269,8 @@ public: [[nodiscard]]friend ubigfloat reciprocal(const ubigfloat& a)noexcept{ return ubigfloat{a._denominator,a._numerator}; } - [[nodiscard]]friend ubigfloat reciprocal(ubigfloat&& a)noexcept{ - return ubigfloat{move(a._denominator),move(a._numerator)}; + [[nodiscard]]friend ubigfloat&& reciprocal(ubigfloat&& a)noexcept{ + return swap(a._denominator,a._numerator),move(a); } //friend get_numerator [[nodiscard]]friend const ubigint& get_numerator(const ubigfloat& a)noexcept{ @@ -31592,6 +31612,9 @@ class bigfloat; [[nodiscard]]bigfloat copy_as_negative(ubigfloat&&,bool sign=true)noexcept; using math::copy_as_negative;//避免可能的符号覆盖 +[[nodiscard]]inline bigfloat operator-(const ubigfloat&num)noexcept; +[[nodiscard]]inline bigfloat operator-(ubigfloat&&num)noexcept; + class bigfloat{ bool _is_negative=false; ubigfloat _num; @@ -31701,7 +31724,7 @@ public: return bigfloat{reciprocal(a._num), a._is_negative}; } [[nodiscard]]friend bigfloat&& reciprocal(bigfloat&& a)noexcept{ - a._num=reciprocal(move(a._num)); + discard=reciprocal(move(a._num));//swap it! return move(a); } //friend trunc @@ -31906,6 +31929,13 @@ public: } }; +[[nodiscard]]inline bigfloat operator-(const ubigfloat&num)noexcept{ + return copy_as_negative(num); +} +[[nodiscard]]inline bigfloat operator-(ubigfloat&&num)noexcept{ + return copy_as_negative(move(num)); +} + template concept bigfloat_cvref=type_info> == type_info; diff --git a/files/string b/files/string index 755e57e..0db1a02 100644 --- a/files/string +++ b/files/string @@ -2844,37 +2844,43 @@ namespace math{ template requires(has_epsilon) [[nodiscard]]force_inline constexpr T sqrt(const T&v)noexcept; template + inline constexpr T sqrt_to_new_epsilon(T&num,const T&v,const to_unsigned_t&epsilon)noexcept{ + //newton-raphson + floop{ + auto next_ret=(num+v/num)/2u; + const bool end=abs(next_ret-num) + [[nodiscard]]inline constexpr T quick_sqrt(const T&v)noexcept{ + if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking + if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 + if constexpr(type_info == type_info) + return union_cast(0x5F375A86-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + elseif constexpr(type_info == type_info) + #if defined(_MSC_VER)//msvc上long double就是double + return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); + #elif defined(ELC_BASE_ENV_HAS_INT128) + return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); + #else + do_nothing;//可以寄了 + #endif + elseif constexpr(is_big_type) + return sqrt(static_cast(v)); + return v/2u; + } + template [[nodiscard]]inline constexpr T sqrt(const T&v,const to_unsigned_t&epsilon)noexcept{ if constexpr(has_NaN && has_inf) if(v < 0u || v >= arithmetic_type_info_prover::Inf()) return arithmetic_type_info_prover::NaN(); - T aret=exlambda()->T{ - if constexpr(BIT_POSSIBILITY==2)// evil floating point bit level hacking - if(!in_consteval)//编译期计算不能使用union_cast,让编译器慢慢算去吧 - if constexpr(type_info == type_info) - return union_cast(0x5F375A86-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - elseif constexpr(type_info == type_info) - #if defined(_MSC_VER)//msvc上long double就是double - return union_cast(0x5FE6EB50C7B537A9-(union_cast(v)>>1)); - #elif defined(ELC_BASE_ENV_HAS_INT128) - return union_cast(0x5F1E45D78623ECB73CAB40BC89254389_u128-(union_cast(v)>>1)); - #else - do_nothing;//可以寄了 - #endif - elseif constexpr(is_big_type) - return sqrt(static_cast(v)); - return v/2u; - }(); - //newton-raphson - floop{ - auto next_ret=(aret+v/aret)/2u; - if(abs(next_ret-aret) requires(has_epsilon) @@ -2888,13 +2894,13 @@ namespace math{ /*! 判断某数是否是素数,无预先检查以供其他素数相关函数快速调用. */ template [[nodiscard]]inline constexpr bool is_prime_num_no_pre_check(T a)noexcept{ - #line 415 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 421 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" T b=safe_arithmetic_cast(sqrt(a));//若一个数可以分解为两因数之积,其中一个因数必定≤其开方:反指数式减少遍历范围. - #line 427 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 433 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" for(T c=5u;c<=b;c+=6u)//遍历判断是否能被因数分解——不会有人看不懂吧? if((!mod(a,c))||(!mod(a,(c+2u)))) return false; - #line 436 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 442 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return true; } /*! 判断某数是否是素数 */ @@ -2907,10 +2913,10 @@ namespace math{ if(b<4) return true;//1和0也是prime,我不管. - #line 458 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 464 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if(mod(mod(b,6)-1u,4u)) return false; - #line 463 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 469 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return is_prime_num_no_pre_check(b); } /// 求小于或等于某数的素数 @@ -2969,13 +2975,13 @@ namespace math{ /// 已知当前array的size,求下一个合适的提前分配大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_array(size_T size)noexcept{ - #line 524 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 530 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(size*magic_number::gold_of_resize); } /// 已知当前hash table的size,求下一个合适的桶大小 template [[nodiscard]]inline constexpr size_T get_next_gold_size_to_resize_for_hash(size_T size)noexcept{ - #line 533 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 539 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" return size_T(get_prime_num_big_or_eq_than(size*magic_number::gold_of_resize)); } pop_msvc_warning(); @@ -3249,6 +3255,8 @@ using math::integer_log; using math::pow; using math::ceil; using math::floor; +using math::sqrt_to_new_epsilon; +using math::quick_sqrt; using math::sqrt; using math::trunc; using math::is_prime_num; @@ -3351,7 +3359,7 @@ namespace magic_number{ //我们可以将result看作Ai*sqrt_640320的和. auto magic_number = sqrt_640320; //计算新的sqrt_640320. - sqrt_640320 = sqrt(ufloat_t{640320u},new_epsilon); + sqrt_to_new_epsilon(sqrt_640320,ufloat_t{640320u},new_epsilon); magic_number /= sqrt_640320; //去除旧数据的影响. result /= magic_number; @@ -3394,9 +3402,9 @@ namespace math{ template [[nodiscard]]constexpr T arctan(T num, const to_unsigned_t&epsilon)noexcept{ - #line 955 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" + #line 963 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base_defs/math.hpp" if constexpr(signed_type) - if (num < 0) return copy_as_negative(arctan(abs(num), epsilon)); + if (num < 0) return -arctan(abs(num), epsilon); if (num > 1) return pi_with_epsilon(epsilon)/2u - arctan(reciprocal(move(num)), epsilon); size_t i = 1; bool negation = false; // 取反 @@ -6119,7 +6127,7 @@ namespace note_n{ force_inline constexpr name##_t(T a)noexcept:value(a){}\ template\ force_inline constexpr name##_t(name##_ta)noexcept:value(a.value){}\ - force_inline constexpr operator T()noexcept{return value;}\ + force_inline explicit constexpr operator T()noexcept{return value;}\ force_inline constexpr T operator()()noexcept{return value;}\ };\ template\ @@ -6150,7 +6158,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr size_t size_of_array_like(T(&)[N])noexcept{return N;} template - [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list&a)noexcept{return a.size();} + [[nodiscard]]inline size_t size_of_array_like(::std::initializer_list>&a)noexcept{return a.size();} enable_adl(begin_of_array_like); template @@ -6158,7 +6166,7 @@ namespace array_like_n{ template [[nodiscard]]inline constexpr auto begin_of_array_like(T(&a)[N])noexcept{return addressof(a[0]);} template - [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list&a)noexcept{return a.begin();} + [[nodiscard]]inline const T* begin_of_array_like(::std::initializer_list>&a)noexcept{return a.begin();} enable_adl(end_of_array_like); template @@ -6187,6 +6195,8 @@ namespace array_like_n{ template constexpr bool is_array_like_for=strict_is_array_like_for||strict_is_array_like_for; + static_assert(is_array_like_for>); + template struct array_like_view_t{ typedef T* iterator; @@ -6217,6 +6227,7 @@ namespace array_like_n{ size_t _size=0; public: constexpr explicit array_like_view_t(T*a,size_t b)noexcept:_begin(a),_size(b){} + constexpr explicit array_like_view_t(T*a,note::size_t b)noexcept:array_like_view_t(a,b()){} template requires strict_is_array_like_for explicit constexpr_as_auto array_like_view_t(U&&a)noexcept_as(begin_of_array_like(a),size_of_array_like(a)):array_like_view_t(begin_of_array_like(a),size_of_array_like(a)){} constexpr array_like_view_t(const this_t&)noexcept=default; @@ -17622,7 +17633,16 @@ namespace array_n{ explicit array_t(note::size_t size,const T&elem)noexcept(get.nothrow<>){ _m=get[size.value](elem); } - #line 60 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base/container/array/defs.hpp" + // ::std::initializer_list的构造 + array_t(::std::initializer_list&&list)noexcept(get.as_array.nothrow<::std::initializer_list>){ + _m=get.as_array(array_like_view_t{list}); + } + // T[N]的构造 + template + array_t(T(&a)[N])noexcept(get.as_array.nothrow){ + _m=get.as_array(a); + } + #line 69 "https://github.com/ELC-lang/ELC/tree/master/parts/header_file/files/elc/_files/base/container/array/defs.hpp" //template.as_array.able> U> template requires(get.as_array.able && type_info>!=type_info) array_t(U&&a)noexcept(get.as_array.nothrow){ @@ -17826,12 +17846,12 @@ namespace array_n{ template - [[nodiscard]]iterator find(U&&a)noexcept requires was_not_an_ill_form(in_range(declvalue(this_t),a)){ - return in_range(*this,a); + [[nodiscard]]iterator find(U&&a)noexcept{ + return in_range(a,array_like_view_t{*this}); } template - [[nodiscard]]const_iterator find(U&&a)const noexcept requires was_not_an_ill_form(in_range(declvalue(this_t),a)){ - return in_range(*this,a); + [[nodiscard]]const_iterator find(U&&a)const noexcept{ + return in_range(a,array_like_view_t{*this}); } }; template