التعبيرات والتحويل بين الأنواع والدوال الرياضية
لماذا تعطي 5 / 2 القيمة 2، وكيف تجعل Java تحسب ما تقصده تمامًا؟
في نهاية هذه المحاضرة ستكون قادرًا على
- تحسب أي تعبير وفق أولوية العوامل، وتغيّر ترتيبه بالأقواس
- تتجنب فخ قسمة الأعداد الصحيحة، خصوصًا في حساب المعدل
- تميّز التحويل التلقائي إلى نوع أوسع من التحويل الصريح، وتضع
(int)و(double)في مكانهما الصحيح - تحسب بالحروف، وتصرّح عن الثوابت بالكلمة
final - تستخدم دوال الصنف
Mathوتعرف نوع ما تُرجعه كل دالة - تفسّر مفاجآت الأعداد العشرية والفيضان، وتوظّف
%في مسائل حقيقية
محتويات المحاضرة
- الضرب يسبق الجمع، والأقواس تسبق الجميع
- قسمة عددين صحيحين تعطي عددًا صحيحًا، ويُحذف الكسر
- صندوق
doubleلا ينقذ قسمة صحيحة انتهت قبل أن تصل إليه - تحوّل Java القيمة تلقائيًا إلى نوع أوسع، لأنها لن تفقد شيئًا
- يرفض المترجم وضع
doubleفيintلأن الكسر سيضيع - التحويل الصريح يقول للمترجم: أعرف ما أفعله
- مكان التحويل يحدد هل ينجو الكسر أم لا
- يخزّن
charرقمًا في الحقيقة، ولذلك يمكن الحساب به finalتجعل القيمة ثابتة، ونكتب اسمها بأحرف كبيرة- الصنف
Mathجاهز للحسابات الصعبة، ولا يحتاج إلى استيراد roundوceilوfloorثلاث طرق مختلفة لإزالة الكسر0.1 + 0.2لا تساوي0.3تمامًا، وprintfتخفي الفرق- يفيض
intبصمت حتى في منتصف الحساب %تجيب عن أسئلة حقيقية: زوجي؟ آخر رقم؟ كم ثانية بقيت؟- التمرين النهائي: معدل ثلاث علامات وأعلاها
- أسئلة المراجعة
الضرب يسبق الجمع، والأقواس تسبق الجميع
| الأولوية | العوامل | الترتيب بين المتساوية |
|---|---|---|
| الأولى | ( ) | من الداخل إلى الخارج |
| الثانية | ++ -- (int) (double) | من اليمين إلى اليسار |
| الثالثة | * / % | من اليسار إلى اليمين |
| الرابعة | + - | من اليسار إلى اليمين |
| الأخيرة | = += -= *= /= | من اليمين إلى اليسار |
احسب كل سطر على الورق أولًا. ماذا يطبع البرنامج؟
public class Precedence {
public static void main(String[] args) {
System.out.println(2 + 3 * 4);
System.out.println((2 + 3) * 4);
System.out.println(20 / 2 * 5);
System.out.println(20 / (2 * 5));
System.out.println(10 + 7 % 3);
}
}أظهر الناتج
14 20 50 2 11
لماذا؟ * قبل +، والأقواس تعكس ذلك. و/ و* متساويان، فنبدأ من اليسار: 20 ÷ 2 = 10، ثم × 5 = 50. و% في مستوى الضرب: 7 % 3 = 1، ثم 10 + 1.
زوج من الأقواس يغيّر الجواب
ما معدل 80 و90؟ قارن بين السطرين، ثم غيّر القيمتين إلى 60 و100 وتوقّع الناتج قبل التشغيل.
public class Average {
public static void main(String[] args) {
int a = 80;
int b = 90;
System.out.println(a + b / 2);
System.out.println((a + b) / 2);
}
}125 85
قسمة عددين صحيحين تعطي عددًا صحيحًا، ويُحذف الكسر
تقرر Java نوع النتيجة من نوع الطرفين قبل أن تحسب: int / int يعطي int. فإذا كان أحد الطرفين double، كانت النتيجة double.
الأرقام متقاربة، لكن النتائج ليست كذلك. ماذا يطبع البرنامج؟
public class Division {
public static void main(String[] args) {
System.out.println(5 / 2);
System.out.println(5.0 / 2);
System.out.println(5 / 2.0);
System.out.println(1 / 2);
}
}أظهر الناتج
2 2.5 2.5 0
لماذا؟ الكسر يُحذف ولا يُقرَّب: 5 / 2 تعطي 2 لا 3. ويكفي أن يكون طرف واحد double لتبقى النتيجة بكسرها.
البيتزا والأصدقاء
وزّع 7 قطع على 4 أصدقاء. جرّب قيمًا أخرى، وابحث عن حالة تطبع فيها القسمة الصحيحة 0.
public class Pizza {
public static void main(String[] args) {
int slices = 7;
int friends = 4;
System.out.println(slices / friends);
System.out.println(slices % friends);
System.out.println(slices / 4.0);
}
}1 3 1.75
ما قيمة 9 / 10؟
صندوق double لا ينقذ قسمة صحيحة انتهت قبل أن تصل إليه
المعدل الحقيقي للعددين 4 و5 هو 4.5. ماذا يطبع البرنامج؟
public class AverageTrap {
public static void main(String[] args) {
int a = 4;
int b = 5;
double average = (a + b) / 2;
System.out.println(average);
}
}أظهر الناتج
4.0
لماذا؟ يُحسب الجانب الأيمن أولًا دون النظر إلى نوع الصندوق: 9 / 2 = 4 قسمة صحيحة. بعد ذلك فقط تُخزَّن 4 في double فتصبح 4.0. لقد ضاع الكسر قبل الوصول إلى الصندوق.
الإصلاح الأسهل: اجعل المقسوم عليه 2.0
غيّر 2.0 إلى 2 ولاحظ الفرق. ثم أضف عددًا ثالثًا c وعدّل المعادلة.
public class AverageFixed {
public static void main(String[] args) {
int a = 4;
int b = 5;
double average = (a + b) / 2.0;
System.out.println(average);
}
}4.5
تحوّل Java القيمة تلقائيًا إلى نوع أوسع، لأنها لن تفقد شيئًا
يتسع double لأي قيمة في int، ويتسع int لرمز أي char. لذلك تنقل Java القيمة إلى الصندوق الأوسع دون أن تطلب منها ذلك، ويسمى هذا التحويل التلقائي. ترتيب الأنواع من الأضيق إلى الأوسع: char ثم int ثم long ثم double.
التحويل التلقائي أثناء العمل
اضغط «تتبّع سطرًا سطرًا» وقارن قيمتي الصندوقين whole وdecimal.
public class Widening {
public static void main(String[] args) {
int whole = 7;
double decimal = whole;
System.out.println(decimal);
System.out.println(whole + 0.5);
char letter = 'A';
int code = letter;
System.out.println(code);
}
}7.0 7.5 65
ما نوع نتيجة 3 + 2.0؟
يرفض المترجم وضع double في int لأن الكسر سيضيع
التحويل التلقائي يسير في اتجاه واحد. إذا كان الاتجاه قد يُضيّع جزءًا من القيمة، أوقفك المترجم وطلب منك أن تقرر بنفسك.
سعر في صندوق صحيح
نريد الاحتفاظ بالسعر كاملًا. أصلح نوع المتغير حتى يطبع البرنامج 12.75.
public class Price {
public static void main(String[] args) {
double price = 12.75;
int copy = price;
System.out.println(copy);
}
}incompatible types: possible lossy conversion from double to intأظهر التصحيح
public class Price {
public static void main(String[] args) {
double price = 12.75;
double copy = price;
System.out.println(copy);
}
}12.75
لماذا؟ «lossy» تعني أن هناك ما قد يضيع، وهو هنا .75. ويرفض المترجم السطر حتى لو كانت القيمة 12.0، لأنه ينظر إلى النوع لا إلى القيمة.
أي سطر يرفضه المترجم؟
5.0 من نوع double رغم أن كسرها صفر. أما السطران الأخيران فصحيحان: 5 / 2 من نوع int، وهو يدخل في الصندوقين.التحويل الصريح يقول للمترجم: أعرف ما أفعله
(int) يحذف الكسرلا يقرّب أبدًا: 12.99 تصبح 12، و-3.99 تصبح -3.
int whole = (int) 12.99;(double) يضيف الكسرلا تتغير القيمة، لكن نوعها يتغير، فتتغير طريقة الحساب بها.
double d = (double) 5;جرّب التحويل الصريح
لاحظ أن price لم يتغير بعد التحويل: التحويل ينشئ قيمة جديدة، ولا يبدّل الصندوق الأصلي. اضغط «تتبّع سطرًا سطرًا» وتأكد.
public class Casts {
public static void main(String[] args) {
double price = 12.99;
int whole = (int) price;
System.out.println(whole);
System.out.println(price);
System.out.println((int) -3.99);
System.out.println((double) 5);
}
}12 12.99 -3 5.0
الفرق زوج من الأقواس. ماذا يطبع البرنامج؟
public class CastScope {
public static void main(String[] args) {
System.out.println((int) 3.7 + 0.9);
System.out.println((int) (3.7 + 0.9));
}
}أظهر الناتج
3.9 4
لماذا؟ للتحويل أولوية أعلى من الجمع، فهو يمس القيمة التالية له فقط. في السطر الأول يصبح 3.7 العدد 3، ثم + 0.9. وفي الثاني تُجمع القيمتان أولًا فنحصل على 4.6، ثم يُحذف الكسر.
مكان التحويل يحدد هل ينجو الكسر أم لا
ثلاثة أماكن للتحويل نفسه. ماذا يطبع البرنامج؟
public class CastPlace {
public static void main(String[] args) {
int a = 5;
int b = 2;
System.out.println((double) a / b);
System.out.println(a / (double) b);
System.out.println((double) (a / b));
}
}أظهر الناتج
2.5 2.5 2.0
لماذا؟ في السطرين الأولين يتحول طرف واحد قبل القسمة، فتكون قسمة double. أما في الثالث فتجري القسمة الصحيحة داخل الأقواس أولًا وتعطي 2، ولا يملك التحويل بعدها إلا أن يجعلها 2.0.
معدل في صندوق صحيح
نريد حذف الكسر عمدًا والاحتفاظ بالجزء الصحيح من المعدل. استخدم تحويلًا صريحًا حتى يطبع البرنامج 4.
public class WholeAverage {
public static void main(String[] args) {
int sum = 9;
int average = sum / 2.0;
System.out.println(average);
}
}possible lossy conversion from double to intأظهر التصحيح
public class WholeAverage {
public static void main(String[] args) {
int sum = 9;
int average = (int) (sum / 2.0);
System.out.println(average);
}
}4
لماذا؟ sum / 2.0 من نوع double، فلا تدخل في int دون إذن. لاحظ الأقواس: دونها يطبق التحويل على sum وحده، وتبقى النتيجة double فيبقى الخطأ.
معدل دقيق لعددين صحيحين
اطبع First: واقرأ عددًا صحيحًا في متغير int، ثم Second: واقرأ عددًا صحيحًا آخر. ثم اطبع Average: متبوعة بالمعدل الدقيق، باستخدام تحويل صريح.
import java.util.Scanner;
public class ExactAverage {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
// Read two int values, then print their exact average
}
}4 5
First: Second: Average: 4.5
تلميح 1
اجمع أولًا داخل أقواس، ثم حوّل المجموع: (double) (a + b).
تلميح 2
إذا طبع البرنامج 4.0 فالتحويل جاء بعد القسمة.
الحل
import java.util.Scanner;
public class ExactAverage {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("First: ");
int a = input.nextInt();
System.out.print("Second: ");
int b = input.nextInt();
double average = (double) (a + b) / 2;
System.out.println("Average: " + average);
}
}يخزّن char رقمًا في الحقيقة، ولذلك يمكن الحساب به
| الحرف | الرمز |
|---|---|
'A' | 65 |
'B' | 66 |
'a' | 97 |
'0' | 48 |
الحساب بالحروف
غيّر letter إلى 'Z' ثم إلى 'a'، وتوقّع الناتج قبل كل تشغيل.
public class CharMath {
public static void main(String[] args) {
char letter = 'A';
System.out.println(letter + 1);
System.out.println((char) (letter + 1));
letter++;
System.out.println(letter);
System.out.println('7' - '0');
System.out.println('a' - 'A');
}
}66 B B 7 32
أين الفرق بين السطرين؟
public class CharPlus {
public static void main(String[] args) {
System.out.println('A' + 'B');
System.out.println("" + 'A' + 'B');
}
}أظهر الناتج
131 AB
لماذا؟ + بين حرفين تعني جمعهما عددين: 65 + 66. أما مع نص، ولو كان فارغًا، فتعني الدمج. ولأن Java تقرأ من اليسار إلى اليمين، يصبح الناتج نصًا بعد الخطوة الأولى، فيُدمج الحرف الثاني أيضًا.
الحرف التالي
نريد الحرف الذي يلي A. أصلح السطر حتى يطبع البرنامج B.
public class NextLetter {
public static void main(String[] args) {
char letter = 'A';
char next = letter + 1;
System.out.println(next);
}
}possible lossy conversion from int to charأظهر التصحيح
public class NextLetter {
public static void main(String[] args) {
char letter = 'A';
char next = (char) (letter + 1);
System.out.println(next);
}
}B
لماذا؟ char + int يعطي int، وint أوسع من char، فنحتاج إلى تحويل صريح. وهذا هو الخطأ نفسه الذي رأيناه مع double، باتجاه آخر من الأنواع.
final تجعل القيمة ثابتة، ونكتب اسمها بأحرف كبيرة
الرقم 0.16 في وسط معادلة لا يقول شيئًا لمن يقرؤه. أما TAX_RATE فتشرح نفسها، وإذا تغيرت الضريبة فسنعدّل سطرًا واحدًا.
ثابت واحد يُستخدم عدة مرات
غيّر قيمة TAX_RATE إلى 0.2 في سطر واحد، ولاحظ كيف تتغير كل النتائج.
public class Tax {
public static void main(String[] args) {
final double TAX_RATE = 0.16;
double price = 100.0;
double tax = price * TAX_RATE;
System.out.println(tax);
System.out.println(price + tax);
}
}16.0 116.0
| الاسم | الاستخدام | القاعدة |
|---|---|---|
studentAge | متغير | camelCase |
TAX_RATE | ثابت | أحرف كبيرة، وبين الكلمات _ |
MAX_STUDENTS | ثابت | أحرف كبيرة، وبين الكلمات _ |
الثابت لا يتغير
لا نريد تغيير الضريبة هنا. احذف السطر الذي يخالف ذلك.
public class FinalRate {
public static void main(String[] args) {
final double TAX_RATE = 0.16;
TAX_RATE = 0.2;
System.out.println(TAX_RATE);
}
}cannot assign a value to final variable TAX_RATEأظهر التصحيح
public class FinalRate {
public static void main(String[] args) {
final double TAX_RATE = 0.16;
System.out.println(TAX_RATE);
}
}0.16
لماذا؟ هذه فائدة final: يمنعك المترجم من تغيير القيمة بالخطأ، بدل أن تكتشف ذلك من نتائج خاطئة لاحقًا.
الصنف Math جاهز للحسابات الصعبة، ولا يحتاج إلى استيراد
| الاستخدام | المعنى | الناتج | النوع |
|---|---|---|---|
Math.pow(2, 10) | 2 أس 10 | 1024.0 | double |
Math.sqrt(16) | الجذر التربيعي | 4.0 | double |
Math.abs(-7) | القيمة المطلقة | 7 | نوع المعامل |
Math.max(3, 9) | الأكبر | 9 | نوع المعامل |
Math.min(3, 9) | الأصغر | 3 | نوع المعامل |
Math.PI | ثابت جاهز | 3.141592653589793 | double |
جولة في Math
لاحظ أن Math.PI مكتوب بأحرف كبيرة لأنه ثابت، ودون أقواس لأنه ليس دالة. غيّر القيم وتوقّع الناتج.
public class MathTour {
public static void main(String[] args) {
System.out.println(Math.pow(2, 10));
System.out.println(Math.sqrt(16));
System.out.println(Math.abs(-7));
System.out.println(Math.max(3, 9));
System.out.println(Math.min(3, 9));
System.out.println(Math.PI);
}
}1024.0 4.0 7 9 3 3.141592653589793
وتر المثلث القائم
جرّب 3 و4، ثم 5 و12، ثم قيمًا من اختيارك. يعتمد الحساب على a وb كما كتبتهما أنت.
import java.util.Scanner;
public class Hypotenuse {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Side a: ");
double a = input.nextDouble();
System.out.print("Side b: ");
double b = input.nextDouble();
double c = Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2));
System.out.println("Hypotenuse: " + c);
}
}pow تُرجع double
أصلح السطر بتحويل صريح حتى يطبع البرنامج 8.
public class Power {
public static void main(String[] args) {
int result = Math.pow(2, 3);
System.out.println(result);
}
}possible lossy conversion from double to intأظهر التصحيح
public class Power {
public static void main(String[] args) {
int result = (int) Math.pow(2, 3);
System.out.println(result);
}
}8
لماذا؟ القيمتان 2 و3 عددان صحيحان، لكن ما يحدد النوع هو ما تُرجعه الدالة: Math.pow تُرجع double دائمًا.
round وceil وfloor ثلاث طرق مختلفة لإزالة الكسر
| الدالة | تفعل | 2.1 | 2.5 | -2.5 | تُرجع |
|---|---|---|---|---|---|
Math.round | إلى الأقرب | 2 | 3 | -2 | long |
Math.ceil | إلى الأعلى | 3.0 | 3.0 | -2.0 | double |
Math.floor | إلى الأسفل | 2.0 | 2.0 | -3.0 | double |
(int) | حذف الكسر | 2 | 2 | -2 | int |
قارن بين الطرق. ماذا يطبع البرنامج؟
public class Rounding {
public static void main(String[] args) {
double value = 2.7;
System.out.println(Math.round(value));
System.out.println(Math.ceil(value));
System.out.println(Math.floor(value));
System.out.println((int) value);
}
}أظهر الناتج
3 3.0 2.0 2
لماذا؟ round تعطي عددًا صحيحًا، وceil وfloor تعطيان double دائمًا، ولذلك يظهر .0. ولا تخلط بين floor و(int): يتفقان في الأعداد الموجبة ويختلفان في السالبة.
متى نحتاج إلى ceil؟
23 طالبًا، وفي كل سيارة 4 مقاعد. كم سيارة نحتاج؟ لاحظ (double) قبل القسمة. ثم غيّر عدد الطلاب إلى 21 وبدّل ceil إلى round: لماذا يبقى طالب دون مقعد؟
public class Cars {
public static void main(String[] args) {
int students = 23;
int seats = 4;
double cars = Math.ceil((double) students / seats);
System.out.println(cars);
}
}6.0
مساحة الدائرة
اطبع Radius: واقرأ نصف القطر عددًا عشريًا، ثم اطبع Area: متبوعة بالمساحة برقمين عشريين. استخدم Math.PI وMath.pow.
import java.util.Scanner;
public class CircleArea {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
// Read the radius, calculate the area, print with printf
}
}1
Radius: Area: 3.14
تلميح 1
المساحة تساوي Math.PI * Math.pow(radius, 2).
تلميح 2
استخدم القالب "Area: %.2f%n".
الحل
import java.util.Scanner;
public class CircleArea {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Radius: ");
double radius = input.nextDouble();
double area = Math.PI * Math.pow(radius, 2);
System.out.printf("Area: %.2f%n", area);
}
}0.1 + 0.2 لا تساوي 0.3 تمامًا، وprintf تخفي الفرق
الحاسوب يخطئ في الجمع؟
توقّع السطر الأول قبل التشغيل. لاحظ أن printf غيّرت شكل العرض فقط: السطر الثالث يثبت أن total لم يتغير.
public class FloatSurprise {
public static void main(String[] args) {
double total = 0.1 + 0.2;
System.out.println(total);
System.out.printf("%.2f%n", total);
System.out.println(total);
System.out.println(Math.round(total * 100) / 100.0);
}
}0.30000000000000004 0.30 0.30000000000000004 0.3
لا يمكن كتابة 1 ÷ 3 في النظام العشري بدقة تامة: 0.333 ثم لا تنتهي. وكذلك لا يمكن كتابة 0.1 بدقة تامة في النظام الثنائي الذي يستخدمه الحاسوب، فيخزَّن أقرب رقم ممكن. هذا سلوك كل لغات البرمجة، وليس خطأ في Java.
printf تقرّب، و(int) تحذف. ماذا يطبع البرنامج؟
public class RoundOrCut {
public static void main(String[] args) {
double value = 2.96;
System.out.printf("%.1f%n", value);
System.out.println((int) value);
System.out.println(1.1 * 3);
}
}أظهر الناتج
3.0 2 3.3000000000000003
لماذا؟ تعرض printf القيمة مقرّبة إلى رقم عشري واحد، بينما يحذف (int) الكسر كله. والسطر الأخير مفاجأة أخرى من النوع نفسه، لأن 1.1 مخزَّنة تقريبيًا أيضًا.
يفيض int بصمت حتى في منتصف الحساب
رأينا في محاضرة المتغيرات أن إضافة 1 إلى أكبر int تعطي عددًا سالبًا. ولا يعترض المترجم على ذلك، ولا يتوقف البرنامج: يظهر رقم خاطئ فقط.
يتسع long لمليون × مليون. ماذا يطبع البرنامج؟
public class Overflow {
public static void main(String[] args) {
long wrong = 1000000 * 1000000;
long right = 1000000L * 1000000;
System.out.println(wrong);
System.out.println(right);
}
}أظهر الناتج
-727379968 1000000000000
لماذا؟ إنه فخ المعدل نفسه: يُحسب الجانب الأيمن قبل النظر إلى الصندوق. فالضرب في السطر الأول int * int ويفيض قبل الوصول إلى long. والحرف L يجعل أحد الطرفين long، فيتم الضرب كله بالنوع الأوسع.
كم ثانية في حياتك؟
السطر الأول يبدو سليمًا، لكنه تجاوز حد int. احذف الحرف L من السطر الثاني وشغّله، ثم عدّل العمر إلى عمرك.
public class Seconds {
public static void main(String[] args) {
int age = 100;
int shortAnswer = age * 365 * 24 * 60 * 60;
long longAnswer = age * 365L * 24 * 60 * 60;
System.out.println(shortAnswer);
System.out.println(longAnswer);
}
}-1141367296 3153600000
% تجيب عن أسئلة حقيقية: زوجي؟ آخر رقم؟ كم ثانية بقيت؟
الباقي بعد القسمة على 2 هو 0 للزوجي و1 للفردي.
n % 2الباقي بعد القسمة على 10 هو الرقم الأخير، والقسمة الصحيحة على 10 تحذفه.
n % 10
n / 10القسمة الصحيحة تعطي الدقائق الكاملة، والباقي يعطي الثواني المتبقية.
total / 60
total % 60فكّك عددًا
اكتب 12345، ثم 7، ثم 100. ما الذي تخبرك به Even check عن العدد؟ ستحتاج إلى هذه الفكرة في شرط if قريبًا.
import java.util.Scanner;
public class Digits {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("A whole number: ");
int number = input.nextInt();
System.out.println("Even check: " + number % 2);
System.out.println("Last digit: " + number % 10);
System.out.println("Without last digit: " + number / 10);
}
}فكّر في كل سطر: ماذا يطبع البرنامج؟
public class ModuloUses {
public static void main(String[] args) {
int number = 2468;
System.out.println(number % 2);
System.out.println(number % 10);
System.out.println(number % 100);
System.out.println(number / 100);
}
}أظهر الناتج
0 8 68 24
لماذا؟ يعطي % 10 آخر رقم، ويعطي % 100 آخر رقمين. و/ 100 قسمة صحيحة تحذف الرقمين الأخيرين. وكلما زادت الأصفار في العدد الذي نقسم عليه، زاد عدد الأرقام.
دقائق وثوانٍ
اطبع Seconds: واقرأ عددًا صحيحًا، ثم اطبع الناتج بالشكل 3 min 5 sec. فمثلًا 185 ثانية هي 3 دقائق و5 ثوانٍ.
import java.util.Scanner;
public class SplitSeconds {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
// Read the total, split it with / and %, then print
}
}185
Seconds: 3 min 5 sec
تلميح 1
في كل دقيقة 60 ثانية، فالدقائق هي total / 60.
تلميح 2
الثواني المتبقية هي total % 60.
الحل
import java.util.Scanner;
public class SplitSeconds {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Seconds: ");
int total = input.nextInt();
int minutes = total / 60;
int seconds = total % 60;
System.out.println(minutes + " min " + seconds + " sec");
}
}التمرين النهائي: معدل ثلاث علامات وأعلاها
ملخص العلامات
اقرأ ثلاث علامات صحيحة بالرسائل Mark 1: وMark 2: وMark 3: . ثم اطبع Average: متبوعة بالمعدل برقمين عشريين على سطر، وHighest: متبوعة بأعلى علامة على السطر التالي.
import java.util.Scanner;
public class MarksSummary {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
// Read three marks, then print the average and the highest
}
}80 90 85
Mark 1: Mark 2: Mark 3: Average: 85.00 Highest: 90
تلميح 1
اقسم على 3.0، وإلا فسيضيع الكسر قبل وصوله إلى printf.
تلميح 2
تأخذ Math.max قيمتين فقط، لكن يمكن وضع إحداهما داخل الأخرى: Math.max(a, Math.max(b, c)).
الحل
import java.util.Scanner;
public class MarksSummary {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Mark 1: ");
int a = input.nextInt();
System.out.print("Mark 2: ");
int b = input.nextInt();
System.out.print("Mark 3: ");
int c = input.nextInt();
double average = (a + b + c) / 3.0;
int highest = Math.max(a, Math.max(b, c));
System.out.printf("Average: %.2f%n", average);
System.out.println("Highest: " + highest);
}
}أسئلة المراجعة
أي سطر يعطي معدل a وb بدقة، إذا كان كلاهما int؟
b وحدها.لماذا يرفض المترجم السطر int r = Math.sqrt(16);؟
أي تصريح يتبع العرف الصحيح لثابت؟
final هي التي تمنع التغيير، والاسم بالأحرف الكبيرة يخبر القارئ بذلك. والخيار الأوسط يعمل لكنه يخفي أنه ثابت، والأخير يوهم بالثبات دون حماية.اجمع ما تعلمته اليوم. ماذا يطبع البرنامج؟
public class ReviewMixed {
public static void main(String[] args) {
int a = 7;
int b = 2;
System.out.println(a / b + 0.5);
System.out.println((double) a / b + 0.5);
System.out.println(a % b * 10);
}
}أظهر الناتج
3.5 4.0 10
لماذا؟ السطر الأول: 7 / 2 = 3 قسمة صحيحة، ثم + 0.5. والثاني: (double) a تحوّل قبل القسمة، فتعطي 3.5، ثم + 0.5. والثالث: % و* متساويان، فمن اليسار: 7 % 2 = 1، ثم × 10.