كيفية تقريب cgfloat
-
28-09-2019 - |
سؤال
لقد صنعت هذه الطريقة
+ (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 قد تضيف ماكرو مثل هذا نفسه ، ولهذا السبب