نوع بدائي | الحجم في الذاكرة | مدى من القيم |
---|---|---|
بايت | 8 بت | -128 إلى 127 |
قصير | 16 بت | إلى -32768 إلى 32767 |
شار | 16 بت | من 0 إلى 65536 |
كثافة العمليات | 32 بت | من -2147483648 إلى 2147483647 |
طويل | 64 بت | من -9223372036854775808 إلى 9223372036854775807 |
يطفو | 32 بت | من (2 إلى الأس -149) إلى ((2-2 إلى الأس -23)*2 إلى الأس 127) |
مزدوج | 64 بت | من (-2 إلى الأس 63) إلى ((2 إلى الأس 63) - 1) |
منطقية | 8 (عند استخدامها في المصفوفات)، 32 (عند استخدامها في غير المصفوفات) | صحيحة أو خاطئة |
BigInteger
غير BigDecimal
محدود عمليا. ما هي هذه الفئات المستخدمة ل؟ بادئ ذي بدء، للحسابات ذات متطلبات الدقة العالية للغاية. هناك، على سبيل المثال، برامج يمكن أن تعتمد فيها حياة الإنسان على دقة الحسابات (برامج الطائرات والصواريخ أو المعدات الطبية). لذلك، إذا كانت العلامة العشرية رقم 150 تلعب دورًا مهمًا، BigDecimal
فهي الخيار الأفضل. بالإضافة إلى ذلك، يتم استخدام هذه الأشياء في كثير من الأحيان في عالم التمويل، حيث تكون دقة الحسابات حتى أصغر القيم مهمة للغاية أيضًا. كيفية العمل مع الأشياء BigInteger
وما BigDecimal
هو المهم أن تتذكرها؟ يتم إنشاء كائنات هذه الفئات على النحو التالي:
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
، وبطريقة ما نحتاج أن نشرح للمترجم بالضبط الرقم الذي نريد الحصول عليه :) فقط قم بتمرير الرقم 11111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 لا تعمل: ستحاول Java القيام بذلك "تناسب" الرقم الذي تم تمريره مع أحد أنواع البيانات البدائية، لكنه لن يتناسب مع أي منها. لذلك، يعد استخدام سلسلة لتمرير الرقم المطلوب خيارًا جيدًا. يمكن لكلا الفئتين استخراج القيم الرقمية تلقائيًا من السلاسل التي تم تمريرها. هناك نقطة أخرى مهمة يجب تذكرها عند العمل مع فئات ذات أعداد كبيرة، وهي أن كائناتها غير قابلة للتغيير ( Immutable
) . أنت بالفعل على دراية جيدة بمبدأ الثبات من خلال مثال الطبقة String
والفئات المجمعة للأوليات (عدد صحيح وطويل وغيرها).
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);
}
}
إخراج وحدة التحكم:
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
أرقامنا لم تتغير كما تتوقع لكي تنجح عملية الإضافة، يجب عليك إنشاء كائن جديد وتعيين نتيجة الإضافة إليه.
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);
}
}
إخراج وحدة التحكم:
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111144444444
الآن كل شيء يعمل كما ينبغي :) بالمناسبة، هل لاحظت كيف تبدو عملية الإضافة غير عادية؟
BigInteger result = integer.add(BigInteger.valueOf(33333333));
وهذه نقطة أخرى مهمة. لا تستخدم فئات الأعداد الكبيرة عوامل التشغيل +-*/ في عملياتها، ولكنها توفر بدلاً من ذلك مجموعة من الأساليب. دعونا نلقي نظرة على أهمها (يمكنك، كما هو الحال دائمًا، العثور على قائمة كاملة بالطرق في وثائق Oracle: هنا وهنا ).
-
طرق إجراء العمليات الحسابية :
add()
,subtract()
,multiply()
.divide()
تستخدم في عمليات الجمع والطرح والضرب والقسمة على التوالي. -
doubleValue()
،intValue()
،floatValue()
،longValue()
إلخ. - يستخدم لتحويل عدد كبير إلى نوع جافا البدائي. كن حذرًا عند استخدامها وتذكر الفرق في السعة!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
تم تضمين هذا الموضوع في قسم منفصل، حيث أن تقريب الأعداد الكبيرة وتعديلها ليس بالأمر السهل. يمكنك ضبط عدد المنازل العشرية لرقم ماBigDecimal
باستخدام setScale()
. على سبيل المثال، نريد ضبط دقة الرقم 111.5555555555 على ثلاث منازل عشرية. ومع ذلك، لن نتمكن من تمرير الرقم 3 كوسيطة للطريقة setScale()
وبالتالي حل مشكلتنا. كما ذكر أعلاه، BigDecimal
هذه أرقام للحسابات ذات الدقة المتزايدة. في صورته الحالية، يتكون العدد من ١٠ منازل عشرية. نريد التخلص من 7 منهم وترك 3 فقط. لذلك، بالإضافة إلى الرقم 3، يجب علينا تمرير وضع التقريب كمعلمة . هناك 8 أوضاع تقريب في المجموع BigDecimal
. كثيرا نوعا ما! ولكن إذا كنت بحاجة إلى ضبط دقة الحسابات في البرنامج، فسيكون لديك كل ما تحتاجه لذلك. لذا، إليك أوضاع التقريب الثمانية المتوفرة في 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
- التقريب إذا كان الرقم بعد العلامة العشرية >= .50.55 -> setScale(1, ROUND_HALF_UP) -> 0.6 0.54 -> setScale(1, ROUND_HALF_UP) -> 0.5
-
ROUND_HALF_DOWN
- التقريب إذا كان الرقم بعد العلامة العشرية > .50.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، فسيتم طرح استثناء ArithmeticException.3.51 -> setScale(1, ROUND_UNNECCESSARY) -> ArithmeticException
-
ROUND_UP
- التقريب.111.5551 -> setScale(3, ROUND_UP) -> 111.556
مقارنة الأعداد الكبيرة
هذا السؤال مهم أيضا. أنت تتذكر بالفعل أن هذه الطريقة تُستخدم لمقارنة الكائنات في Javaequals()
. يتم توفيره إما بواسطة اللغة نفسها (في حالة فئات Java المضمنة) أو يتم تجاوزه بواسطة المبرمج. ولكن في حالة كائنات الفئة، لا ينصح BigDecimal
باستخدام الطريقة equals()
للمقارنة. والسبب في ذلك هو أن BigDecimal.equals()
الطريقة ذات الرقمين تُرجع صحيحة فقط إذا كان الرقمان لهما نفس القيمة والمقياس : دعنا نقارن سلوك الطريقتين equals()
y Double
و y 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
كما ترون، تبين أن الأرقام 1.5 و 1.50 في حالة c BigDecimal
غير متساوية! حدث هذا على وجه التحديد بسبب تفاصيل الطريقة equals()
في الفصل 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
أعادت الطريقة compareTo()
0، وهو ما يعني يساوي 1.5 و 1.50. هذه هي النتيجة التي كنا نعول عليها! :) بهذا نختتم درسنا لهذا اليوم. حان الوقت للعودة إلى المهام! :)
GO TO FULL VERSION