الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

مكتبة MathX

بدأه C++er في 5 ديسمبر 2013 · 5 رد · 2,373 مشاهدة · في لغة C و ++C
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

بسم الله الرحمن الرحيم

 

قمت بحمد الله من الإنتهاء من الإصدار 0.1a1 من مكتبة MathX و إليك نبذة مختصرة عنها.

 

ما هي MathX

 

هى مكتبة تحتوى على انواع رقمية مماثله للانواع الرقمية الأساسية بلغة C++/C و لكنك انت من يحدد احجامهم فمثلا يمكنك انشاء نوع رقمي بإشارة مماثل للنوع int و لكن بمساحة 1024 بت.

 

المكتبة تستخدم لغة ++C مع الـ Templates و لا يتم إستخدام اى مكتبات خارجية او داخلية من اى نوع حتى تزيد من محمولية المكتبة.

 

تحتوي المكتبة على الانواع التالية:

  int_t: و يمثل عدد صحيح بإشارة.

  uint_t: و يمثل عدد صحيح بدون إشارة.

  float_t: و يمثل عدد عشرى يخضع لمواصفات IEEE 754-2008 القياسية.

  fixed_t: و يمثل عدد عشرى بعدد محدود من الخانات.

 

حتى الان النوعين int_t و uint_t هما من يتم تطويرهم و عند الإنتهاء من الإصدار 1.0.0 سيتم إضافة النوع float_t بإذن الله.

 

النوعين int_t/uint_t يتم تغيير الـ layout الخاصه بهما تبعا لبنية النظام التى تعمل عليهم بمعنى انه إذا تم إستخدام المكتبة داخل نظام little-endian حينها الـ layout الخاصه بهم ستكون little-endian و بالمثل مع big-endian. الهدف من هذا التغيير هو امكانية استخدام النوعين بشكل يماثل إستخدام الأنواع الأساسية بلغة c++/c.

 

النسخه الحالية تحتوى على كود لـ little-endian فقط.

 

المكتبة تأتى بمجموعة جاهزه من int_t و uint_t و هم:

int128_t, uint128_t, int256_t, uint256_t, int512_t, uint512_t, int1024_t, uint1024_t, int2048_t, uint2048_t, int4096_t, uint4096_t

مدى الأرقام لهذه الانواع كما يلي:

int128_t: (16 bytes)
  min: -170141183460469231731687303715884105728
  max:  170141183460469231731687303715884105727

uint128_t:
  max:  340282366920938463463374607431768211455

int256_t: (32 bytes)
  min: -57896044618658097711785492504343953926634992332820282019728792003956564819968
  max:  57896044618658097711785492504343953926634992332820282019728792003956564819967

uint256_t:
  max: 115792089237316195423570985008687907853269984665640564039457584007913129639935

int512_t: (64 bytes)
  min: -67039039649712985497870124991029230637396829102961966888617807218608820150367
        73488400937149083451713845015929093243025426876941405973284973216824503042048

  max:  67039039649712985497870124991029230637396829102961966888617807218608820150367
        73488400937149083451713845015929093243025426876941405973284973216824503042047

uint512_t:
  max: 134078079299425970995740249982058461274793658205923933777235614437217640300735
       46976801874298166903427690031858186486050853753882811946569946433649006084095

int1024_t: (128 bytes)
  min: -898846567431157953864652595394512366808988489471153286367150405788663379027504
        815663542386612037680105600569399356966788293948844072083112464237153197370621
        888839467124327426381511098006230470597265414760425028844190753411712314407369
        56555270413618581675255342293149119973622969239858152417678164812112068608

  max:  898846567431157953864652595394512366808988489471153286367150405788663379027504
        815663542386612037680105600569399356966788293948844072083112464237153197370621
        888839467124327426381511098006230470597265414760425028844190753411712314407369
        56555270413618581675255342293149119973622969239858152417678164812112068607

uint1024_t:
  max: 1797693134862315907729305190789024733617976978942306572734300811577326758055009
       6313270847732240753602112011387987139335765878976881441662249284743063947412437
       7767893424865485276302219601246094119453082952085005768838150682342462881473913
       110540827237163350510684586298239947245938479716304835356329624224137215

