java - عدد - تقريب الاعداد بعد الفاصله




كيفية تدوير عدد إلى عدد المنازل العشرية في جاوة (20)

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

أود أيضًا أن يتم عرض أرقام مهمة فقط - أي يجب ألا يكون هناك أي زائدة.

أعرف أن إحدى الطرق للقيام بذلك هي استخدام طريقة String.format :

String.format("%.5g%n", 0.912385);

عائدات:

0.91239

وهو أمر رائع ، إلا أنه يعرض دائمًا أرقامًا تحتوي على 5 منازل عشرية حتى إذا لم تكن ذات أهمية:

String.format("%.5g%n", 0.912300);

عائدات:

0.91230

طريقة أخرى هي استخدام DecimalFormatter :

DecimalFormat df = new DecimalFormat("#.#####");
df.format(0.912385);

عائدات:

0.91238

ومع ذلك كما ترون هذا يستخدم التقريب نصف. هذا هو أنها سوف تقلب إذا كان الرقم السابق هو حتى. ما أريده هو:

0.912385 -> 0.91239
0.912300 -> 0.9123

ما هي أفضل طريقة لتحقيق ذلك في جافا؟


DecimalFormat هي أفضل الطرق للإخراج ، لكنني لا أفضل ذلك. أفعل هذا دائماً طوال الوقت ، لأنه يعيد القيمة المزدوجة. حتى أتمكن من استخدامه أكثر من مجرد الإخراج.

Math.round(selfEvaluate*100000d.0)/100000d.0;

أو

Math.round(selfEvaluate*100000d.0)*0.00000d1;

إذا كنت بحاجة إلى قيمة كبيرة للأماكن العشرية ، فيمكنك استخدام BigDecimal بدلاً من ذلك. على أي حال .0 مهم. وبدون ذلك ، فإن تقريب 0.33333d5 سيعود 0.33333 ويسمح فقط بـ 9 أرقام. لدى الدالة الثانية دون .0 مشاكل مع 0.30000 return 0.30000000000000004.


Milhous: التنسيق العشري للتقريب ممتاز:

يمكنك أيضا استخدام

DecimalFormat df = new DecimalFormat("#.00000");
df.format(0.912385);

للتأكد من أن لديك 0 زائدة.

وأود أن أضيف أن هذه الطريقة جيدة للغاية في توفير آلية تقريب رقمية حقيقية - ليس فقط بصريًا ، ولكن أيضًا عند التجهيز.

افتراضيًا: يجب عليك تطبيق آلية التقريب في برنامج GUI. لتغيير دقة / دقة ناتج النتيجة ، قم ببساطة بتغيير تنسيق حرف الإقحام (أي داخل الأقواس). لهذا السبب:

DecimalFormat df = new DecimalFormat("#0.######");
df.format(0.912385);

سيعود الناتج: 0.912385

DecimalFormat df = new DecimalFormat("#0.#####");
df.format(0.912385);

سيعود الناتج: 0.91239

DecimalFormat df = new DecimalFormat("#0.####");
df.format(0.912385);

سيعود الناتج: 0.9124

[EDIT: أيضًا إذا كان تنسيق علامة الإقحام مثل ذلك ("# 0. ############") وقمت بإدخال رقم عشري ، على سبيل المثال 3.1415926 ، من أجل الوسيطة ، فإن DecimalFormat لا ينتج أي قمامة ( على سبيل المثال زائدة الأصفار) وسوف يعود: 3.1415926 .. إذا كنت على هذا النحو تميل. منح ، انها مطول قليلا لتروق بعض ديف - ولكن مهلا ، لديها بصمة ذاكرة منخفضة أثناء المعالجة وسهلة التنفيذ.]

بشكل أساسي ، فإن جمال DecimalFormat هو أنه يعالج في نفس الوقت مظهر السلسلة - بالإضافة إلى مستوى دقة التقريب. Ergo: تحصل على فائدتين لسعر تنفيذ أحد الرموز. ؛)


أين dp = المكان العشري الذي تريده ، والقيمة مضاعفة.

    double p = Math.pow(10d, dp);

    double result = Math.round(value * p)/p;

إذا افترضنا أن value double ، فيمكنك القيام بذلك:

(double)Math.round(value * 100000d) / 100000d

هذا ل 5 أرقام الدقة. يشير عدد الأصفار إلى عدد الكسور العشرية.


إذا كنت تستخدم DecimalFormat لتحويل double إلى String ، فسيكون ذلك واضحًا جدًا:

