استكشاف أخطاء أنواع البيانات

تسرد هذه الصفحة بعض المشاكل الشائعة التي يمكن أن تحدث عند إجراء عمليات تشغيل أنواع بيانات فعلية.

لا تـقارن تعبيرات مؤشر-عائم كيساوي

عند العمل مع أرقام الفاصلة العائمة (نوع البيانات المفرد (Visual Basic) و نوع بيانات مزدوج (Visual Basic)) ، تذكر أنه يتم تخزينها كـالكسور الثنائية . وهذا يعني أنها يتعذر تقييد بالضبط تمثيل لأي كمية التي ليست كسر ثنائي (من الشكل k / (2 ^ n) حيث k و n هي أعداد صحيحة). على سبيل المثال، 0.5 (1/2 =) و 0.3125 (= 5/16) يمكن تقييدها كقيم دقيقة بينما يمكن ل (1/5 =) 0.2 و 0.3 (= 3/10) تقريبها فقط.

بسبب عدم الدقة هذه ، يتعذر الاعتماد على النتائج الصحيحة عند العمل على قيم الفاصلة العائمة. بشكل خاص، قد يكون لديك قيمتين متساويتين نظرياً تملكان تمثيلات مختلفة قليلاً.

لمـقارنة كميات الفاصلة العائمة

  1. قم بـحساب القيمة المطلقة للفرقهم باستخدام Abs الأسلوب لـ Math الفئة في System مساحة الاسم.

  2. قم بـتحديد فرق أقصى مقبول بحيث يمكن أن تأخذ بعين الاعتبار الكميتين ليكونا أن متساويين لأغراض عملية إذا كان فرقهم ليس كبيرا.

  3. قارن القيمة المطلقة للفرق للفرق المتوقع.

يوضح المثال التالي مقارنة غير صحيحة وصحيحة لقيمتي Double .

Dim oneThird As Double = 1.0 / 3.0
Dim pointThrees As Double = 0.333333333333333

' The following comparison does not indicate equality.
Dim exactlyEqual As Boolean = (oneThird = pointThrees)

' The following comparison indicates equality.
Dim closeEnough As Double = 0.000000000000001
Dim absoluteDifference As Double = Math.Abs(oneThird - pointThrees)
Dim practicallyEqual As Boolean = (absoluteDifference < closeEnough)

MsgBox("1.0 / 3.0 is represented as " & oneThird.ToString("G17") &
    vbCrLf & "0.333333333333333 is represented as " &
    pointThrees.ToString("G17") &
    vbCrLf & "Exact comparison generates " & CStr(exactlyEqual) &
    vbCrLf & "Acceptable difference comparison generates " &
    CStr(practicallyEqual))

يستخدم المثال السابق ToString الأسلوب لـ Double البناء بحيث يتم تحديد دقة أفضل من التي تستخدمها CStr الكلمة الأساسية. الافتراضي هو 15 رقماً ولكن تنسيق "G17" يوسيعها إلى 17 رقماً.

عامل التشغيل mod لا يقوم بإرجاع نتيجة دقيقة

نتيجة لعدم دقة تخزين الفاصلة العائمة , عامل التشغيل باقي القسمة في (Visual Basic) يمكن أن يرجع نتيجة غير متوقعة عندما يكون واحد على الأقل من المعاملات هو فاصلة عائمة.

نوع بيانات العشري (Visual Basic) لا يستخدم تمثيل الفاصلة العائمة. كثير من الأرقام الغير دقيقة في Single و Double يتم دقيقة في Decimal (على سبيل المثال 0.2 و 0.3). على الرغم من أن الحسابي أبطأ في Decimal من الفاصلة العائمة, قد يكون استحق انخفاض الأداء لتحقيق دقة أفضل.

لاجاد باقي قسمة العدد الصحيح لكميات الفاصلة العائمة

  1. قم بتعريف المتغيرات كـ Decimal.

  2. استخدام حرف نوع القيمة الحرفية D لفرض القيم الحرفية إلى Decimal، في حال كون قيمها كبيرة جداً بالنسبة لـ Long نوع البيانات.

يوضح المثال التالي عدم الدقة المحتملة من معامل الفاصلة العائمة.

Dim two As Double = 2.0
Dim zeroPointTwo As Double = 0.2
Dim quotient As Double = two / zeroPointTwo
Dim doubleRemainder As Double = two Mod zeroPointTwo

