سؤال

لدي ثلاث مجموعات من الأرقام، وهو قياس (وهو موجود في النطاق 0-1 شامل) أخطاء (إيجابي وسلبي. يجب عرض هذه الأرقام بشكل متسق لعدد أرقام كبيرة، تقريب، والتي تتوافق مع أول غير إدخال صفر في أي من العدد.

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

0.95637 (+0.00123, -0.02935) --> 0.96 +0.00 -0.03
1.00000 (+0.0, -0.0979) --> 1.0 +0.0 -0.1 (note had to truncate due to -ve error rounding up at first significant digit)

الآن، الحصول على أول رقم غير صفر من السهل من خلال أخذ Log10 (Num)، لكنني أحصل على لحظة غبية في محاولة للتعرية والتقرير العاملة في أزياء نظيفة.

جميع أنواع البيانات مضاعفات، ولغة الاختيار هي C ++. الكل وأي أفكار موضع ترحيب!

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

المحلول

بلدي C ++ هو صدئ، ولكن لن التالي تفعل ذلك:

std::string FormatNum(double measurement, double poserror, double negerror)
{
  int precision = 1;  // Precision to use if all numbers are zero

  if (poserror > 0)
    precision = ceil(-1 * log10(poserror));
  if (negerror < 0)
    precision = min(precision, ceil(-1 * log10(abs(negerror))));

  // If you meant the first non-zero in any of the 3 numbers, uncomment this:
  //if( measurement < 1 )
  //  precision = min(precision, ceil(-1 * log10(measurement)));

  stringstream ss;
  ss.setf(ios::fixed, ios::floatfield);
  ss.precision( precision );
  ss << measurement << " +" << poserror << " " << negerror ;
  return ss.str();
}

نصائح أخرى

استخدام

cout.setf(ios::fixed, ios::floatfield);
cout.precision(2);

قبل إخراج الأرقام، يجب أن تفعل ما تبحث عنه.

تحرير: كمثال

double a = 0.95637;
double b = 0.00123;
double c = -0.02935;

cout.setf(ios::fixed, ios::floatfield);
cout.precision(2);
cout << a << endl;
cout << b << endl;
cout << c << endl;

سوف الإخراج:

0.96
0.00
-0.03

مزيد من التحرير: من الواضح أنك يجب أن تضطر إلى ضبط الدقة لتتناسب مع شخصياتك المهمة.

ربما شيء مثل:

std::string FormatNum(double num)
{
  int numToDisplay ((int)((num + 0.005) * 100.0));
  stringstream ss;
  int digitsToDisplay(abs(numToDisplay) % 100);
  ss << ((num > 0) ? '+' : '-') << (abs(numToDisplay) / 100) << '.' << (digitsToDisplay / 10) << (digitsToDisplay % 10);
  return ss.str();
}

    stringstream ss;
    ss << FormatNum(0.95637) << ' ' << FormatNum(+0.00123) << ' ' << FormatNum(-0.02935);

لست متأكدا تماما من الطريقة التي ستساعدك فيها Log10 في الحصول على أول رقم غير صفرية، ولكن على افتراض أنها تفعل (وبالتالي، فأنت تعرف ما هو المكان العشري الذي تقرر إليه)، ستستول الدالة التالية بشكل صحيح:

double round(double num, int decimalPlaces)
{
    //given your example of .95637 being rounded to two decimal places
    double decimalMultiplier = pow(10, decimalPlaces); // = 100
    double roundedShiftedNum = num * decimalMultiplier + 0.5; // = 96.137
    double insignificantDigits = (roundedShiftedNum - (int)roundedShiftedNum; // = 0.137
    return (roundedShiftedNum - insignificantDigits) / decimalMultiplier; // = (96.137 - 0.137)/100 = 0.96
}

قد لا يكون هذا الحل الأكثر أناقة، لكنني أعتقد أنه يعمل (لم أحاول ذلك)

إليك اختلاف على الإصدار المقدم من شين باول.

std::string FormatNum(double num, int decimals)
{
    stringstream ss;
    if (num >= 0.0)
        ss << '+';
    ss << setiosflags(ios::fixed) << setprecision(decimals) << num;
    return ss.str();
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top