DecimalFormat formatter = new DecimalFormat("0.0##");
formatter.setRoundingMode(RoundingMode.HALF_UP);

double num = 1.234567;
return formatter.format(num);

هناك العديد من قيم التعداد من نوع RoundingMode للاختيار من بينها ، اعتمادًا على السلوك الذي تحتاجه.


إليك الحل الأساسي الذي تقدمه jpdymond :

   public static double round(double value, int precision) {
      int scale = (int) Math.pow(10, precision);
      return (double) Math.round(value * scale) / scale;
  }

https://.com/a/22186845/212950


جرب هذا: org.apache.commons.math3.util.Precision.round (double x، int scale)

راجع: http://commons.apache.org/proper/commons-math/apidocs/org/apache/commons/math3/util/Precision.html

Apache Commons Mathematics Library homepage: http://commons.apache.org/proper/commons-math/index.html

الادعاء الداخلي لهذه الطريقة هو:

public static double round(double x, int scale) {
    return round(x, scale, BigDecimal.ROUND_HALF_UP);
}

public static double round(double x, int scale, int roundingMethod) {
    try {
        return (new BigDecimal
               (Double.toString(x))
               .setScale(scale, roundingMethod))
               .doubleValue();
    } catch (NumberFormatException ex) {
        if (Double.isInfinite(x)) {
            return x;
        } else {
            return Double.NaN;
        }
    }
}

جوال Real كيف يعمل هذا الحل ، والذي يتوافق أيضًا مع الإصدارات قبل Java 1.6.

BigDecimal bd = new BigDecimal(Double.toString(d));
bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP);
return bd.doubleValue();

فقط في حالة مازال شخص ما بحاجة إلى مساعدة في هذا. هذا الحل يعمل بشكل مثالي بالنسبة لي.

private String withNoTrailingZeros(final double value, final int nrOfDecimals) {
return new BigDecimal(String.valueOf(value)).setScale(nrOfDecimals,  BigDecimal.ROUND_HALF_UP).stripTrailingZeros().toPlainString();

}

بإرجاع String مع الإخراج المطلوب.


في ما يلي ملخص لما يمكنك استخدامه إذا كنت تريد أن تكون النتيجة سلسة:

  1. DecimalFormat#setRoundingMode() :

    DecimalFormat df = new DecimalFormat("#.#####");
    df.setRoundingMode(RoundingMode.HALF_UP);
    String str1 = df.format(0.912385)); // 0.91239
    
  2. BigDecimal#setScale()

    String str2 = new BigDecimal(0.912385)
        .setScale(5, BigDecimal.ROUND_HALF_UP)
        .toString();
    

في ما يلي اقتراح حول المكتبات التي يمكنك استخدامها إذا كنت تريد double نتيجة لذلك. أنا لا أوصي به لتحويل السلسلة ، على الرغم من أنه قد لا يكون بمقدور مزدوج تمثيل ما تريده بالضبط (انظر على سبيل المثال here ):

  1. Precision من Apache Commons Math

    double rounded = Precision.round(0.912385, 5, BigDecimal.ROUND_HALF_UP);
    
  2. Functions من كولت

    double rounded = Functions.round(0.00001).apply(0.912385)
    
  3. Utils من ويكا

    double rounded = Utils.roundDouble(0.912385, 5)
    

لقد جئت إلى هنا فقط أريد إجابة بسيطة حول كيفية تدوير رقم. هذه إجابة تكميلية لتوفير ذلك.

كيفية تدوير عدد في جاوة

الحالة الأكثر شيوعًا هي استخدام Math.round() .

Math.round(3.7) // 4

يتم تقريب الأرقام إلى أقرب عدد صحيح. يتم تقريب قيمة .5 . إذا كنت بحاجة إلى سلوك تقريب مختلف عن ذلك ، فيمكنك استخدام إحدى وظائف Math الأخرى. انظر المقارنة أدناه.

round

كما ذكر أعلاه ، هذه الجولات إلى أقرب عدد صحيح. .5 الكسور العشرية. هذا الأسلوب يعيد int .

Math.round(3.0); // 3
Math.round(3.1); // 3
Math.round(3.5); // 4
Math.round(3.9); // 4

Math.round(-3.0); // -3
Math.round(-3.1); // -3
Math.round(-3.5); // -3 *** careful here ***
Math.round(-3.9); // -4

ceil

