Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
steve02081504 committed Oct 28, 2023
1 parent 5e2fc33 commit 56d115b
Show file tree
Hide file tree
Showing 10 changed files with 150 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,7 @@ class base_stack_t:non_copyable{//基础容器,可用于hashtable
}
void move_top_to(this_t&a)noexcept{
_size--;
auto tmp=_m;
_m=_m->_next;
a.add(tmp);
a.add(swap(_m,add_const(_m->_next)));
}
};

Expand Down
14 changes: 4 additions & 10 deletions parts/header_file/files/elc/_files/base_defs/bitset.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,23 +145,17 @@ struct bitset:byteset<ceil_div(bit_num,bitnum_of(byte))>{
constexpr auto&operator<<=(size_t n)noexcept{
const auto [move_step,offset]=divmod(n,bitnum_of(byte));
byte carry{};
for(size_t i=data_size-move_step-1;i!=npos;--i){
const auto tmp=_data[i];
_data[i]=byte((tmp<<offset)|carry);
carry=tmp>>(bitnum_of(byte)-offset);
}
for(size_t i=data_size-move_step-1;i!=npos;--i)
carry=swap(_data[i],byte((_data[i]<<offset)|carry))>>(bitnum_of(byte)-offset);
for(size_t i=0;i<move_step;++i)
_data[i]=byte{};
return*this;
}
constexpr auto&operator>>=(size_t n)noexcept{
const auto [move_step,offset]=divmod(n,bitnum_of(byte));
byte carry{};
for(size_t i=move_step;i!=data_size;++i){
const auto tmp=_data[i];
_data[i]=byte((tmp>>offset)|carry);
carry=tmp<<(bitnum_of(byte)-offset);
}
for(size_t i=move_step;i!=data_size;++i)
carry=swap(_data[i],byte((_data[i]>>offset)|carry))<<(bitnum_of(byte)-offset);
for(size_t i=data_size-move_step;i!=data_size;++i)
_data[i]=byte{};
return*this;
Expand Down
61 changes: 60 additions & 1 deletion parts/header_file/files/elc/_files/base_defs/math.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -910,7 +910,7 @@ namespace math{

//求出最大公约数
template<integer_type T>
[[nodiscard]]inline auto gcd(T x, T y)noexcept{
[[nodiscard]]inline auto base_gcd(T x, T y)noexcept{
size_t shift = 0;
while(y){
//都是偶数时,shift++并位移
Expand All @@ -927,6 +927,65 @@ namespace math{
// 返回 x 左移 shift 位的结果
return move(x) << shift;
}
//求出最大公约数
template<unsigned_big_integer_type T>
[[nodiscard]]inline auto gcd(T x, T y)noexcept{
//假设x≥y
if(x < y)swap(x, y);
//如果y只包含一位数,则使用其他方法求出结果
if (y.size_in_base_type() == 1)
return base_gcd(x, y);

//如果x和y的数位长度不同,使x和y的长度相等于m
size_t m=exλ{
size_t m1=x.size_in_base_type(),m2=y.size_in_base_type();
if(m1>m2)
x = x>>((m1-m2)*bitnum_of(T::base_type));
//else if(m1<m2):不可能,因为x≥y
return m2;
}();

T A, B, C, D;
do{
while(x && y) {//外循环
--m;//提高精度
T a = x >> (m * bitnum_of(T::base_type)), b = y >> (m * bitnum_of(T::base_type));//取最显著数位
/*初始化矩阵[A B a]为扩展的同一矩阵[1 0 a]
[C D b] [0 1 b]
*/
A = 1u, B = T{}, C = T{}, D = 1u;
//对(a+A,b+C)和(a+B,b+D)同时执行欧几里得算法,直到商不同为止
do{
const auto w1 = (a+A) / (b+C);
const auto w2 = (a+B) / (b+D);
if(w1 != w2)break;
const auto& w = w1;//w为欧几里得算法长除法链中当前长除法的商
/*根据扩展欧几里得算法的矩阵表述替换当前矩阵[A B a]到矩阵积[0 1] [A B a] [C D a ]
[C D b] ⋅ =
[1 −w] [C D b] [A−wC B−wD a−wb]
*/
A-=w*C;swap(A,C);
B-=w*D;swap(B,D);
a-=w*b;swap(a,b);
}while(B);//B≠0则继续
//B=0意味着陷入了死锁;执行欧几里得算法的正常步骤,然后重新开始外循环
x = swap(y, x%y);
}
//将对压缩形式的前数位执行的欧几里得算法步骤应用到x和y上
auto new_x = A*x+B*y, new_y = C*x+D*y;
x = move(new_x),y = move(new_y);
}while(y);//如果y≠0,则转到外循环的起点。
return x;
}
template<basic_integer_type T>
[[nodiscard]]force_inline auto gcd(T x, T y)noexcept{
return base_gcd(x, y);
}
template<signed_big_integer_type T>
[[nodiscard]]force_inline auto gcd(T x, T y)noexcept{
const bool sign = is_negative(x) && is_negative(y);
return copy_as_negative(gcd(abs(x), abs(y)), sign);
}
}
using math::gcd;

Expand Down
28 changes: 28 additions & 0 deletions parts/header_file/files/elc/_files/base_defs/other.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,34 @@ constexpr struct do_nothing_t{
constexpr bool operator==(T&)noexcept{return false;}
}do_nothing;

//swap
template<typename T1,typename T2>
inline constexpr_as_auto void swap(T1&a,T2&b)noexcept_as_auto{
using ::std::move;
auto tmp=move(b);
b=move(a);
a=move(tmp);
}
/*
如何不用中间变量swap两个值?
方法一:
a=a+b
b=a-b
a=a-b
方法二:
a^=b^=a^=b
道理我都懂,可是还是用中间变量快些
XD
更多方法欢迎补充
*/
template<typename T1,typename T2>
inline constexpr_as_auto [[nodiscard]]T1 swap(T1&a,const T2&b)noexcept_as_auto{
using ::std::move;
T1 tmp=move(a);
a=b;
return tmp;
}

template<typename T>
struct times_provider_t{
typedef times_provider_t<T> this_t;
Expand Down
13 changes: 0 additions & 13 deletions parts/header_file/files/elc/_files/base_defs/using_std.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,6 @@ using ::std::size_t;

using ::std::forward;
using ::std::addressof;
using ::std::swap;
/*
如何不用中间变量swap两个值?
方法一:
a=a+b
b=a-b
a=a-b
方法二:
a^=b^=a^=b
道理我都懂,可是还是用中间变量快些
XD
更多方法欢迎补充
*/

template<class T>
using remove_cvref= ::std::remove_cvref_t<T>;
Expand Down
9 changes: 9 additions & 0 deletions parts/header_file/files/elc/_files/bignum/bignum/bigfloat.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,15 @@ class bigfloat{
const auto tmp = hash_n::hash(_num)._value;
return hash_t{_is_negative?tmp*7u:tmp};
}
//swap_with
void swap_with(bigfloat& other)noexcept{
swap(_is_negative,other._is_negative);
swap(_num,other._num);
}
//friend swap
friend force_inline void swap(bigfloat& a,bigfloat& b)noexcept{
a.swap_with(b);
}
};

[[nodiscard]]inline bigfloat operator-(const ubigfloat&num)noexcept{
Expand Down
9 changes: 9 additions & 0 deletions parts/header_file/files/elc/_files/bignum/bignum/bigint.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,15 @@ class bigint{
const auto tmp = hash_n::hash(_num)._value;
return hash_t{_is_negative?tmp*7u:tmp};
}
//swap_with
void swap_with(bigint& other)noexcept{
swap(_is_negative,other._is_negative);
swap(_num,other._num);
}
//friend swap
friend force_inline void swap(bigint& a,bigint& b)noexcept{
a.swap_with(b);
}
};

[[nodiscard]]inline bigint operator-(const ubigint& num)noexcept{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,15 @@ class ubigfloat{
[[nodiscard]]force_inline hash_t hash()const noexcept{
return hash_t{hash_n::hash(_numerator)._value*13+hash_n::hash(_denominator)._value};
}
//swap_with
void swap_with(ubigfloat& other)noexcept{
swap(_numerator,other._numerator);
swap(_denominator,other._denominator);
}
//friend swap
friend force_inline void swap(ubigfloat& a,ubigfloat& b)noexcept{
a.swap_with(b);
}
};

template<typename T>
Expand Down
40 changes: 29 additions & 11 deletions parts/header_file/files/elc/_files/bignum/bignum/ubigint.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,14 +246,6 @@ class ubigint{
return other==0?strong_ordering::equivalent:strong_ordering::less;
}
}
//调试用,返回一个可以输出到流的内部结构查看器
[[nodiscard]]auto get_data_viewer()const noexcept{
return λ_with_catch(this)(auto&stream)noexcept->auto&{
for(auto& i: _data)
stream << i << U' ';
return stream;
};
}
private:
//operator+-*/%s
typedef unsigned_specific_size_fast_t<2*sizeof(base_type)> calc_type;
Expand Down Expand Up @@ -632,10 +624,9 @@ class ubigint{
//除法实现
[[nodiscard]]static base_type div_with_base_no_optimisation(data_type&buf,base_type*a,data_view_type b)noexcept{
data_view_type tryto{a,b.size()+1};
const calc_type dividend=exλ{
const auto dividend=(calc_type)exλ{
const base_type*p=tryto.rbegin();
auto tmp=calc_type(*p);tmp*=base_type_mod;tmp+=calc_type(p[-1]);
return tmp;
return calc_type(*p)*base_type_mod+calc_type(p[-1]);
}();
const calc_type divisor=calc_type(b.back());
calc_type left=dividend/(divisor+1);
Expand Down Expand Up @@ -1200,6 +1191,25 @@ class ubigint{
[[nodiscard]]force_inline size_t memory_usage()const noexcept{
return _data.size_in_byte();
}
//size_in_byte
[[nodiscard]]force_inline size_t size_in_byte()const noexcept{
return _data.size_in_byte();
}
//size_in_base_type
[[nodiscard]]force_inline size_t size_in_base_type()const noexcept{
return _data.size();
}
//fast_size_method
[[nodiscard]]force_inline size_t fast_size_method()const noexcept{
return _data.size();
}
//row_data
[[nodiscard]]force_inline data_type& row_data()noexcept{
return _data;
}
[[nodiscard]]force_inline const data_type& row_data()const noexcept{
return _data;
}
//friend base_type_num
[[nodiscard]]friend force_inline size_t base_type_num(const ubigint& x)noexcept{
return x._data.size();
Expand All @@ -1216,6 +1226,14 @@ class ubigint{
[[nodiscard]]force_inline hash_t hash()const noexcept{
return hash_n::hash(_data);
}
//swap_with
force_inline void swap_with(ubigint& other)noexcept{
swap(_data,other._data);
}
//friend swap
friend force_inline void swap(ubigint& a,ubigint& b)noexcept{
a.swap_with(b);
}
};

template<typename T>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ namespace to_string_n{
T base{radix};
size_t len=1;//余数部分要补的前导0个数
//计算分割点
while(base.memory_usage()*3 < num.memory_usage()){
while(base.fast_size_method()*3 < num.fast_size_method()){
len *= 2;
base *= base;
}
Expand Down

0 comments on commit 56d115b

Please sign in to comment.