int2048_t: (256 bytes)
  min: -161585030356555036503574383443349759802220513348577420160651727137623275694339454465986007057614567318
        443589804609490097470597795752454605475440761932241415603154386836504980458750988751948260533980288191
        920337841383961093213098780809190471692380852352908229260181525214437879457705329043037761995619651927
        609571666948341712103424873932822847474280880176631610290389028296655130963542301570751292964320885583
        629718018592309286787991755761508229522018488066166436156135628423554101048625785508634656617348392712
        903283489675229986341764993191077625831947186677718010677166148023226592393024760740967779268055297981
        15328

  max:  161585030356555036503574383443349759802220513348577420160651727137623275694339454465986007057614567318
        443589804609490097470597795752454605475440761932241415603154386836504980458750988751948260533980288191
        920337841383961093213098780809190471692380852352908229260181525214437879457705329043037761995619651927
        609571666948341712103424873932822847474280880176631610290389028296655130963542301570751292964320885583
        629718018592309286787991755761508229522018488066166436156135628423554101048625785508634656617348392712
        903283489675229986341764993191077625831947186677718010677166148023226592393024760740967779268055297981
        15327

uint2048_t:
  max: 3231700607131100730071487668866995196044410266971548403213034542752465513886789089319720141152291346368
       8717960921898019494119559150490921095088152386448283120630877367300996091750197750389652106796057638384
       0675682767922186426197561618380943384761704705816458520363050428875758915410658086075523991239303855219
       1433338966834242068497478656456949485617603532632205807780565933102619270846031415025859286417711672594
       3603718461857357598351152301645904403697613233287231227125684710820209725157101726931323469678542580656
       697935045997268352998638215525166389437335543602135433229604645318478604952148193555853611059596230655

int4096_t: (512 bytes)
  min: -522194440706576253345876355358312191289982124523691890192116741641976953985778728424413405967498779170
        445053357219631418993786719092896803631618043925682638972978488271854999170180795067191859157214035005
        927973113188159419698856372836167342172293308748403954352901852035642024370059304557233988891799014503
        343469488440893892973452815095130470299789726716411734651513348221529512507986199933857107770846917779
        942645743159118957217248367043905936319748237550094520674504208530837546834166925275516486044134775384
        991808184705966507606898412918594045916828375610659246423184062775112999150206172392431297837246097308
        511903252956622805412865917690043804311051417135098849101156584508839003337597742539960818209685142687
        562392007453579567729991395256699805775897135553415567045292136442139895777424891477161767258532611634
        530697452993846501061481697843891439474220308003706472837459911525285821188577408160690315522951458068
        463354171428220365223949985950890732881736611925133626529949897998045399734600887312408859224933727829
        625089164535236559716582775403784110923285873186648442456409760158728501220463308455437074192539205964
        902261490928669488824051563042951500651206733594863336608245755565801460390869016718045121902354170201
        577095168

  max:  522194440706576253345876355358312191289982124523691890192116741641976953985778728424413405967498779170
        445053357219631418993786719092896803631618043925682638972978488271854999170180795067191859157214035005
        927973113188159419698856372836167342172293308748403954352901852035642024370059304557233988891799014503
        343469488440893892973452815095130470299789726716411734651513348221529512507986199933857107770846917779
        942645743159118957217248367043905936319748237550094520674504208530837546834166925275516486044134775384
        991808184705966507606898412918594045916828375610659246423184062775112999150206172392431297837246097308
        511903252956622805412865917690043804311051417135098849101156584508839003337597742539960818209685142687
        562392007453579567729991395256699805775897135553415567045292136442139895777424891477161767258532611634
        530697452993846501061481697843891439474220308003706472837459911525285821188577408160690315522951458068
        463354171428220365223949985950890732881736611925133626529949897998045399734600887312408859224933727829
        625089164535236559716582775403784110923285873186648442456409760158728501220463308455437074192539205964
        902261490928669488824051563042951500651206733594863336608245755565801460390869016718045121902354170201
        577095167

