سؤال

لقد صنعت هذه الطريقة

+ (CGFloat) round: (CGFloat)f {
    int a = f;
    CGFloat b = a;
    return b;
}

إنه يعمل كما هو متوقع ولكنه يدور فقط. وإذا كان رقمًا سالبًا ، فلا يزال يدور حوله.

كانت هذه مجرد طريقة سريعة صنعتها ، فليس من المهم للغاية أن تدور بشكل صحيح ، لقد جعلتها فقط حول قيم x و y للكاميرا.

هل هذه الطريقة بخير؟ هل هي سريعة؟ أو هناك حل أفضل؟

هل كانت مفيدة؟

المحلول

هناك بالفعل وظائف قياسية مع سلوكيات قد تحتاج إليها <math.h> مثل: floorf, ceilf, roundf, rintf و nearbyintf (تعني LASF 'F' إصدار "Float" ، الإصدارات التي لا توجد بها إصدارات "مزدوجة").

من الأفضل استخدام الطرق القياسية ليس فقط لأنها قياسية ، ولكن لأنها تعمل بشكل أفضل في حالات الحافة.

تحديث 2013 (JURNOC)

لم يعد iOS 32 بت فقط. هناك عدد من الإجابات الأخرى على هذا السؤال الذي أصبح الآن أكثر أهمية.

تذكر معظم الإجابات استيرادها tgmath.h

نصائح أخرى

2018 الإجابة

الإجابات الأخرى هنا إما مؤرخة أو لا تعطي أمثلة جيدة. من السهل تقريب CGFloat باستخدام سويفت بنيت في rounded وظيفة.

let x: CGFloat = 3.5
let y = x.rounded() // 4.0

إذا كنت ترغب في تحويل القيمة في مكانك يمكنك استخدامها round:

var x: CGFloat = 3.5
x.round() // 4.0

قواعد التقريب

إذا كنت تريد تحكمًا أكثر دقة في كيفية تقريب الأرقام ، فيمكنك استخدام ملف FloatingPointRoundingRule.

بعيدا عن الصفر

x.rounded(.awayFromZero)

يتم تقريب الأرقام فوق الصفر ويتم تقريب الأرقام التي تقل عن الصفر.

3.000  ->  3.0
3.001  ->  4.0
3.499  ->  4.0
3.500  ->  4.0
3.999  ->  4.0

-3.000  ->  -3.0
-3.001  ->  -4.0
-3.499  ->  -4.0
-3.500  ->  -4.0
-3.999  ->  -4.0

أسفل

x.rounded(.down)

يربط أي رقم ذي قيمة عشرية وصولاً إلى الرقم الكامل الأصغر التالي. هذا هو نفسه floor(x).

3.000  ->  3.0
3.001  ->  3.0
3.499  ->  3.0
3.500  ->  3.0
3.999  ->  3.0

-3.000  ->  -3.0
-3.001  ->  -4.0
-3.499  ->  -4.0
-3.500  ->  -4.0
-3.999  ->  -4.0

إلى الأقرب أو بعيدًا عن الصفر

x.rounded(.toNearestOrAwayFromZero)   // same as x.rounded()

يتم تقريب الأرقام العشرية إلى أقرب قيمة عدد صحيح. ومع ذلك ، عندما تكون القيمة في الوسط بالضبط (مثل 3.5 أو -3.5) ثم يتم تقريب الأرقام الإيجابية ويتم تقريب الأرقام السلبية.

قد يكون له اسم معقد طويل ، ولكن هذا هو عادة كيف يتعلم المرء التقريب في المدرسة. إنها أيضًا القاعدة المستخدمة إذا قمت بذلك فقط x.rounded().

3.000  ->  3.0
3.001  ->  3.0
3.499  ->  3.0
3.500  ->  4.0  ***
3.999  ->  4.0

