الأعداد والقيم المنطقية وتحويل الأنواع
الأعداد في Dart
تمتلك Dart ثلاثة أنواع رقمية تشكل تسلسلاً هرمياً: num هو النوع الأب مع int و double كأبنائه. فهم متى تستخدم كل نوع ضروري لكتابة كود Dart صحيح وفعال.
التسلسل الهرمي لأنواع الأعداد
// num هو الأب لكل من int و double
num anyNumber = 42; // يمكنه حمل int
anyNumber = 3.14; // يمكنه أيضاً حمل double
int wholeNumber = 42; // أعداد صحيحة فقط
double decimalNumber = 3.14; // أعداد عشرية فقط
الأعداد الصحيحة (int)
الأعداد الصحيحة تمثل أرقاماً كاملة بدون فاصلة عشرية. على المنصات الأصلية (الهاتف وسطح المكتب) الأعداد الصحيحة في Dart هي قيم 64-بت بإشارة مما يعطي نطاقاً من حوالي -9.2 كوينتيليون إلى 9.2 كوينتيليون.
العمل مع الأعداد الصحيحة
void main() {
int age = 28;
int negative = -100;
int zero = 0;
// صيغ مختلفة للأعداد الصحيحة
int decimal = 255;
int hex = 0xFF; // 255 بالست عشري
int binary = 0b11111111; // 255 بالثنائي
print(decimal == hex); // true
print(hex == binary); // true
// أعداد كبيرة مع فواصل سفلية للقراءة
int population = 7_900_000_000;
int bytes = 1_073_741_824;
print(population); // 7900000000
print(bytes); // 1073741824
}
_) في الأعداد الكبيرة لتحسين القراءة. يتجاهلها Dart تماماً -- 1_000_000 هي نفسها 1000000 بالضبط.الأعداد العشرية (double)
الأعداد العشرية تمثل أرقام الفاصلة العائمة 64-بت وفق معيار IEEE 754. يمكنها حمل قيم كسرية وأعداد كبيرة جداً وأعداد صغيرة جداً باستخدام الترميز العلمي.
العمل مع الأعداد العشرية
void main() {
double pi = 3.14159265;
double price = 29.99;
double tiny = 0.001;
double negative = -273.15;
// الترميز العلمي
double speed = 3.0e8; // 300,000,000 (سرعة الضوء م/ث)
double small = 1.6e-19; // 0.00000000000000000016
print(speed); // 300000000.0
print(small); // 1.6e-19
// عدد صحيح مُسند لـ double يصبح double تلقائياً
double value = 42; // يُخزن كـ 42.0
print(value); // 42.0
}
0.1 + 0.2 يساوي 0.30000000000000004 وليس 0.3. للحسابات المالية فكر في العمل بالأعداد الصحيحة (القروش بدلاً من الريالات).خصائص ودوال الأعداد المفيدة
خصائص الأعداد
void main() {
int number = -42;
double decimal = 3.7;
// الخصائص
print(number.isNegative); // true
print(number.isEven); // true
print(number.isOdd); // false
print(decimal.isFinite); // true
print(decimal.isInfinite); // false
print(decimal.isNaN); // false
}
دوال الأعداد
void main() {
double value = 3.7;
// التقريب
print(value.round()); // 4 (أقرب عدد صحيح)
print(value.floor()); // 3 (تقريب لأسفل)
print(value.ceil()); // 4 (تقريب لأعلى)
print(value.truncate()); // 3 (حذف الجزء العشري)
// القيمة المطلقة
print((-42).abs()); // 42
// الحصر في نطاق
int score = 150;
print(score.clamp(0, 100)); // 100 (محصور بالحد الأقصى)
// تنسيق الأعداد العشرية
double pi = 3.14159265;
print(pi.toStringAsFixed(2)); // 3.14
print(pi.toStringAsPrecision(4)); // 3.142
}
العوامل الحسابية
يدعم Dart جميع العوامل الحسابية القياسية:
الحساب الأساسي
void main() {
int a = 10;
int b = 3;
print(a + b); // 13 (جمع)
print(a - b); // 7 (طرح)
print(a * b); // 30 (ضرب)
print(a / b); // 3.3333... (قسمة -- تُرجع دائماً double)
print(a ~/ b); // 3 (قسمة صحيحة -- تقطع)
print(a % b); // 1 (باقي القسمة)
}
/ يُرجع دائماً double في Dart حتى عند قسمة عددين صحيحين. استخدم ~/ (القسمة المقطوعة) عندما تريد نتيجة صحيحة.مكتبة dart:math
للعمليات الرياضية المتقدمة استورد مكتبة dart:math:
استخدام dart:math
import 'dart:math';
void main() {
// الثوابت
print(pi); // 3.141592653589793
print(e); // 2.718281828459045
// الأس والجذر التربيعي
print(pow(2, 10)); // 1024
print(sqrt(144)); // 12.0
// الأصغر والأكبر
print(min(5, 10)); // 5
print(max(5, 10)); // 10
// أعداد عشوائية
var random = Random();
print(random.nextInt(100)); // 0-99
print(random.nextDouble()); // 0.0-1.0
print(random.nextBool()); // true أو false
}
القيم المنطقية (bool)
نوع bool له قيمتان فقط: true و false. على عكس JavaScript لا تمتلك Dart قيماً صادقة وكاذبة ضمنية. فقط قيم bool الفعلية يمكن استخدامها في الشروط.
أساسيات القيم المنطقية
void main() {
bool isActive = true;
bool isAdmin = false;
// الاستخدام المباشر في الشروط
if (isActive) {
print('المستخدم نشط');
}
// Dart لا تملك truthy/falsy مثل JavaScript
// if (1) { ... } // خطأ! 1 ليس bool
// if ('hello') { ... } // خطأ! String ليس bool
// يجب المقارنة صراحة
int count = 5;
if (count > 0) { // هذا يعمل -- المقارنة تُرجع bool
print('يحتوي على عناصر');
}
}
0 أو "" أو null إلى false. يجب دائماً استخدام تعبيرات منطقية صريحة في الشروط.العوامل المنطقية
المنطق البولياني
void main() {
bool a = true;
bool b = false;
// AND -- كلاهما يجب أن يكون true
print(a && b); // false
print(a && a); // true
// OR -- واحد على الأقل يجب أن يكون true
print(a || b); // true
print(b || b); // false
// NOT -- يعكس القيمة
print(!a); // false
print(!b); // true
// مثال عملي
int age = 25;
bool hasLicense = true;
bool canDrive = age >= 18 && hasLicense;
print('يمكنه القيادة: \$canDrive'); // يمكنه القيادة: true
}
عوامل المقارنة
عوامل المقارنة تُرجع قيماً منطقية وتُستخدم بكثرة في الشروط:
جميع عوامل المقارنة
void main() {
int x = 10;
int y = 20;
print(x == y); // false (يساوي)
print(x != y); // true (لا يساوي)
print(x > y); // false (أكبر من)
print(x < y); // true (أصغر من)
print(x >= 10); // true (أكبر أو يساوي)
print(x <= 20); // true (أصغر أو يساوي)
}
تحويل الأنواع
التحويل بين الأنواع مهمة شائعة في Dart. إليك جميع التحويلات المهمة التي تحتاج معرفتها:
بين أنواع الأعداد
تحويل int و double
void main() {
// int إلى double
int whole = 42;
double asDouble = whole.toDouble();
print(asDouble); // 42.0
// double إلى int (يقطع الجزء العشري)
double decimal = 9.99;
int asInt = decimal.toInt();
print(asInt); // 9 (لا يُقرّب!)
// double إلى int (مُقرّب)
int rounded = decimal.round();
print(rounded); // 10
}
الأعداد إلى نصوص
عدد إلى نص
void main() {
int count = 42;
double price = 9.99;
// تحويل أساسي
String countStr = count.toString();
String priceStr = price.toString();
print(countStr); // '42'
print(priceStr); // '9.99'
// تحويل منسق
print(price.toStringAsFixed(1)); // '10.0'
print(price.toStringAsFixed(3)); // '9.990'
}
النصوص إلى أعداد
نص إلى عدد (آمن مقابل غير آمن)
void main() {
// غير آمن -- يطرح FormatException على مدخل غير صالح
int a = int.parse('42');
double b = double.parse('3.14');
// آمن -- يُرجع null على مدخل غير صالح
int? c = int.tryParse('abc');
print(c); // null
// نمط: tryParse مع قيمة بديلة
String userInput = 'ليس رقماً';
int value = int.tryParse(userInput) ?? 0;
print(value); // 0 (القيمة البديلة)
}
تحويلات القيم المنطقية
تحويل القيم المنطقية من/إلى أنواع أخرى
void main() {
// Bool إلى String
bool active = true;
String activeStr = active.toString();
print(activeStr); // 'true'
// String إلى Bool (يدوياً)
String input = 'true';
bool parsed = input.toLowerCase() == 'true';
print(parsed); // true
// رقم إلى bool
int status = 1;
bool isActive = status == 1;
print(isActive); // true
// Bool إلى int
bool flag = true;
int flagInt = flag ? 1 : 0;
print(flagInt); // 1
}
العوامل المدركة للقيم الفارغة
عند العمل مع تحويلات الأنواع يمكن أن تكون القيم null غالباً. يوفر Dart عوامل مدركة للقيم الفارغة للتعامل مع هذا بأناقة:
العوامل المدركة للقيم الفارغة مع التحويلات
void main() {
// ?? -- توفير قيمة افتراضية إذا كانت null
int? parsed = int.tryParse('abc');
int value = parsed ?? 0;
print(value); // 0
// اختصار في سطر واحد
int age = int.tryParse('25') ?? 0;
print(age); // 25
int invalid = int.tryParse('مرحبا') ?? -1;
print(invalid); // -1
}
مثال عملي: بناء آلة حاسبة
آلة حاسبة مصغرة
import 'dart:math';
void main() {
double a = 15.0;
double b = 4.0;
print('--- الآلة الحاسبة ---');
print('\$a + \$b = ${a + b}'); // 19.0
print('\$a - \$b = ${a - b}'); // 11.0
print('\$a * \$b = ${a * b}'); // 60.0
print('\$a / \$b = ${(a / b).toStringAsFixed(2)}'); // 3.75
print('\$a % \$b = ${a % b}'); // 3.0
print('\$a ^ \$b = ${pow(a, b)}'); // 50625.0
print('جذر(\$a) = ${sqrt(a).toStringAsFixed(4)}'); // 3.8730
}
تمرين عملي
افتح DartPad وأنشئ برنامجاً: (1) أعلن عن متغيرين صحيحين ومتغيرين عشريين. (2) نفذ جميع العمليات الحسابية (+، -، *، /، ~/، %) واطبع النتائج. (3) استخدم dart:math لحساب الجذر التربيعي والأس لعدد. (4) حوّل سعراً عشرياً إلى عدد صحيح باستخدام round() و floor() و ceil() وقارن النتائج. (5) استخدم tryParse مع عامل ?? لتحويل نص إلى عدد بأمان مع قيمة بديلة.