uint4096_t:
  max: 1044388881413152506691752710716624382579964249047383780384233483283953907971557456848826811934997558340
       8901067144392628379875734381857936072632360878513652779459569765437099983403615901343837183144280700118
       5594622637631883939771274567233468434458661749680790870580370407128404874011860911446797778359802900668
       6938976881787785946905630190260940599579453432823469303026696443059025015972399867714215541693835559885
       2914863182379144344967340878118726394964751001890413490084170616750936683338505510329720882695507699836
       1636941193301521379682583718809183365675122131849284636812555022599830041234478486259567449219461702380
       6505913245610825731835380087608622102834270197698202313169017678006675195485079921636419370285375124784
       0149071591354599827905133996115517942711068311340905842728842797915548497829543235345170652232690613949
       0598769300212296339568778287894844061600741294567491982305057164237715481632138063104590291613692670834
       2856440730447899971901781465763473223850267253059899795996090799469201774624817718449867455659250178329
       0704731194331655508075682218465717463732968849128195203174570024409266169108741483850784119298045229818
       57338977648103126085903001302413467189726673216491511131602920781738033436090243804708340403154190335

يمكنك إنشاء نسخ من النوعين int_t/uint_t بإحجام تبدا من 16 بايت و حتى 256 ميجا و لكن مع كبر الحجم ستحتاج لتكبير حجم الـ stack ألخاص ببرنامجك.

 

لماذا MathX

 

أغلب المكتبات الموجوده مصممه لتعمل داخل الـ heap و بأحجام متغيره تبعا لإحتياجك و هذا يجعل من الصعب إستخدام هذه المكتبات داخل الـ embedded systems و المكتبات التى يمكنها العمل داخل الـ stack تجدها تعتمد على انواع بيانات معينه لا تستطيع تغييرها.

 

كل هذه المعوقات و غيرها تم تجنبها فى MathX حيث:

 

1- تقوم أنت بتحديد عدد البت داخل البايت الواحد فإن لم تقم بذلك سيتم إستخدام الحجم الإفتراضي الذى يقوم المترجم بتعريفه.

2- تقوم بتحديد حجم نوع البيانات الذى يتم إنشاء الأنواع الإفتراضية من int_t/uint_t فإن لم تقم سيتم إستخدام انواع بيانات بحجم يساوى مساحة حجم مسجل المعالج لضمان اقصى سرعة فى التنفيذ.

3- تقوم انت بتحديد الأنواع التى سيتم إستخدامها داخل الكود لحفظ حجم المصفوفة و موقع عنصر بها و قيمة العداد، فإن لم تقم سيتم إستخدام قيم إفتراضية تتلائم مع البيئة التى تعمل بها.

4- كما ذكرت يوجد حد أقصي للذاكرة التى يمكن للنوعين int_t/uint_t استخدامها و هى محدوده بأقصي قيمه لنوع يمكنك تغييره إن اردت.

5- يمكنك إيقاف و تشغيل العمليات على الأعداد العشرية و بذلك تضمن عدم استخدام اى دوال من المكتبة الإفتراضية باللغه و ذلك إن اردت ترجمه المكتبه لتعمل مع نظام لا يدعم float-point.

6- لا يوجد كود C أو كود أسكبلي من أى نوع فقط ++Pure C و هذا يعنى ان المترجم يعمل بأقصي طاقاته مع التحسينات و يعطيك افضل نتيجه.

7- لا يتم إستخدام المؤشرات و لا اى خصائص الوراثة و الكود الناتج يتم فلترته بشكل كبير، شكرا للـ Templates.

8- تم إستخدام أساليب برمجية تضمن سرعة و كفاءة الكود و مع تفعيل SIMD يتم إنتاج كود سريع جدا، جرب بنفسك و سترى.

9- توجد العديد من المزايا و لكن لا يوجد وقت للكتابة، يمكنك مراجعة صفحة المشروع للمزيد من المعلومات.

 

توثيق المكتبة

 

لازال جارى العمل عليه و سأقوم بتحديث هذا الموضوع مع كل تعديلات جديده داخل المشروع.

 

 

كيف يتم إستخدامها

 

سأفترض ان مسار المكتبة موجود PATH.

 

1- العمليات الحسابية الأساسية تتم كما فى الأنواع الأساسية:

#include <mathx.hpp>
using mathx::uint128_t;

