نوع بدائي | الحجم في الذاكرة | مدى القيمة |
---|---|---|
بايت | 8 بت | -128 إلى 127 |
قصير | 16 بت | -32768 إلى 32767 |
شار | 16 بت | 0 إلى 65536 |
كثافة العمليات | 32 بت | -2147483648 إلى 2147483647 |
طويل | 64 بت | -9223372036854775808 إلى 9223372036854775807 |
يطفو | 32 بت | (2 أس -149) إلى ((2 أس -23) * 2 أس 127) |
مزدوج | 64 بت | (-2 للأس 63) إلى ((2 للأس 63) - 1) |
منطقية | 8 (عند استخدامها في المصفوفات)، 32 (عند عدم استخدامها في المصفوفات) | صحيحة أو خاطئة |
public class Main {
public static void main(String[] args) {
BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
System.out.println(integer);
BigDecimal decimal = new BigDecimal("123.444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444");
System.out.println(decimal);
}
}
يعد تمرير سلسلة إلى المنشئ مجرد خيار واحد ممكن. هنا نستخدم السلاسل، لأن أرقامنا تتجاوز الحد الأقصى لقيم long و double ، ونحن بحاجة إلى طريقة ما لنشرح للمترجم الرقم الذي نريد إنشاءه :) ببساطة قم بتمرير الرقم 1111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 لن يعمل: Java سيحاول حشر الرقم الذي تم تمريره في أحد أنواع البيانات البدائية، لكنه لن يتناسب مع أي منها. ولهذا السبب يعد استخدام سلسلة لتمرير الرقم المطلوب خيارًا جيدًا. يمكن لكلا الفئتين استخراج القيم الرقمية تلقائيًا من السلاسل التي تم تمريرها. هناك نقطة أخرى مهمة يجب تذكرها عند العمل مع فئات ذات أرقام كبيرة وهي أن كائناتها غير قابلة للتغيير ( Immutable ). أنت بالفعل على دراية بالثبات بفضل تجربتك مع فئة String وفئات التغليف للأنواع البدائية (Integer، Long، وما إلى ذلك).
import java.math.BigInteger;
public class Main {
public static void main(String[] args) {
BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
System.out.println(integer);
integer.add(BigInteger.valueOf(33333333));
System.out.println(integer);
}
}
إخراج وحدة التحكم:
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
كما تتوقعون، رقمنا لم يتغير. لإجراء عملية الإضافة، يجب عليك إنشاء كائن جديد لتلقي نتيجة العملية.
import java.math.BigInteger;
public class Main {
public static void main(String[] args) {
BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
System.out.println(integer);
BigInteger result = integer.add(BigInteger.valueOf(33333333));
System.out.println(result);
}
}
إخراج وحدة التحكم:
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111144444444
انظر، الآن كل شيء يعمل كما ينبغي :) بالمناسبة، هل لاحظت كيف تبدو عملية الإضافة غير عادية؟
BigInteger result = integer.add(BigInteger.valueOf(33333333));
وهذه نقطة أخرى مهمة. لا تستخدم الفئات ذات الأرقام الكبيرة عوامل التشغيل + - * /. وبدلا من ذلك، فإنها توفر مجموعة من الأساليب. دعنا نتعرف على أهمها (كما هو الحال دائمًا، يمكنك العثور على قائمة كاملة بالطرق في وثائق Oracle: هنا
وهنا
) .
-
طرق العمليات الحسابية: add() و subtract() و multiply() و Divide() . وتستخدم هذه الطرق لإجراء عمليات الجمع والطرح والضرب والقسمة على التوالي.
-
يتم استخدام doubleValue() و intValue() و floatValue() و longValue() وما إلى ذلك لتحويل رقم كبير إلى أحد أنواع Java البدائية. كن حذرا عند استخدام هذه الأساليب. لا تنس الاختلافات في حجم البت!
import java.math.BigInteger; public class Main { public static void main(String[] args) { BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"); long result = integer.longValue(); System.out.println(result); } }
إخراج وحدة التحكم:
8198552921648689607
-
تتيح لك min() و max() العثور على الحد الأدنى والحد الأقصى لقيمة رقمين كبيرين.
لاحظ أن هذه الأساليب ليست ثابتة!import java.math.BigInteger; public class Main { public static void main(String[] args) { BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"); BigInteger integer2 = new BigInteger("222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222"); System.out.println(integer.max(integer2)); } }
إخراج وحدة التحكم:
222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
سلوك التقريب BigDecimal
يحتوي هذا الموضوع على قسم منفصل خاص به، نظرًا لأن تقريب الأعداد الكبيرة وتكوين سلوك التقريب ليس بهذه البساطة. يمكنك استخدام طريقة setScale() لتعيين عدد المنازل العشرية لـ BigDecimal . على سبيل المثال، لنفترض أننا نريد أن يتكون الرقم 111.5555555555 من ثلاثة أرقام بعد العلامة العشرية. ومع ذلك، لا يمكننا تحقيق ما نريد عن طريق تمرير الرقم 3 كوسيطة إلى الأسلوب setScale() . كما ذكرنا أعلاه، BigDecimal مخصص لتمثيل الأرقام ذات المتطلبات الصارمة المتعلقة بالدقة الحسابية. في شكله الحالي، يتكون العدد من 10 أرقام بعد العلامة العشرية. نريد إسقاط 7 منهم والاحتفاظ بـ 3 فقط. وعليه، بالإضافة إلى الرقم 3، يجب علينا اجتياز وضع التقريب. يحتوي BigDecimal على إجمالي 8 أوضاع تقريب. هذا كثير! ولكن إذا كنت تريد حقًا ضبط دقة حساباتك، فسيكون لديك كل ما تحتاجه. لذا، إليك أوضاع التقريب الثمانية التي تقدمها BigDecimal :-
ROUND_CEILING — تقريب لأعلى
111.5555555555 -> setScale(3, ROUND_CEILING) -> 111.556
-
ROUND_DOWN — تقريب نحو الصفر
111.5555555555 -> setScale(3, ROUND_DOWN) -> 111.555
-
ROUND_FLOOR — للتقريب للأسفل
111.5555555555 -> setScale(3, ROUND_FLOOR) -> 111.555
-
ROUND_HALF_UP — يتم التقريب للأعلى إذا كان الرقم بعد العلامة العشرية >= 0.5
0.55 -> setScale(1, ROUND_HALF_UP) -> 0.6 0.54 -> setScale(1, ROUND_HALF_UP) -> 0.5
-
ROUND_HALF_DOWN — يتم التقريب للأعلى إذا كان الرقم بعد العلامة العشرية > 0.5
0.55 -> setScale(1, ROUND_HALF_DOWN) -> 0.5 0.56 -> setScale(1, ROUND_HALF_DOWN) -> 0.6
-
ROUND_HALF_EVEN — يعتمد التقريب على الرقم الموجود على يسار العلامة العشرية. إذا كان الرقم الموجود على اليسار زوجي، فسيتم التقريب للأسفل. إذا كان الرقم الموجود على يسار العلامة العشرية فرديًا، فسيتم التقريب للأعلى.
2.5 -> setScale(0, ROUND_HALF_EVEN) -> 2
الرقم الموجود على يسار العلامة العشرية هو 2 (زوجي). تم تقريب الرقم إلى الأسفل. نريد 0 منازل عشرية، وبالتالي فإن النتيجة هي 2.
3.5 -> setScale(0, ROUND_HALF_EVEN) -> 4
الرقم الموجود على يسار العلامة العشرية هو 3 (فردي). تم تقريب الرقم. نريد 0 منازل عشرية، وبالتالي فإن النتيجة هي 4.
-
ROUND_UNNECCESSARY — يتم استخدام هذا الوضع عندما يتعين عليك تمرير وضع التقريب إلى طريقة ما، ولكن لا يلزم تقريب الرقم. إذا حاولت تقريب رقم باستخدام الوضع ROUND_UNNECCESSARY، فسيتم طرح استثناء حسابي.
3.51 -> setScale(1, ROUND_UNNECCESSARY) -> ArithmeticException
-
ROUND_UP — تقريب بعيدًا عن الصفر.
111.5551 -> setScale(3, ROUND_UP) -> 111.556
مقارنة الأعداد الكبيرة
وهذا مهم أيضًا. ستتذكر أننا نستخدم طريقة يساوي () لمقارنة الكائنات في Java. يتم توفير التنفيذ إما عن طريق اللغة نفسها (لفئات Java القياسية) أو يتم تجاوزه بواسطة المبرمج. لكن في حالة كائنات BigDecimal ، لا يُنصح باستخدام طريقة يساوي () لإجراء المقارنات. وذلك لأن التابع BigDecimal.equals() يُرجع صحيحًا فقط إذا كان الرقمان لهما نفس القيمة والمقياس: دعنا نقارن سلوك التابع يساوي () للفئتين Double و BigDecimal :import java.math.BigDecimal;
public class Main {
public static void main(String[] args) {
Double a = 1.5;
Double b = 1.50;
System.out.println(a.equals(b));
BigDecimal x = new BigDecimal("1.5");
BigDecimal y = new BigDecimal("1.50");
System.out.println(x.equals(y));
}
}
إخراج وحدة التحكم:
true
false
كما ترون، بالنسبة لـ BigDecimal ، تبين أن الرقمين 1.5 و 1.50 غير متساويين! كان هذا على وجه التحديد بسبب تفاصيل تنفيذ طريقة يساوي () في فئة BigDecimal . لإجراء مقارنة أكثر دقة بين كائنين من نوع BigDecimal ، من الأفضل استخدام طريقة CompareTo() :
import java.math.BigDecimal;
public class Main {
public static void main(String[] args) {
BigDecimal x = new BigDecimal("1.5");
BigDecimal y = new BigDecimal("1.50");
System.out.println(x.compareTo(y));
}
}
إخراج وحدة التحكم:
0
أعادت طريقة المقارنة () 0، مما يعني أن 1.5 و1.50 متساويان. وهذه هي النتيجة التي توقعناها! :) بهذا نختتم درسنا اليوم. الآن حان الوقت للعودة إلى المهام! :)
GO TO FULL VERSION