MsgBox("2.0 is represented as " & two.ToString("G17") &
    vbCrLf & "0.2 is represented as " & zeroPointTwo.ToString("G17") &
    vbCrLf & "2.0 / 0.2 generates " & quotient.ToString("G17") &
    vbCrLf & "2.0 Mod 0.2 generates " &
    doubleRemainder.ToString("G17"))

Dim decimalRemainder As Decimal = 2D Mod 0.2D
MsgBox("2.0D Mod 0.2D generates " & CStr(decimalRemainder))

يستخدم المثال السابق ToString الأسلوب لـ Double البناء بحيث يتم تحديد دقة أفضل من التي تستخدمها CStr الكلمة الأساسية. الافتراضي هو 15 رقماً ولكن تنسيق "G17" يوسيعها إلى 17 رقماً.

لأن zeroPointTwo هو Double، قيمته لـ 0.2 كسر ثنائية مكرر بشكل لا نهائي مع قيمة مخزنة 0.20000000000000001. قسمة 2.0 من هذه الكمية تعطي 9.9999999999999995 مع باقي 0.19999999999999991.

في التعبير لـ decimalRemainder ، نوع الحرف الحرفي D يفرض كلا المعاملات إلى Decimal ، ولديه 0.2 تمثيل دقيق. لذلكMod عامل التشغيل يعطي الباقي المتوقع 0.0.

لاحظ أنه من الغير الكافي تعريف decimalRemainder كـ Decimal. يجب أيضاً فرض القيم الحرفية إلى Decimal، أو يستخدمون Double افتراضيا و decimalRemainder يتلقى نفس القيمة الغير دقيقة كـ doubleRemainder.

لا يمكن تحويل نوع القيمة المنطقية الى نوع رقمي بدقة

قيم نوع بيانات القيمة المنطقية في (Visual Basic) لا تخزّن كأرقام و القيم المخزّنة لا تنوي أن تكون مكافئة إلى أرقام. من أجل التوافق مع الإصدارات السابقة Visual Basic يوفر الكلمات الأساسية التحويل (دالة CType, CBool, CInt، وهكذا) للتحويل بين Boolean والأنواع الرقمية. ولكن، لغات أخرى أحياناً تنفذ هذه التحويلات بشكل مختلف كما تفعل أساليب .NET Framework .

يجب عدم كتابة تعليمات برمجية التي تعتمد على قيم رقمية المكافئ True و False. عند الإمكان، يجب تقييد استخدام متغيرات Boolean للقيم المنطقية التي تم تصميمها. إذا خلطت بين Boolean و القيم الرقمية تأكد من فهم أسلوب التحويل الذي قمت بتحديده .

التحويل في Visual Basic

عند استخدام CType أو CBool الكلمات الأساسية التحويل لتحويل أنواع البيانات الرقمية إلى Boolean، 0 يصبح False وكل القيم الأخرى تصبح True. عند تحويل Boolean القيم إلى أنواع رقمية باستخدام الكلمات الأساسية التحويل False يصبح 0 و True يصبح -1.

التحويل في Framework

ToInt32 الأسلوب لـ Convert الفئة في System مساحة الاسم تحول True إلى + 1.

إذا كان يجب عليك تحويل Boolean القيمة لنوع بيانات رقمية، كن حذراً ا] أسلوب تحويل تستخدمه.

قيم حرفية الحرف تقوم بإنشاء خطأ محول برمجي

في غياب أية أحرف نوع Visual Basic يفترض أنواع بيانات افتراضية للقيم الحرفية. النوع الافتراضي لحرف قيمة حرفية — محاطه بعلامات اقتباس (" ") — هو String.

String نوع البيانات لا تسع لـنوع بيانات الحرف (Visual Basic). وهذا يعني أنه إذا أردت تعيين قيمة حرفية لـ Char المتغير, يجب عليك إما إجراء تحويل تضييقي أو فرض القيمية الحرفية إلى Char النوع.