int main()
{
	uint128_t a = 1024, b = 0;
	bool r;

	/*   Addition   */
	a = a + 500;
	a += 100; 

	/*   subtraction   */
	a = a - 13;
	a -= 17; 

	/*   multiplication   */
	a = a * 13;
	a *= 17; 

	/*   division   */
	a = a / 8;
	a /= 2; 

	/*   modulus   */
	a = a % 123456789;
	a %= 3365478; 

	/*   left shift   */
	a = a >> 10;
	a >>= 3; 

	/*   right shift   */
	a = a << 3;
	a <<= 12; 

	/*   bitwise and   */
	a = a & a;
	a &= a;

	/*   bitwise or   */
	a = a | a;
	a |= a;

	/*   bitwise xor   */
	a = a ^ a;
	a ^= a;

	/*   bitwise negation   */
	a = ~a;

	/*   logic and   */
	r = a && b;

	/*   logic or   */
	r = a || b;

	/*   logic not   */
	r = !a;

	/*   logic equal-to   */
	r = a == b;

	/*   logic not-equal-to   */
	r = a != b;

	/*   logic less-than   */
	r = a < b;

	/*   logic less-than-or-equal   */
	r = a <= b;

	/*   logic greater-than   */
	r = a > b;

	/*   logic greater-than-or-equal   */
	r = a >= b;
}

المعاملات التى يتم إستخدامها هنا فعليا تقوم بإستدعاء دوال تقوم بالعمليات التى نريدها و هذه الدوال مقسمه حسب نوع فمثلا الجمع و الطرح داخل فئة دوال الحسابات و الإزاحه فى فئة دوال البت و العمليات المنطقية فى فئة العمليات المنطقية، هذه الفئات هى قلب الأنواع الأساسية بـ MathX و اهمية وجودهم تكمن فى امكانية استبدالة مجموعة بأخرى بكود مختلف دون الحاجه لإعادة كتابة كل شي من جديد.

 

لنأخذ مثال على النوع unit128_t و الذى هو منبثق من uint_t و تعريف هذه الفئه يأخذ الشكل التالي:

template<cu_t bits_count, typename ut_t, typename udt_t,
		 template <typename> class range_t, template <typename> class bitwise_t,
		 template <typename> class logic_t, template <typename> class arithmetic_t,
		 template <typename> class meta_t>
struct uint_t
{
	typedef uint_t<bits_count, ut_t, udt_t, range_t, bitwise_t, logic_t, arithmetic_t, meta_t> type;

	typedef ut_t     ut; // unsigned half type
	typedef ut_t     st; // defined to prevent compile-time error (implementation should never use this type)
	typedef udt_t   udt; // unsigned full type
	typedef udt_t   sdt; // defined to prevent compile-time error (implementation should never use this type)

	typedef range_t<type>           range; // range functions
	typedef bitwise_t<type>       bitwise; // bitwise functions
	typedef logic_t<type>           logic; // logic functions
	typedef arithmetic_t<type> arithmetic; // arithmetic functions
	typedef meta_t<type>             meta; // metadata constants

	ut comp[meta::array_count];
};

داخل المجلد src/base ستجد تعريف فئات الأنواع الأساسية التى تقوم المكتبة بتصديرها و التى uint_t إحداها.

 

داخل الفئة uint_t تجد مجموعة من الـ typedef و التى تمثل كل مجموعة عمليات و هم 5 مجموعات كل منهم يحتوى على دوال تقوم بعمليات محدده، بعض الدوال لا يوجد لها مقابل داخل كود الفئه الأصلي فمثلا توجد الدالة is_neg داخل range و التى تعود لك بـ true إذا كانت القيمه الممرره للداله تحتوى قيمه سالبة و false إذا كانت تحتوى على قيمة موجبة.

 

كافة هذه الدوال يمكنك معرفتها بالإطلاع على محتوى الملف src/base/int_contract.hpp.

 

 

2- التحويل بين الأنواع المختلفه: المكتبة تسمح لك بالتحويل بين اى نوع وأخر فيمكنك تحويل bool إلى int128_t و من ثم تحويل ذلك النوع إلى uint512_t و فى النهاية تقوم بتحويل الناتج إلى int، أنظر الكود التالي:

