إذا كنت أريد تقريب متغير من نوع double من هذا الشكل xxx.9999 إلى ( xxx +1)
بحيث أن الحد الأدنى لظهور التسعة بعد الفاصلة هو أربع مرات فأكثر أما إذا كان أقل فيبقه كما هو xxx.999
جزاكم الله خيرا
إذا كنت أريد تقريب متغير من نوع double من هذا الشكل xxx.9999 إلى ( xxx +1)
بحيث أن الحد الأدنى لظهور التسعة بعد الفاصلة هو أربع مرات فأكثر أما إذا كان أقل فيبقه كما هو xxx.999
جزاكم الله خيرا
تم تعديل هذه المشاركة بواسطة KeepForward في 3 نوفمبر 2012 في 03:50
مرحباً أخي :)
هذا مثال كتبتُه لك ع السريع, أرجو أن يُفيدك :
#include <stdio.h>
#include <stdlib.h>
int exist(char *s, char c) {
char *pt;
unsigned int i;
for (pt = s, i = 0; *pt; pt++, i++) {
if (*pt == c) {
return i;
}
}
return -1;
}
char result [50];
char* round(char* numberString) {
int counter = exist(numberString, '.');
char c, *temp = numberString;
while (*temp++ && counter)
counter--;
for (int i = 0; i < 4 && *temp; i++) {
if (c < '9')
return numberString;
c = *temp++;
}
sprintf(result, "%d", (int) atof(numberString));
return result;
}
int main() {
double x = 712.999;
char buffer [50];
sprintf(buffer, "%f", x);
printf("%s", round(buffer));
return 0;
}تحياتي.
تم تعديل هذه المشاركة بواسطة khaled_prg في 3 نوفمبر 2012 في 13:12
إليك مثال بسيط كتبته لك
، أخي صديق مصطفى
،،، المهم هو أن المثال يقسم الأعداد العشرية حيث يضع مكان النقطة ~ فاصلة ~
يمكنك استخدام شرط يتحقق من عدم وصوله إلى الفاصلة و يطبع الرقم الذي تريده بدون ترسبات ما بعد الفاصلة ، وضعت لك الشرط كتعليق ،،،