يتم تقريب أي قيمة عشرية إلى العدد الصحيح التالي. يذهب إلى السقف CE . هذه الطريقة ترجع double .

Math.ceil(3.0); // 3.0
Math.ceil(3.1); // 4.0
Math.ceil(3.5); // 4.0
Math.ceil(3.9); // 4.0

Math.ceil(-3.0); // -3.0
Math.ceil(-3.1); // -3.0
Math.ceil(-3.5); // -3.0
Math.ceil(-3.9); // -3.0

floor

يتم تقريب أي قيمة عشرية إلى العدد الصحيح التالي. هذه الطريقة ترجع double .

Math.floor(3.0); // 3.0
Math.floor(3.1); // 3.0
Math.floor(3.5); // 3.0
Math.floor(3.9); // 3.0

Math.floor(-3.0); // -3.0
Math.floor(-3.1); // -4.0
Math.floor(-3.5); // -4.0
Math.floor(-3.9); // -4.0

rint

يشبه هذا الجولة في تلك القيم العشرية إلى أقرب عدد صحيح. ومع ذلك ، على عكس round ، والقيم .5 جولة إلى العدد الصحيح حتى. هذه الطريقة ترجع double .

Math.rint(3.0); // 3.0
Math.rint(3.1); // 3.0
Math.rint(3.5); // 4.0 ***
Math.rint(3.9); // 4.0
Math.rint(4.5); // 4.0 ***
Math.rint(5.5); // 6.0 ***

Math.rint(-3.0); // -3.0
Math.rint(-3.1); // -3.0
Math.rint(-3.5); // -4.0 ***
Math.rint(-3.9); // -4.0
Math.rint(-4.5); // -4.0 ***
Math.rint(-5.5); // -6.0 ***

لنفترض أن لديك

double d = 9232.129394d;

يمكنك استخدام BigDecimal

BigDecimal bd = new BigDecimal(d).setScale(2, RoundingMode.HALF_EVEN);
d = bd.doubleValue();

أو بدون BigDecimal

d = Math.round(d*100)/100.0d;

مع كل من الحلول d == 9232.13


يمكنك أيضا استخدام

DecimalFormat df = new DecimalFormat("#.00000");
df.format(0.912385);

للتأكد من أن لديك 0 زائدة.



يمكنك استخدام فئة DecimalFormat.

double d = 3.76628729;

DecimalFormat newFormat = new DecimalFormat("#.##");
double twoDecimal =  Double.valueOf(newFormat.format(d));

يوضح مقتطف الشفرة أدناه كيفية عرض n n أرقام. الخدعة هي تعيين pp متغير إلى 1 متبوعاً بالأصفار n. في المثال أدناه ، تحتوي قيمة pp المتغيرة على 5 أصفار ، بحيث يتم عرض 5 أرقام.

double pp = 10000;

double myVal = 22.268699999999967;
String needVal = "22.2687";

double i = (5.0/pp);

String format = "%10.4f";
String getVal = String.format(format,(Math.round((myVal +i)*pp)/pp)-i).trim();

If you're using a technology that has a minimal JDK. Here's a way without any Java libs:

double scale = 100000;    
double myVal = 0.912385;
double rounded = (int)((myVal * scale) + 0.5d) / scale;

In general, rounding is done by scaling: round(num / p) * p

/**
 * MidpointRounding away from zero ('arithmetic' rounding)
 * Uses a half-epsilon for correction. (This offsets IEEE-754
 * half-to-even rounding that was applied at the edge cases).
 */
double RoundCorrect(double num, int precision) {
	double c = 0.5 * EPSILON * num;
//	double p = Math.pow(10, precision); //slow
	double p = 1; while (precision--> 0) p *= 10;
	if (num < 0)
		p *= -1;
	return Math.round((num + c) * p) / p;
}

// testing edge cases
RoundCorrect(1.005, 2);   // 1.01 correct
RoundCorrect(2.175, 2);   // 2.18 correct
RoundCorrect(5.015, 2);   // 5.02 correct

RoundCorrect(-1.005, 2);  // -1.01 correct
RoundCorrect(-2.175, 2);  // -2.18 correct
RoundCorrect(-5.015, 2);  // -5.02 correct


DecimalFormat myFormatter = new DecimalFormat("0.000");
String output = myFormatter.format(2.34d);

double myNum = .912385;
int precision = 10000; //keep 4 digits
myNum= Math.floor(myNum * precision +.5)/precision;




digits