#include <mathx.hpp>
using mathx::numeric_cast;
using mathx::int128_t;
using mathx::uint512_t;

int main()
{
	bool a = true;
	
	int128_t b = a;
	
	uint512_t c = numeric_cast<int128_t>(b);
	
	int d = numeric_cast<uint512_t>(c);
}

الفئه numeric_cast بإختصار هى المسئولة عن عمليات التحويل الرقميه بين اى نوع وأخر و إستخدامها بسيط حيث يتم تمرير النوع المراد التحويل منه و القيمه المراد تحويلها و لابد من تحديد نوع القيمه الجديده فمثلا الكود التالي لن يتم ترجمته:

numeric_cast<uint512_t>(c);

مع كل مترجم ستظهر رسالة مختلفه و لكن أصل المشكل هو عدم معرفة المترجم النوع الذى ترغب فى تحويل القيمه المدخله إليه، و لإصلاح الخطأ قم بتحديد النوع بأى من الطرق التالية:

	(int)numeric_cast<uint512_t>(c);
	static_cast<int>(numeric_cast<uint512_t>(c));

3- تحويل أنواع المكتبة من و إلي نص يحتاج منا ان نتحدث قليلا قبل النظر للكود

 

كما نعلم انه توجد العديد من الخيارات عندما نتحدث للتحويل من و إلى النص مثلا الأساس الذى تريد التحويل إليه أو منه، و نوع النص فيمكنك إستخدام الفئه string او مصفوفه من نوع wchar و إذا كان لديك فئة نصوص خاصه بك يمكنك ان ترغب فى التعامل معها و ايضا حالة الحروف المحول منها او إليها و العديد من الخصائص الاخرى.

 

كما ترى عملية التحويل من و إلى النصوص لها العديد من الخيارات و لهذا فبخلاف كل اجزاء المكتبة هذا الجزء تحديدا يحتاج منك إلى تركيز كبير، فافعل ما يجعلك تشعر بالراحه و أكمل معي.

 

توجد 3 عمليات أساسية و هم: تحويل رقم إلى نص و تحويل نص إلى رقم و معرفة المساحة التى يحتاجها رقم قبل ان يتم تحويله لنص، و سنتناول هذه العمليات بعد قليل.

 

إسم الفئه التى سنستخدمها للتعامل مع النصوص هو string_cast و شكلها كالتالي:

template<typename num_type, typename str_type, typename base_type>
struct string_cast
{
	inline static cs_t length(const num_type& n);

	inline static bool from(const str_type& s, num_type& n);

	inline static bool to(str_type& s, const num_type& n);

	inline static bool to(str_type& s, const num_type& n, bool upper);
};

يتم تمرير للفئة string_cast ثلاثة معاملات و أولهم النوع الرقمي و هو فى حالتنا هذه اى مشتقات انواع مكتبة MathX مثل int128_t أو uint512_t او float4096_t و هكذا.

 

المعامل الثاني و هو نوع النص و توجد مجموعتين لأنواع النصوص يمكن إستخدامهم و هم:

type*, basic_string

حيث *type هو مؤشر لنوع بيانات اساسي فيمكن ان يكون *char أو *wchar_t او أى مؤشر لنوع بيانات ترغب فى استخدامه كمصفوفة نصوص.

و basic_string هى فئة النصوص الأساسية الموجوده داخل ++c و التى من مشتقاتها الفئتين string و wstring.

 

المعامل الثالث هو أهم معامل و هو الأساس، و الذى سيقوم بالإجابه على الأسئلة التالية:

  1- ما هى الحروف التى تمثل هذا الاساس.

  2- هل يستطيع الأساس تمثيل الإشاره.

  3- فى حالة العدد السالب هل يتم إظهار الإشارة.

  4- هل حرف معين من ضمن حروف هذا الاساس.

  5- ما هى قيمة الحرف داخل هذا الأساس.

  6- ما هو الحرف المقابل لعدد معين داخل الأساس.

 

هذه الأسئلة تقوم بإجابتها الفئات التى تمثل الأساس و التى تتيح لك انشاء مجموعه كبيره من الأسس و لكن توجد بعض الحالات التى لابد من كتابة كود جديد لها مثل الأعداد الرومانيه.