لإنشاء قيمة حرفية لأحرف لتعيينها الى متغير أو ثابت

  1. قم بتعريف المتغير أو الثابت كـ Char.

  2. قم بـوضع قيمة الحرف ضمن علامات اقتباس (" ").

  3. اتبع علامة الاقتباس المزدوجة للإغلاق مع حرف نوع القيمة الحرفية C لفرض القيمة الحرفية إلى Char. يعد هذا ضرورياً إذا كان مُبَدْل التحقق من النوع (كشف الخيار الصارمِ) هو On، وهي مطلوبة في أي حالة.

يوضح المثال التالي كلا التعيينات الغير الناجحة و الناجحة من قيمة حرفية الى متغير Char.

Option Strict On
Dim charVar As Char
' The following statement attempts to convert a String literal to Char.
' Because Option Strict is On, it generates a compiler error.
charVar = "Z"
' The following statement succeeds because it specifies a Char literal.
charVar = "Z"c
' The following statement succeeds because it converts String to Char.
charVar = CChar("Z")

هناك دوماً مخاطرة في استخدام التحويل التضييقي لأنه يمكن أن تفشل في وقت التشغيل. على سبيل المثال، تحويل من String إلى Char يمكن فشل إذا كانت قيمة String تحتوي على حرف واحد أو أكثر. لذلك، فإنها تكون البرمجة بشكل أفضل عند استخدام حرف نوع C.

فشل تحويل السلسلة في وقت التشغيل

نوع بيانات السلسلة (Visual Basic) يشارك في عمليات تحويل توسيعية قليلة جداً. String تتوسع فقط على نفسها و Object، و فقط Char و Char() ( Char الصفيف) يتوسيع الى String. وهذا لأن متغيرات String والثوابت يمكن أن تحتوي على القيم التي لا يمكن أن تحويها أنواع البيانات الأخرى .

عندما مُبَدْل التحقق من النوع (كشف الخيار الصارمِ) هو On، لا يسمح المحول البرمجي كل عمليات التحويل الضمنية التضييقية. يتضمن هذا تلك التي تتضمن String. يمكن للتعليمات البرمجية الاستمرار باستخدام تحويل الكلمات الأساسية مثل CStr و دالة CType، التي توجه .NET Framework لمحاولة عملية التحويل.

ملاحظة

يـمنع خطأ تحويل التضييق للتحويلات من العناصر في For Each…Next المجموعة إلى متغير عنصر تحكم التكرار الحلقي. للحصول على مزيد من المعلومات وأمثلة, راجع مقطع "تحويلات التضييق" في عبارة Visual Basic) For Each...Next).

حماية التحويل التضييقي

ومن سيئات تحويلات التضييق أنها يمكن أن تفشل في وقت التشغيل. على سبيل المثال، إذا كان متغير String يحتوي على أي شيء أخرى غير "صحيح" أو "خطأ", لا يمكن تحويلها إلى Boolean. إذا كانت تحتوي على أحرف علامات التنقيط, يفشل التحويل إلى أي نوع عددي. إلا إذا عرفت أن متغير String يحتوي على قيم التي يمكن أن يقبلها نوع الوجهة دوماً, يجب عدم محاولة إجراء تحويل.

إذا كان يجب عليك التحويل من String إلى نوع بيانات آخر, الإجراء الأكثر أماناً هي إحاطة التحويل المطلوب في عبارة Visual Basic) Try...Catch...Finally). يتيح لك هذا إمكانية التعامل مع فشل وقت التشغيل.

صفائف الحرف

الـمفرد Char و صفيف من Char العناصر كلاهما يوسعان إلى String. ومع ذلك، String لا يوسع إلى Char(). لـتحويل قيمة String إلى Char الصفيف, يمكنك استخدام ToCharArray الأسلوب لـ System.String الفئة.

الـقيم الغامضة

بشكل عام , String القيم ليس لها معنى في أنواع بيانات أخرى و التحويل زائف و خطير بشدة . عند الإمكان، يجب تقييد استخدام متغيرات String لمتتاليات الحرف التي تم تصميمها. يجب عدم كتابة تعليمات برمجية تعتمد على القيم المناظرة في أنواع أخرى.

راجع أيضًا:

المرجع

خلاصة نوع بيانات (Visual Basic)

دوال تحويل النوع

المبادئ

أنواع البيانات في Visual Basic

نوع الأحرف.

البرمجة اللا نوعية في Visual Basic

كفاءة استخدام أنواع البيانات

موارد أخرى

تطبيق نوع البيانات

نوع التحويلات في Visual Basic