Integers and Floating-Point Numbers
الأعداد الصحيحة والقيم العشرية هي اللبنات الأساسية للحسابات والعمليات الحسابية. تُعرف التمثيلات المدمجة لمثل هذه القيم باسم البدائيات العددية، بينما تُعرف تمثيلات الأعداد الصحيحة والأعداد العشرية كقيم فورية في الشيفرة باسم الأدبيات العددية. على سبيل المثال، 1
هو أدب عدد صحيح، بينما 1.0
هو أدب عدد عشري؛ وتمثيلها الثنائي في الذاكرة ككائنات هو بدائيات عددية.
تقدم جوليا مجموعة واسعة من الأنواع الرقمية الأولية، ويتم تعريف مجموعة كاملة من العمليات الحسابية وعمليات بت كما يتم تعريف الدوال الرياضية القياسية عليها. هذه تتطابق مباشرة مع الأنواع الرقمية والعمليات المدعومة بشكل أصلي على الحواسيب الحديثة، مما يسمح لجوليا بالاستفادة الكاملة من الموارد الحاسوبية. بالإضافة إلى ذلك، توفر جوليا دعمًا برمجيًا لـ Arbitrary Precision Arithmetic، والذي يمكنه التعامل مع العمليات على القيم الرقمية التي لا يمكن تمثيلها بشكل فعال في تمثيلات الأجهزة الأصلية، ولكن على حساب أداء أبطأ نسبيًا.
الأنواع الرقمية البدائية لجوليا هي:
- أنواع الأعداد الصحيحة:
Type | Signed? | Number of bits | Smallest value | Largest value |
---|---|---|---|---|
Int8 | ✓ | 8 | -2^7 | 2^7 - 1 |
UInt8 | 8 | 0 | 2^8 - 1 | |
Int16 | ✓ | 16 | -2^15 | 2^15 - 1 |
UInt16 | 16 | 0 | 2^16 - 1 | |
Int32 | ✓ | 32 | -2^31 | 2^31 - 1 |
UInt32 | 32 | 0 | 2^32 - 1 | |
Int64 | ✓ | 64 | -2^63 | 2^63 - 1 |
UInt64 | 64 | 0 | 2^64 - 1 | |
Int128 | ✓ | 128 | -2^127 | 2^127 - 1 |
UInt128 | 128 | 0 | 2^128 - 1 | |
Bool | N/A | 8 | false (0) | true (1) |
- أنواع النقاط العائمة:
Type | Precision | Number of bits |
---|---|---|
Float16 | half | 16 |
Float32 | single | 32 |
Float64 | double | 64 |
بالإضافة إلى ذلك، يتم بناء الدعم الكامل لـ Complex and Rational Numbers على هذه الأنواع الرقمية الأولية. تتفاعل جميع الأنواع الرقمية بشكل طبيعي دون الحاجة إلى تحويل صريح، بفضل type promotion system القابلة للتوسيع من قبل المستخدم.
Integers
تمثل الأعداد الصحيحة الحرفية بالطريقة القياسية:
julia> 1
1
julia> 1234
1234
يعتمد النوع الافتراضي لرمز العدد الصحيح على ما إذا كان نظام الهدف لديه بنية 32 بت أو بنية 64 بت:
# 32-bit system:
julia> typeof(1)
Int32
# 64-bit system:
julia> typeof(1)
Int64
تشير المتغير الداخلي في جوليا Sys.WORD_SIZE
إلى ما إذا كان نظام الهدف 32 بت أو 64 بت:
# 32-bit system:
julia> Sys.WORD_SIZE
32
# 64-bit system:
julia> Sys.WORD_SIZE
64
تعرّف جوليا أيضًا الأنواع Int
و UInt
، والتي هي أسماء مستعارة لأنواع الأعداد الصحيحة الأصلية الموقعة وغير الموقعة للنظام على التوالي:
# 32-bit system:
julia> Int
Int32
julia> UInt
UInt32
# 64-bit system:
julia> Int
Int64
julia> UInt
UInt64
الأعداد الصحيحة الأكبر التي لا يمكن تمثيلها باستخدام 32 بت فقط ولكن يمكن تمثيلها في 64 بت دائمًا تخلق أعدادًا صحيحة 64 بت، بغض النظر عن نوع النظام:
# 32-bit or 64-bit system:
julia> typeof(3000000000)
Int64
تُدخل وتُخرج الأعداد الصحيحة غير الموقعة باستخدام البادئة 0x
وأرقام النظام السداسي عشر (الأساس 16) 0-9a-f
(تعمل الأرقام الكبيرة A-F
أيضًا للإدخال). يتم تحديد حجم القيمة غير الموقعة من خلال عدد أرقام السداسي عشر المستخدمة:
julia> x = 0x1
0x01
julia> typeof(x)
UInt8
julia> x = 0x123
0x0123
julia> typeof(x)
UInt16
julia> x = 0x1234567
0x01234567
julia> typeof(x)
UInt32
julia> x = 0x123456789abcdef
0x0123456789abcdef
julia> typeof(x)
UInt64
julia> x = 0x11112222333344445555666677778888
0x11112222333344445555666677778888
julia> typeof(x)
UInt128
هذا السلوك يعتمد على الملاحظة أنه عندما يستخدم المرء القيم العددية الصحيحة غير الموقعة في شكل أرقام سداسية عشرية، فإنه عادة ما يستخدمها لتمثيل تسلسل بايت رقمي ثابت، بدلاً من مجرد قيمة عددية صحيحة.
تدعم القيم الثنائية والثمانية أيضًا:
julia> x = 0b10
0x02
julia> typeof(x)
UInt8
julia> x = 0o010
0x08
julia> typeof(x)
UInt8
julia> x = 0x00000000000000001111222233334444
0x00000000000000001111222233334444
julia> typeof(x)
UInt128
فيما يتعلق بالأدبيات السداسية عشر، تنتج الأدبيات الثنائية والثمانية أنواع أعداد صحيحة غير موقعة. حجم عنصر البيانات الثنائية هو الحد الأدنى المطلوب من الحجم، إذا لم يكن الرقم الأول من الأدبيات هو 0
. في حالة الأصفار البادئة، يتم تحديد الحجم من خلال الحد الأدنى المطلوب من الحجم لأدبية لها نفس الطول ولكن الرقم الأول هو 1
. وهذا يعني أن:
0x1
و0x12
هما ثوابتUInt8
،0x123
و0x1234
هي ثوابتUInt16
،0x12345
و0x12345678
هما ثوابت من نوعUInt32
،0x123456789
و0x1234567890adcdef
هما ثوابتUInt64
، إلخ.
حتى لو كانت هناك أصفار رائدة لا تساهم في القيمة، فإنها تُحسب لتحديد حجم التخزين للعدد. لذا فإن 0x01
هو UInt8
بينما 0x0001
هو UInt16
.
يسمح للمستخدم بالتحكم في الحجم.
الأدبيات غير الموقعة (التي تبدأ بـ 0x
) التي ترمز إلى أعداد صحيحة كبيرة جدًا لا يمكن تمثيلها كقيم UInt128
ستقوم بإنشاء قيم BigInt
بدلاً من ذلك. هذا ليس نوعًا غير موقّع ولكنه النوع المدمج الوحيد الكبير بما يكفي لتمثيل مثل هذه القيم العددية الكبيرة.
يمكن أن تكون القيم الثنائية والثمانية والسداسية عشر موقعة بواسطة -
التي تسبق القيمة غير الموقعة مباشرة. إنها تنتج عددًا صحيحًا غير موقع بنفس حجم القيمة غير الموقعة كما تفعل، مع مكمل اثنين للقيمة:
julia> -0x2
0xfe
julia> -0x0002
0xfffe
تُعطى القيم الدنيا والقصوى القابلة للتمثيل لأنواع الأرقام البدائية مثل الأعداد الصحيحة بواسطة دالة typemin
و دالة typemax
:
julia> (typemin(Int32), typemax(Int32))
(-2147483648, 2147483647)
julia> for T in [Int8,Int16,Int32,Int64,Int128,UInt8,UInt16,UInt32,UInt64,UInt128]
println("$(lpad(T,7)): [$(typemin(T)),$(typemax(T))]")
end
Int8: [-128,127]
Int16: [-32768,32767]
Int32: [-2147483648,2147483647]
Int64: [-9223372036854775808,9223372036854775807]
Int128: [-170141183460469231731687303715884105728,170141183460469231731687303715884105727]
UInt8: [0,255]
UInt16: [0,65535]
UInt32: [0,4294967295]
UInt64: [0,18446744073709551615]
UInt128: [0,340282366920938463463374607431768211455]
القيم التي يتم إرجاعها بواسطة typemin
و typemax
هي دائمًا من نوع الوسيطة المعطاة. (تستخدم التعبير أعلاه عدة ميزات لم يتم تقديمها بعد، بما في ذلك for loops، Strings، و Interpolation، ولكن يجب أن يكون من السهل بما يكفي فهمه للمستخدمين الذين لديهم بعض الخبرة البرمجية الحالية.)
Overflow behavior
في جوليا، يؤدي تجاوز القيمة القصوى القابلة للتمثيل لنوع معين إلى سلوك التفاف:
julia> x = typemax(Int64)
9223372036854775807
julia> x + 1
-9223372036854775808
julia> x + 1 == typemin(Int64)
true
تؤدي العمليات الحسابية مع أنواع الأعداد الصحيحة في جوليا بشكل جوهري إلى modular arithmetic، مما يعكس خصائص الحسابات الصحيحة على الأجهزة الحديثة. في السيناريوهات التي قد يحدث فيها تجاوز، من الضروري التحقق صراحة من تأثيرات الالتفاف التي يمكن أن تنتج عن مثل هذه التجاوزات. يوفر نموذج Base.Checked
مجموعة من العمليات الحسابية المزودة بفحوصات تجاوز، والتي تؤدي إلى حدوث أخطاء إذا حدث تجاوز. بالنسبة لحالات الاستخدام التي لا يمكن فيها تحمل التجاوز تحت أي ظرف من الظروف، يُنصح باستخدام نوع BigInt
، كما هو موضح في Arbitrary Precision Arithmetic.
مثال على سلوك الفائض وكيفية حله بشكل محتمل هو كما يلي:
julia> 10^19
-8446744073709551616
julia> big(10)^19
10000000000000000000
Division errors
القسمة الصحيحة (دالة div
) لها حالتان استثنائيتان: القسمة على الصفر، والقسمة على أقل عدد سالب (typemin
) بواسطة -1. كلا هاتين الحالتين ترميان استثناء DivideError
. دالتا الباقي والمودولوس (rem
و mod
) ترميان استثناء 4d61726b646f776e2e436f64652822222c20224469766964654572726f722229_40726566
عندما تكون الحجة الثانية صفرًا.
Floating-Point Numbers
تمثل الأرقام العائمة الحرفية في التنسيقات القياسية، باستخدام E-notation عند الضرورة:
julia> 1.0
1.0
julia> 1.
1.0
julia> 0.5
0.5
julia> .5
0.5
julia> -1.23
-1.23
julia> 1e10
1.0e10
julia> 2.5e-4
0.00025
النتائج أعلاه هي جميع قيم Float64
. يمكن إدخال قيم Float32
الحرفية عن طريق كتابة f
بدلاً من e
:
julia> x = 0.5f0
0.5f0
julia> typeof(x)
Float32
julia> 2.5f-4
0.00025f0
يمكن تحويل القيم إلى Float32
بسهولة:
julia> x = Float32(-1.5)
-1.5f0
julia> typeof(x)
Float32
القيم العشرية السداسية العائمة صحيحة أيضًا، ولكن فقط كقيم Float64
، مع وجود p
قبل الأس الأساس-2:
julia> 0x1p0
1.0
julia> 0x1.8p3
12.0
julia> x = 0x.4p-1
0.125
julia> typeof(x)
Float64
تدعم الأعداد العائمة بدقة نصف (Float16
) على جميع المنصات، مع استخدام التعليمات الأصلية على الأجهزة التي تدعم هذا التنسيق العددي. خلاف ذلك، يتم تنفيذ العمليات في البرمجيات، وتستخدم Float32
للحسابات الوسيطة. كجزء من تفاصيل التنفيذ الداخلية، يتم تحقيق ذلك من خلال استخدام نوع LLVM half
، الذي يتصرف بشكل مشابه لما يفعله علم -fexcess-precision=16
لشفرة C/C++.
julia> sizeof(Float16(4.))
2
julia> 2*Float16(4.)
Float16(8.0)
يمكن استخدام الخط السفلي _
كفاصل للأرقام:
julia> 10_000, 0.000_000_005, 0xdead_beef, 0b1011_0010
(10000, 5.0e-9, 0xdeadbeef, 0xb2)
Floating-point zero
تحتوي الأعداد العشرية العائمة على two zeros، الصفر الإيجابي والصفر السلبي. إنهما متساويان ولكن لهما تمثيلات ثنائية مختلفة، كما يمكن رؤيته باستخدام دالة bitstring
:
julia> 0.0 == -0.0
true
julia> bitstring(0.0)
"0000000000000000000000000000000000000000000000000000000000000000"
julia> bitstring(-0.0)
"1000000000000000000000000000000000000000000000000000000000000000"
Special floating-point values
هناك ثلاثة قيم عائمة قياسية محددة لا تتوافق مع أي نقطة على خط الأعداد الحقيقية:
Float16 | Float32 | Float64 | Name | Description |
---|---|---|---|---|
Inf16 | Inf32 | Inf | positive infinity | a value greater than all finite floating-point values |
-Inf16 | -Inf32 | -Inf | negative infinity | a value less than all finite floating-point values |
NaN16 | NaN32 | NaN | not a number | a value not == to any floating-point value (including itself) |
لمزيد من المناقشة حول كيفية ترتيب هذه القيم العائمة غير المنتهية بالنسبة لبعضها البعض وبالنسبة للقيم العائمة الأخرى، انظر Numeric Comparisons. بواسطة IEEE 754 standard، تعتبر هذه القيم العائمة نتائج لعمليات حسابية معينة:
julia> 1/Inf
0.0
julia> 1/0
Inf
julia> -5/0
-Inf
julia> 0.000001/0
Inf
julia> 0/0
NaN
julia> 500 + Inf
Inf
julia> 500 - Inf
-Inf
julia> Inf + Inf
Inf
julia> Inf - Inf
NaN
julia> Inf * Inf
Inf
julia> Inf / Inf
NaN
julia> 0 * Inf
NaN
julia> NaN == NaN
false
julia> NaN != NaN
true
julia> NaN < NaN
false
julia> NaN > NaN
false
تطبق الدوال typemin
و typemax
أيضًا على أنواع النقاط العائمة:
julia> (typemin(Float16),typemax(Float16))
(-Inf16, Inf16)
julia> (typemin(Float32),typemax(Float32))
(-Inf32, Inf32)
julia> (typemin(Float64),typemax(Float64))
(-Inf, Inf)
Machine epsilon
لا يمكن تمثيل معظم الأعداد الحقيقية بدقة باستخدام أعداد الفاصلة العائمة، لذا من المهم في العديد من الأغراض معرفة المسافة بين عددين متجاورين يمكن تمثيلهما باستخدام أعداد الفاصلة العائمة، والتي تُعرف غالبًا بـ machine epsilon.
تقدم جوليا eps
، والذي يعطي المسافة بين 1.0
والقيمة العائمة القابلة للتمثيل الأكبر التالية:
julia> eps(Float32)
1.1920929f-7
julia> eps(Float64)
2.220446049250313e-16
julia> eps() # same as eps(Float64)
2.220446049250313e-16
هذه القيم هي 2.0^-23
و 2.0^-52
كـ Float32
و Float64
، على التوالي. يمكن أيضًا لدالة eps
أن تأخذ قيمة عائمة كوسيط، وتقدم الفرق المطلق بين تلك القيمة والقيمة العائمة القابلة للتمثيل التالية. أي أن eps(x)
تعطي قيمة من نفس نوع x
بحيث أن x + eps(x)
هي القيمة العائمة القابلة للتمثيل التالية الأكبر من x
:
julia> eps(1.0)
2.220446049250313e-16
julia> eps(1000.)
1.1368683772161603e-13
julia> eps(1e-27)
1.793662034335766e-43
julia> eps(0.0)
5.0e-324
المسافة بين عددين متجاورين يمكن تمثيلهما بنظام الأعداد العائمة ليست ثابتة، بل هي أصغر للقيم الصغيرة وأكبر للقيم الكبيرة. بعبارة أخرى، الأعداد العائمة القابلة للتمثيل هي الأكثر كثافة على خط الأعداد الحقيقية بالقرب من الصفر، وتصبح أقل كثافة بشكل أسي كلما ابتعدنا عن الصفر. حسب التعريف، eps(1.0)
هو نفسه eps(Float64)
حيث أن 1.0
هو قيمة عدد عائم بدقة 64 بت.
تقدم جوليا أيضًا الدوال nextfloat
و prevfloat
التي تعيد أكبر أو أصغر عدد عائم يمكن تمثيله بالنسبة للحجة على التوالي:
julia> x = 1.25f0
1.25f0
julia> nextfloat(x)
1.2500001f0
julia> prevfloat(x)
1.2499999f0
julia> bitstring(prevfloat(x))
"00111111100111111111111111111111"
julia> bitstring(x)
"00111111101000000000000000000000"
julia> bitstring(nextfloat(x))
"00111111101000000000000000000001"
هذا المثال يبرز المبدأ العام الذي ينص على أن الأعداد العائمة القابلة للتمثيل المجاورة لها أيضًا تمثيلات صحيحة ثنائية مجاورة.
Rounding modes
إذا لم يكن للعدد تمثيل دقيق بنقطة عائمة، يجب تقريبه إلى قيمة قابلة للتمثيل مناسبة. ومع ذلك، يمكن تغيير الطريقة التي يتم بها هذا التقريب إذا لزم الأمر وفقًا لوضاع التقريب المقدمة في IEEE 754 standard.
الوضع الافتراضي المستخدم هو دائمًا RoundNearest
، والذي يقرب إلى أقرب قيمة يمكن تمثيلها، مع تقريب الروابط نحو أقرب قيمة ذات بت أقل أهمية زوجي.
Background and References
تتضمن الحسابات العشرية العائمة العديد من التفاصيل الدقيقة التي قد تكون مفاجئة للمستخدمين الذين ليسوا على دراية بتفاصيل التنفيذ على المستوى المنخفض. ومع ذلك، يتم وصف هذه التفاصيل الدقيقة بالتفصيل في معظم الكتب المتعلقة بالحسابات العلمية، وأيضًا في المراجع التالية:
- الدليل النهائي لحسابات النقطة العائمة هو IEEE 754-2008 Standard؛ ومع ذلك، فإنه غير متاح مجانًا على الإنترنت.
- للحصول على عرض تقديمي موجز ولكنه واضح حول كيفية تمثيل الأعداد العشرية العائمة، انظر إلى article حول هذا الموضوع بالإضافة إلى introduction لبعض القضايا الناشئة عن كيفية اختلاف هذا التمثيل في السلوك عن التجريد المثالي للأعداد الحقيقية.
- يوصى أيضًا بكتاب بروس داوسون series of blog posts on floating-point numbers.
- للحصول على مناقشة ممتازة وعميقة حول الأعداد العشرية العائمة ومشكلات الدقة العددية التي تواجهها عند الحساب بها، انظر إلى ورقة ديفيد غولدفيرغ What Every Computer Scientist Should Know About Floating-Point Arithmetic.
- للحصول على وثائق أكثر شمولاً حول تاريخ وأسباب ومشكلات الأعداد العشرية العائمة، بالإضافة إلى مناقشة العديد من المواضيع الأخرى في الحوسبة العددية، راجع collected writings من William Kahan، المعروف عمومًا باسم "أب الأعداد العشرية العائمة". قد تكون An Interview with the Old Man of Floating-Point ذات اهتمام خاص.
Arbitrary Precision Arithmetic
للسماح بإجراء حسابات مع أعداد صحيحة وأعداد عشرية بدقة تعسفية، تقوم جوليا بلف GNU Multiple Precision Arithmetic Library (GMP) و GNU MPFR Library، على التوالي. الأنواع BigInt
و BigFloat
متاحة في جوليا للأعداد الصحيحة والأعداد العشرية بدقة تعسفية على التوالي.
توجد المُنشئات لإنشاء هذه الأنواع من الأنواع العددية الأولية، ويمكن استخدام string literal أو @big_str
أو parse
لإنشائها من AbstractString
s. يمكن أيضًا إدخال BigInt
s كأدلة عددية عندما تكون كبيرة جدًا بالنسبة لأنواع الأعداد الصحيحة المدمجة الأخرى. لاحظ أنه نظرًا لعدم وجود نوع عدد صحيح غير موقّع بدقة تعسفية في Base
(فإن BigInt
كافٍ في معظم الحالات)، يمكن استخدام الأدلة السداسية والثمانية والثنائية (بالإضافة إلى الأدلة العشرية).
بمجرد إنشائها، تشارك في العمليات الحسابية مع جميع الأنواع الرقمية الأخرى بفضل type promotion and conversion mechanism:
julia> BigInt(typemax(Int64)) + 1
9223372036854775808
julia> big"123456789012345678901234567890" + 1
123456789012345678901234567891
julia> parse(BigInt, "123456789012345678901234567890") + 1
123456789012345678901234567891
julia> string(big"2"^200, base=16)
"100000000000000000000000000000000000000000000000000"
julia> 0x100000000000000000000000000000000-1 == typemax(UInt128)
true
julia> 0x000000000000000000000000000000000
0
julia> typeof(ans)
BigInt
julia> big"1.23456789012345678901"
1.234567890123456789010000000000000000000000000000000000000000000000000000000004
julia> parse(BigFloat, "1.23456789012345678901")
1.234567890123456789010000000000000000000000000000000000000000000000000000000004
julia> BigFloat(2.0^66) / 3
2.459565876494606882133333333333333333333333333333333333333333333333333333333344e+19
julia> factorial(BigInt(40))
815915283247897734345611269596115894272000000000
ومع ذلك، فإن ترقية النوع بين الأنواع البدائية المذكورة أعلاه و BigInt
/BigFloat
ليست تلقائية ويجب أن يتم تحديدها بشكل صريح.
julia> x = typemin(Int64)
-9223372036854775808
julia> x = x - 1
9223372036854775807
julia> typeof(x)
Int64
julia> y = BigInt(typemin(Int64))
-9223372036854775808
julia> y = y - 1
-9223372036854775809
julia> typeof(y)
BigInt
يمكن تغيير الدقة الافتراضية (بعدد بتات المقياس) ووضع التقريب لعمليات BigFloat
على مستوى عالمي عن طريق استدعاء setprecision
و setrounding
، وستأخذ جميع الحسابات اللاحقة هذه التغييرات في الاعتبار. بدلاً من ذلك، يمكن تغيير الدقة أو التقريب فقط ضمن تنفيذ كتلة معينة من التعليمات البرمجية باستخدام نفس الدوال مع كتلة do
:
julia> setrounding(BigFloat, RoundUp) do
BigFloat(1) + parse(BigFloat, "0.1")
end
1.100000000000000000000000000000000000000000000000000000000000000000000000000003
julia> setrounding(BigFloat, RoundDown) do
BigFloat(1) + parse(BigFloat, "0.1")
end
1.099999999999999999999999999999999999999999999999999999999999999999999999999986
julia> setprecision(40) do
BigFloat(1) + parse(BigFloat, "0.1")
end
1.1000000000004
العلاقة بين setprecision
أو setrounding
و @big_str
، الماكرو المستخدم لـ big
سلسلة الحروف (مثل big"0.3"
)، قد لا يكون بديهيًا، نتيجة لحقيقة أن @big_str
هو ماكرو. راجع وثائق 4d61726b646f776e2e436f64652822222c2022406269675f7374722229_40726566
للحصول على التفاصيل.
Numeric Literal Coefficients
لجعل الصيغ والتعبيرات العددية الشائعة أكثر وضوحًا، تسمح جوليا بأن تسبق المتغيرات مباشرةً عددًا صحيحًا، مما يعني الضرب. هذا يجعل كتابة التعبيرات متعددة الحدود أكثر نظافة:
julia> x = 3
3
julia> 2x^2 - 3x + 1
10
julia> 1.5x^2 - .5x + 1
13.0
يجعل كتابة الدوال الأسية أكثر أناقة:
julia> 2^2x
64
تكون أسبقية معاملات الأعداد الرقمية أقل قليلاً من أسبقية العوامل الأحادية مثل النفي. لذا يتم تحليل -2x
على أنه (-2) * x
و √2x
يتم تحليله على أنه (√2) * x
. ومع ذلك، يتم تحليل معاملات الأعداد الرقمية بشكل مشابه للعوامل الأحادية عند دمجها مع الأس. على سبيل المثال، يتم تحليل 2^3x
على أنه 2^(3x)
، و 2x^3
يتم تحليله على أنه 2*(x^3)
.
تعمل القيم العددية أيضًا كمعاملات للتعبيرات المحاطة بأقواس:
julia> 2(x-1)^2 - 3(x-1) + 1
3
تكون أسبقية معاملات الأعداد الرقمية المستخدمة في الضرب الضمني أعلى من غيرها من العمليات الثنائية مثل الضرب (*
) والقسمة (/
و \
و //
). هذا يعني، على سبيل المثال، أن 1 / 2im
يساوي -0.5im
و 6 // 2(2 + 1)
يساوي 1 // 1
.
بالإضافة إلى ذلك، يمكن استخدام التعبيرات المحاطة بأقواس كمعاملات للمتغيرات، مما يعني ضرب التعبير في المتغير:
julia> (x-1)x
6
لا يمكن استخدام لا الجمع بين تعبيرين محاطين بأقواس، ولا وضع متغير قبل تعبير محاط بأقواس، للإيحاء بالضرب:
julia> (x-1)(x+1)
ERROR: MethodError: objects of type Int64 are not callable
julia> x(x+1)
ERROR: MethodError: objects of type Int64 are not callable
يتم تفسير كلا التعبيرين كتطبيق دالة: أي تعبير ليس حرفًا رقميًا، عندما يتبعه مباشرة قوس، يتم تفسيره كدالة مطبقة على القيم الموجودة في الأقواس (انظر Functions لمزيد من المعلومات حول الدوال). وبالتالي، في كلتا الحالتين، يحدث خطأ لأن القيمة الموجودة على اليسار ليست دالة.
تُقلل التحسينات النحوية المذكورة أعلاه بشكل كبير من الضوضاء البصرية الناتجة عند كتابة الصيغ الرياضية الشائعة. لاحظ أنه لا يجوز أن يأتي أي فراغ بين معامل عددي واسم المعرف أو التعبير المحاط بأقواس الذي يضربه.
Syntax Conflicts
قد يتعارض بناء معامل حرفي متجاور مع بعض بناءات الأعداد الحرفية: الأعداد الصحيحة السداسية عشرية، والثمانية، والثنائية، والتدوين الهندسي للأعداد العشرية العائمة. فيما يلي بعض الحالات التي تنشأ فيها تعارضات نحوية:
- يمكن تفسير التعبير الأدبي للعدد الصحيح السداسي عشر
0xff
على أنه العدد الأدبي0
مضروبًا في المتغيرxff
. تظهر التباسات مماثلة مع الأدبيات الثمانية والثنائية مثل0o777
أو0b01001010
. - يمكن تفسير التعبير الأدبي للنقطة العائمة
1e10
على أنه العدد الأدبي1
مضروبًا في المتغيرe10
، وبالمثل مع الشكل المعادلE
. - يمكن تفسير التعبير الأدبي العائم 32 بت
1.5f22
على أنه العدد الأدبي1.5
مضروبًا في المتغيرf22
.
في جميع الحالات، يتم حل الغموض لصالح التفسير كأدبيات عددية:
- التعبيرات التي تبدأ بـ
0x
/0o
/0b
هي دائمًا ثوابت سداسية عشرية/ثمانية/ثنائية. - التعبيرات التي تبدأ برقم حرفي متبوعًا بـ
e
أوE
هي دائمًا حرفيات نقطة عائمة. - التعبيرات التي تبدأ برمز عددي متبوعًا بـ
f
هي دائمًا رموز عائمة بدقة 32 بت.
على عكس E
، الذي يعادل e
في الأدبيات الرقمية لأسباب تاريخية، فإن F
هو مجرد حرف آخر ولا يتصرف مثل f
في الأدبيات الرقمية. وبالتالي، يتم تفسير التعبيرات التي تبدأ بأدبيات رقمية تليها F
على أنها الأدبيات الرقمية مضروبة في متغير، مما يعني أن 1.5F22
يساوي 1.5 * F22
.
Literal zero and one
تقدم جوليا دوالًا تعيد 0 و 1 حرفيًا وفقًا لنوع محدد أو نوع متغير معين.
Function | Description |
---|---|
zero(x) | Literal zero of type x or type of variable x |
one(x) | Literal one of type x or type of variable x |
تكون هذه الوظائف مفيدة في Numeric Comparisons لتجنب الأعباء الناتجة عن type conversion غير الضرورية.
أمثلة:
julia> zero(Float32)
0.0f0
julia> zero(1.0)
0.0
julia> one(Int32)
1
julia> one(BigFloat)
1.0