الأساس الإفتراضي لفئة string_cast هو الأساس العشرى.

 

فئة الأساس إسمها base_t و يتم تمرير لها عدة معاملات كل منهم له قيمه إفتراضية إلا المعامل الأول و قيمه الأساس و التى لابد منك تمريرها، أيضا إذا كان نوع بيانات النص المدخل غير مبني على النوع char فستحتاج لتمرير نوع الحرف داخل نوع النص كمعامل ثاني.

 

توجد 4 اسس تم تعريفهم لك و هم 2 و 8 و 10 و 16، قم بتمرير أيهم لـ base_t و سيتم التحويل من و إلى هذا الأساس بإستخدام دوال string_cast.

#include <mathx.hpp>
#include <string>
using std::string;
using std::cout;
using mathx::int128_t;
using mathx::string_cast;
using mathx::base_t;

int main()
{
	int128_t n = ~0ull;
	
	string s;

	string_cast<int128_t, string>::to(s, n);
	cout << "base10 implicit: " << s << "\n";

	string_cast<int128_t, string, base_t<10> >::to(s, n);
	cout << "base10 explicit: " << s << "\n";

	string_cast<int128_t, string, base_t<8> >::to(s, n);
	cout << "base8: " << s << "\n";

	string_cast<int128_t, string, base_t<16> >::to(s, n);
	cout << "base16: " << s << "\n";

	string_cast<int128_t, string, base_t<2> >::to(s, n);
	cout << "base2: " << s << "\n";
}

و النتيجه:

base10 implicit: 18446744073709551615
base10 explicit: 18446744073709551615
base8: 377777777777777777777
base16: ffffffffffffffff
base2: 1111111111111111111111111111111111111111111111111111111111111111

ماذا لو اردت استخدام النوع wchar_t بدلا من char:

	string_cast<int128_t, wstring, base_t<10, wchar_t> >::to(s, n);
	wcout << "base10 explicit: " << s << "\n";

لنقوم الأن بتحويل النصوص التى حصلنا عليها مجددا إلى رقم:

#include <mathx.hpp>
#include <iomanip>
using std::string;
using std::cout;
using std::boolalpha;
using mathx::int128_t;
using mathx::string_cast;
using mathx::base_t;

int main()
{
	int128_t n;
	bool r;

	r = string_cast<int128_t, char*>::from("18446744073709551615", n);
	cout << "is conversion from base10 string OK: " << boolalpha << r << "\n";

	r = string_cast<int128_t, char*, base_t<8> >::from("377777777777777777777", n);
	cout << "is conversion from base8 string OK: " << boolalpha << r << "\n";

	r = string_cast<int128_t, char*, base_t<2> >::from("1111111111111111111111111111111111111111111111111111111111111111", n);
	cout << "is conversion from base2 string OK: " << boolalpha << r << "\n";

	r = string_cast<int128_t, char*, base_t<16> >::from("ffffffffffffffff", n);
	cout << "is conversion from base16 string OK: " << boolalpha << r << "\n";
}

و النتيجه:

is conversion from base10 string OK: true
is conversion from base8 string OK: true
is conversion from base2 string OK: true
is conversion from base16 string OK: true

لكن ماذا يحدث إذا حاولنا التحويل من نص إلى أساس لا يدعم احد حروف النص:

	r = string_cast<int128_t, char*, base_t<10> >::from("ffffffffffffffff", n);
	cout << "is conversion from base10 string OK: " << boolalpha << r << "\n";

و النتيجه:

is conversion from base10 string OK: false

من باب التسلية قمت بكتابة الفئة alphanum_base لتمثل الأساس 36 و حروفه هى:

0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ

أنظر كيف يتم إستخدامها:

#include <mathx.hpp>
#include <string>
using std::string;
using std::cout;
using mathx::uint256_t;
using mathx::string_cast;
using mathx::imp::alphanum_base;

int main()
{
	uint256_t n;
	string s;

	uint256_t::range::set_max(n);

	cout << "max value of uint256_t in\n";
	
	string_cast<uint256_t, string, alphanum_base<6> >::to(s, n);
	cout << "  base6: " << s << "\n\n";

	string_cast<uint256_t, string, alphanum_base<19> >::to(s, n, true);
	cout << "  base19: " << s << "\n\n";

	string_cast<uint256_t, string, alphanum_base<31> >::to(s, n);
	cout << "  base31: " << s << "\n\n";
}