-3.000  ->  -3.0
-3.001  ->  -3.0
-3.499  ->  -3.0
-3.500  ->  -4.0  ***
-3.999  ->  -4.0

إلى أقرب أو حتى

x.rounded(.toNearestOrEven)

هذا مشابه ل toNearestOrAwayFromZero, ، باستثناء الآن .5 يتم تقريب القيم إلى العدد الكامل.

3.000  ->  3.0
3.001  ->  3.0
3.499  ->  3.0
3.500  ->  4.0   ***
3.999  ->  4.0
4.500  ->  4.0   ***

-3.000  ->  -3.0
-3.001  ->  -3.0
-3.499  ->  -3.0
-3.500  ->  -4.0   ***
-3.999  ->  -4.0
-4.500  ->  -4.0   ***

نحو الصفر

x.rounded(.towardZero)

هذا فقط له تأثير قطع أي قيم عشرية. إذا كنت بحاجة إلى Int يمكنك أن تفعل الشيء نفسه مع Int(x).

3.000  ->  3.0
3.001  ->  3.0
3.499  ->  3.0
3.500  ->  3.0
3.999  ->  3.0

-3.000  ->  -3.0
-3.001  ->  -3.0
-3.499  ->  -3.0
-3.500  ->  -3.0
-3.999  ->  -3.0

أعلى

x.rounded(.up)

هذا هو عكس .down. يتم تقريب جميع الأرقام العشرية. هذا هو نفسه ceil(x).

3.000  ->  3.0
3.001  ->  4.0
3.499  ->  4.0
3.500  ->  4.0
3.999  ->  4.0

-3.000  ->  -3.0
-3.001  ->  -3.0
-3.499  ->  -3.0
-3.500  ->  -3.0
-3.999  ->  -3.0

ملحوظات

  • لا تنس أن تأخذ القيم السلبية في الاعتبار.
  • نتائج round و rounded لا تزال CGFloat. إذا كنت بحاجة إلى Int عليك تحويله مثل Int(myCGFloat).
  • ليست هناك حاجة لاستخدام وظائف الرياضيات C round(x), ceil(x) و floor(x) أي أكثر من ذلك. ومع ذلك ، إذا كنت تستخدمها ، فإنهم يتعاملون roundf, ceilf و floorf الآن عفا عليها الزمن.

أ CGFloat هو typedef'd إما double أو أ float, ، لذلك يمكنك تقريبهم مثل أي نوع حقيقي آخر:

CGFloat round(CGFloat aFloat)
{
    return (int)(aFloat + 0.5);
}

لاحظ أنه على الرغم من أن هذا يعمل مع عوامات صغيرة بما يكفي لحمل جزء صغير ، إلا أنه قد يتصرف بشكل غريب على القيم الكبيرة.

محاولة #import "tgmath.h".

ال <tgmath.h> سيشمل الرأس الرؤوس <math.h> و <complex.h> وسوف تحدد العديد من وحدات الماكرو من النوع الجيني.

أنت تعيد اختراع العجلة - وهذا سؤال C ، وليس الهدف C. فقط استخدم وظيفة C route () القياسية.

للعمل مع 32 و 64 بت يمكنك إنشاء مثل ماكرو الخاص بك

#ifndef CGFLOAT_CEIL
    #ifdef CGFLOAT_IS_DOUBLE
        #define CGFLOAT_CEIL(value) ceil(value)
    #else
        #define CGFLOAT_CEIL(value) ceilf(value)
    #endif
#endif

ملاحظة: هذه ليست إجابة للسؤال ولكن إضافة عن السؤال حول كيفية العمل بقيم 32/64 بت.

حدد هذا في ملف مثل mymacros.h وإضافة استيراد في myapp-prefix.pch

تذكر أيضًا أن اختيار CGFLOAT كبادئة لوظائفك يمكن أن يكون خطرًا لأن Apple قد تضيف ماكرو مثل هذا نفسه ، ولهذا السبب

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top