المشكلة أخي حمزة أنه المتغير لا نعرف قيمته وهو ناتج عن عمليات حسابية فمن الممكن أن يكون : 3 فقط أو 7.9 أو xxxx.xxxx
وأنا أريده أن يقرب عند xxxxx.9999 ...
ربما لا منفذ من ذلك غير حل الأخ خالد .. لكن أطلب منه أن يشرح لي الدالتين وماهية وسطائهما :
sprintf
atof(string)
حسناً سأشرح الكود كاملاً, للفائدة العامة :)
نبدأ مع الدالة exist التي تستقبل وسيطين, الأول عبارة عن مؤشر حرفي حيث يُمثل المصفوفة الحرفية التي نريد البحث داخلها و الوسيط الثاني عبارة عن المحرف الذي نريد البحث عنه, الدالة exist تقوم بالبحث عن الوسيط الثاني داخل الوسيط الأول. إذا وجدته, تُعيد مكانه في المصفوفة الحرفية و إلا فستعيد -1.
نأتي الآن إلى الدالة round التي تستقبل مؤشر حرفي يُمثل العدد المُستهدف (في هيئة نص) و تُعيد مصفوفة حرفية تحوي تقريب العدد إذا ظهر الرقم 9 بعد الفاصلة أربع مرات على الأقل و إلا فالعدد يبقى كما هو.
في السطر الأول, قمنا باستدعاء الدالة exist بوسيطين, الوسيط الأول عبارة عن النص الذي يحوي العدد و الوسيط الثاني عبارة عن الفاصلة. و بالتالي ستُعيد التالية رقم الخانة التي تحتوي على الفاصلة و ستكون هذه هي بداية انطلاقتنا ..
في السطر الثاني, قمنا بالإعلان عن متغيرين من نوع char, المتغير الأول c تأتي فائدته في التخزين المؤقت لقيم الأرقام الأربعة الموجودة بعد الفاصلة و المتغير الثاني temp عبارة عن نسخة من الوسيط الأصلي. لأنه عند التعامل مع المؤشرات يجب العمل دائماً على نسخة فقط و ليس المؤشر الأب حتى لا نفقد البيانات الأصلية.
في السطر الثالث قمنا بنقل المؤشر temp من أول خانة في المصفوفة إلى الخانة الأولى بعد الفاصلة.
في السطر الخامس, قمنا بالتحقق من أن الأرقام الأربعة الموجودة بعد الفاصلة تُساوي 9, إذا وجدنا (على الأقل) رقم واحد من الأرقام السابقة أقل تماماً من 9 فستعيد الدالة القيمة الأصلية للعدد (في هيئة نص) و ينتهي الموضوع.
إذا خرجنا من الــ for بسلام فهذا يعني أن العدد يحتوي (على الأقل) على الرقم 9 أربع مرات بعد الفاصلة, حينها سنقوم باستدعاء الدالة sprintf من أجل تخزين مقصور العدد (أي الجزء الصحيح) في المصفوفة result و إعادة الناتج.
بالنسبة للدالة sprintf فهي غير محدودة الوسائط حيث تقوم بتحويل متغير من نوع (int or double) إلى نص (string) و هي موجودة في المكتبة stdio.h و لها استخدامان (حسب طبيعة الاستدعاء).
الاستدعاء الأول يكون هكذا :
#include <stdio.h>
int main ()
{
char buffer [50];
int n, a=5, b=3;
n=sprintf (buffer, "%d plus %d is %d", a, b, a+b);
printf ("[%s] is a string %d chars long\n",buffer,n);
return 0;
}و نستخدمه عادة عندما نريد تحويل/تخزين مجموعة متغيرات إلى متغير نصي في نفس الوقت.
الاستخدام الثاني يكون هكذا : (نستخدمه عادة عندما نريد تحويل متغير واحد)
sprintf(buffer, "%f", x);
حيث تستقبل الدالة 3 وسائط, الأول يُمثل السلسلة الحرفية التي سيتم تخزين العدد بداخلها و الوسيط الثاني يُمثل رمز المتغير (%d, %f, …) و الوسيط الثالث يُمثل العدد المُراد تحويله.
أما الدالة atof فهي موجودة في المكتبة stdlib.h و تستقبل سلسلة حرفية و تُعيدها على هئية متغير من نوع double إذا كانت السلسلة قابلة للتحويل و إلا فستتم إعادة القيمة 0.0
بالنسبة للكود فقد كتبته على عجالة و لدي الآن 3 ملاحظات حوله :
1. اسم الدالة يجب أن لا يكون round لأن هذا الإسم تمتلكه دالة مُعرفة مُسبقا (خصوصا في مترجمات Borland) في المكتبة math.h حسب معيار C99. لذا من الأفضل تغيير اسم الدالة إلى aroundIt مثلاً.
2. إذا وُجد الرقم 9 أربع مرات بعد الفاصلة, يجب أن تُعيد الدالة قيمة الجزء الصحيح للعدد + 1 و بالتالي سطر sprintf يجب أن يكون هكذا :
sprintf(result, "%d", (int) atof(numberString) + 1);
3. إذا أردنا التحقق من أن الوسيط المُرسل إلى الدالة exist يُمثل فعلا عدد حقيقي فيُمكننا فعل ذلك بسهولة من خلال المؤشرات :
#include <cctype>
bool isFloat(const char* floatString) {
int counter = 0;
while (*floatString) {
char c = *floatString++;
if (c == '.') {
counter++;
if (counter > 1)
return false;
} else {
if (!std::isdigit(c))
return false;
}
}
return true;
}أي استفسار أنا في الخدمة.
تحياتي.
تم تعديل هذه المشاركة بواسطة khaled_prg في 3 نوفمبر 2012 في 23:10
الله يعطيك العافية أخي خالد كفيت ووفيت ... لقد حلت مشكلتي مع الدالتين sprintf و atof لأول مرة أتعامل مع cstdlib ![]()
المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية
جارٍ التحقق من المتواجدين…