و النتيجه:

max value of uint256_t in
  base6: 1021410542201502023034020312354303525141003020114213135200030531345402305211301035040321031131454023

  base19: 237IFHBBCE5DIAC835EHHG793C6BCDD6739HFFGBFCEFDEDD0FG72B1HD4D7F

  base31: a313gilnoeiiekt9559bqu7h8pbh49n65lt9ek54eo1c67n06b91

قم بالدخول على صفحة المشروع لأحدث نسخه من المشروع، أو أضغط هنا لتحميل كود الإصدار 0.1a1

 

أتمني أن تستمتع بإستخدامها كما أستمتع انا بتصميمها.

 

 

و الله ولي التوفيق

تم تعديل هذه المشاركة بواسطة C++er في 6 ديسمبر 2013 في 23:24

5

مدونتي: C++ Tips and Tricks

#2

ما شاء الله , عمل متقن وفقك الله وفتح عليك ..

اقتباس
هذه الأسئلة تقوم بإجابتها الفئات التى تمثل الأساس و التى تتيح لك انشاء مجموعه كبيره من الأسس و لكن توجد بعض الحالات التى لابد من كتابة كود جديد لها مثل الأعداد الرومانيه.

:D أرى أنك تبالغ بعض الشيء في الغوص في التجريد
اقتباس
uint32 log2(t value)
{
    // only uint_t allowed, if not throw array bound error
    int32 arr[global_t<t>::size_t == global_t<t>::used_t];

    uint32 r = ~0u;
    while (r++, !!(value >>= 1));
    return r;
}

فكرة إنشاء مصفوفة من صفر عنصر مدهشة  :)

لماذا نفي النفي ؟
1-   while (r++, !!(value >>= 1));
2-   for (uint32 i=0; i<global_t<t>::size_t && !!small; i++)
هل ليقوم النفي الآول بتحويل النوع إلى bool ثم يعود النفي الثاني بالقيمة , حتى تضمن أن تكون bool?
اقتباس
uint32 log10(t value)
{
    // only uint_t allowed, if not throw array bound error
    int32 arr[global_t<t>::size_t == global_t<t>::used_t];
    static const t ten = t(10u);
    uint32 p = uint32((log2(value) + 1) * 0.301f);
    t n = ten;
    for(uint32 i=p-1; i>0; i--) n *= ten;
    return  p - (value < n);
}

ألا يكفي
uint32 r = ~0u;while (r++, !!(value /= 10));return r;
?
هذه أعجبتني أيضاً :)
bool operator!() const      { return !(hi | lo); }

t& rotateLeft (uint32 rhs) { return *this = (*this << rhs) | (*this >> (global_t<t>::size_t - rhs)); }

t& rotateRight(uint32 rhs) { return *this = (*this >> rhs) | (*this << (global_t<t>::size_t - rhs)); }

template<typename c>
    operator c() const { return (c)uint_t<uint64>(*this).lo; }

في الملف common_mathX هناك خطأ مطبعي
اقتباس
// for ower example 4*5, smaller = 4, larger = 5

والصحيح our
وفي helper_mathX
اقتباس
// choose temp char because it faster

والصحيح
// choose temp char because it is faster
:p
___________________________
بالمناسبة طريقة قسم كل نوع إلى low و hi رائعة بالفعل
يمكنك تسريع عملية الضرب باستخدام تحويل فورييه فهو أسرع طريقة للضرب n*log(n)  l

لي عودة إن شاء الله بعد التجربة
(سؤال خارجي : ماذا حل بمشروع BigInteger الخاص بـBoost الذي كنت تعمل عليه مع الاخ خالد ؟)
#3

عمل رائع ..

 

أمس صادفتني مشكلة في العدد المحدود لإستعمال المتغير int ..

 

ففكرت في إستعمال biginteger .. ولكن عدلت عنها ..

 

واليوم أرى MathX ، أظن أنني سأستعملها ..

 

تقبل تحياتي  ^_^

رجعت ومازال الفريق خاملاَ  :( 


 


abPuw.1.gif

#4

@مصطفى 36a2: النسخه التى أنزلتها هى القديمه و هى بالإسم mathx_update_1 أما الحديثه فهى بالإسم v0.1a1.

 

النسخه القديمه للقراءة فقط و للتعلم و ليست للإستخدام لأنها كانت مجرد تطبيق لبعض الأفكار أما الحديثه فهى المكتبه الفعليه.

 

إذا اردت التحميل فقم بتحميل المكتبه الموجوده بالمجلد v0.1a

 

 

و الله ولي التوفيق

تم تعديل هذه المشاركة بواسطة C++er في 4 يناير 2014 في 06:22

مدونتي: C++ Tips and Tricks

#5

:D

يا رجل .. وأنا أقول لنفسي ليش آخر تعديل بـ 9 /2011 :)

#6
اقتباس
أرى أنك تبالغ بعض الشيء في الغوص في التجريد

ليس فى كل شئ، توجد بعض الأجزاء من المشروع التى من الأفضل ان تكون ابسط ما يمكن و أخرى لابد ان تكون على درجة كبيره من التجريد و هذا بناءا على طبيعة الجزء، فمثلا عملية تحويل الأنواع الرقيمه بإستخدام numeric_cast لن تفشل أبدا و هذا يعنى ان حفظ قيمه متغير بمساحة كبيره داخل نوع بمساحة أصغر سيؤدى لحذف أجزاء منه و العكس يتم بمد الإشاره او وضع صفر.

 

بالنسبة لتحويل النصوص لابد من مستويات التجريد و ذلك لأن مستخدم المكتبه قد يحتاج لإجراء تعديلات لتناسب ما يريد و فى هذه الحالة لابد من جعله يركز اهتمامه على ما يريد بدلا من وضع أمور ثانوية - بالنسبة لما يريد - فى الحسبان.

 

اقتباس
ماذا حل بمشروع BigInteger الخاص بـBoost الذي كنت تعمل عليه مع الاخ خالد ؟

المشروع توقف العمل عليه منذ فترة طويلة.

 

باقي الأسلة تتعلق بالنسخه التى كنت اتعلم فيها. و سأحاول أن اجيبك على الأسئلة بقدر ما اتذكر

 

اقتباس
لماذا نفي النفي ؟

نفي النفي يماثل تحويل القيمة للنوع bool و حيث ان النوع المدخل للدالة log2 قد لا يمكن تحويله لـ bool - النوع unit_t - لذا كان إستخدام هذا الإسلوب فعال (وقت كتابة ذلك الكود).

 

اقتباس
هل ليقوم النفي الآول بتحويل النوع إلى bool ثم يعود النفي الثاني بالقيمة , حتى تضمن أن تكون bool?

النفي الأول سيحول القيمه لـ bool و لكن معكوسه و النفي الأخير يعيدها لأصلها.

 

 

داخل log10 ذكرت ألا يكفي القسمه على 10؟

تذكر انك تتعامل مع MP و ليس نوع عادى و عملية القسمه مكلفة جدا و تجنبها أمر اضررارى إذا اردت ان تجعل الكود يعمل افضل ما يمكن، و الطريقه المذكوره داخل log10 ستعمل جيدا سواء كان النوع المدخل composite أو primitive.

 

كما ذكرت لك النسخه التى القديمه هى التى بها كنت اتعلم كيفية بناء مكتبة MP و كنت اطبق كل افكارى كما أتت إلي بدون إضافة اى تحسينات، النسخه الحالية هى المكتبة الحقيقية لإنى تلاشيت فيها كل الأخطاء و المشاكل التى واجهتنى فى القديمه.

 

*************

 

إن شاء الله انوى التقدم بهذه المكتبة لـ boost بعد إنتهائي من توثيقها و بعض الأجزاء بها، فإن قمت عزيزى القارئ بتجربتها و لديك اى ملاحظات فسيتم وضعها بالحسبان إن شاء الله.

 

 

 

و الله ولي التوفيق

تم تعديل هذه المشاركة بواسطة C++er في 7 ديسمبر 2013 في 00:00

1

مدونتي: C++ Tips and Tricks

مواضيع مشابهة