سؤال

ما أريده هو طريقة لتحويل مزدوج إلى سلسلة يتم تقريبها باستخدام طريقة النصف - أي.إذا كان الرقم العشري المراد تقريبه هو 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

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

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

المحلول

يستخدم setRoundingMode, ، تعيين RoundingMode بشكل صريح للتعامل مع مشكلتك مع الجولة النصف الزوجية، ثم استخدم نمط التنسيق للمخرجات المطلوبة.

مثال:

DecimalFormat df = new DecimalFormat("#.####");
df.setRoundingMode(RoundingMode.CEILING);
for (Number n : Arrays.asList(12, 123.12345, 0.23, 0.1, 2341234.212431324)) {
    Double d = n.doubleValue();
    System.out.println(df.format(d));
}

يعطي الإخراج:

12
123.1235
0.23
0.1
2341234.2125

نصائح أخرى

على افتراض value هو double, ، يمكنك ان تفعل:

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

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

new BigDecimal(String.valueOf(double)).setScale(yourScale, BigDecimal.ROUND_HALF_UP);

سوف تحصل على BigDecimal.لإخراج السلسلة منه، فقط اتصل بهذا BigDecimaltoString الطريقة، أو toPlainString طريقة Java 5+ لسلسلة تنسيق عادي.

برنامج عينة:

package trials;
import java.math.BigDecimal;

public class Trials {

    public static void main(String[] args) {
        int yourScale = 10;
        System.out.println(BigDecimal.valueOf(0.42344534534553453453-0.42324534524553453453).setScale(yourScale, BigDecimal.ROUND_HALF_UP));
    }

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

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

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

وكما لاحظ البعض الآخر، فإن الإجابة الصحيحة هي استخدام أي منهما DecimalFormat أو BigDecimal.النقطة العائمة لا يملك المنازل العشرية بحيث لا يمكنك تقريبها/اقتطاعها إلى عدد محدد منها في المقام الأول.عليك أن تعمل في جذر عشري، وهذا ما تفعله هاتان الفئتان.

أقوم بنشر الكود التالي كمثال مضاد لجميع الإجابات في هذا الموضوع وفي الواقع في جميع أنحاء StackOverflow (وأماكن أخرى) التي توصي بالضرب متبوعًا بالاقتطاع متبوعًا بالقسمة.يتعين على المدافعين عن هذه التقنية توضيح سبب إنتاج الكود التالي لمخرجات خاطئة في أكثر من 92% من الحالات.

public class RoundingCounterExample
{

    static float roundOff(float x, int position)
    {
        float a = x;
        double temp = Math.pow(10.0, position);
        a *= temp;
        a = Math.round(a);
        return (a / (float)temp);
    }

    public static void main(String[] args)
    {
        float a = roundOff(0.0009434f,3);
        System.out.println("a="+a+" (a % .001)="+(a % 0.001));
        int count = 0, errors = 0;
        for (double x = 0.0; x < 1; x += 0.0001)
        {
            count++;
            double d = x;
            int scale = 2;
            double factor = Math.pow(10, scale);
            d = Math.round(d * factor) / factor;
            if ((d % 0.01) != 0.0)
            {
                System.out.println(d + " " + (d % 0.01));
                errors++;
            }
        }
        System.out.println(count + " trials " + errors + " errors");
    }
}

مخرجات هذا البرنامج :

10001 trials 9251 errors

يحرر: لمعالجة بعض التعليقات أدناه، قمت بإعادة تصميم جزء المعامل من حلقة الاختبار باستخدام BigDecimal و new MathContext(16) لتشغيل المعامل على النحو التالي:

public static void main(String[] args)
{
    int count = 0, errors = 0;
    int scale = 2;
    double factor = Math.pow(10, scale);
    MathContext mc = new MathContext(16, RoundingMode.DOWN);
    for (double x = 0.0; x < 1; x += 0.0001)
    {
        count++;
        double d = x;
        d = Math.round(d * factor) / factor;
        BigDecimal bd = new BigDecimal(d, mc);
        bd = bd.remainder(new BigDecimal("0.01"), mc);
        if (bd.multiply(BigDecimal.valueOf(100)).remainder(BigDecimal.ONE, mc).compareTo(BigDecimal.ZERO) != 0)
        {
            System.out.println(d + " " + bd);
            errors++;
        }
    }
    System.out.println(count + " trials " + errors + " errors");
}

نتيجة:

10001 trials 4401 errors

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

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.

double d = 3.76628729;

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

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

BigDecimal bd = new BigDecimal(Double.toString(d));
bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP);
return bd.doubleValue();
double myNum = .912385;
int precision = 10000; //keep 4 digits
myNum= Math.floor(myNum * precision +.5)/precision;

@ميلهاوس:التنسيق العشري للتقريب ممتاز:

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

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

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

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

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

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

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

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

يمكنك استخدام طريقة الأداة المساعدة التالية-

public static double round(double valueToRound, int numberOfDecimalPlaces)
{
    double multipicationFactor = Math.pow(10, numberOfDecimalPlaces);
    double interestedInZeroDPs = valueToRound * multipicationFactor;
    return Math.round(interestedInZeroDPs) / multipicationFactor;
}

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

  1. التنسيق العشري#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 نتيجة ل.لا أوصي به لتحويل السلسلة، على الرغم من أن double قد لا يكون قادرًا على تمثيل ما تريده بالضبط (انظر على سبيل المثال: هنا):

  1. دقة من أباتشي كومنز الرياضيات

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

    double rounded = Functions.round(0.00001).apply(0.912385)
    
  3. المرافق من ويكا

    double rounded = Utils.roundDouble(0.912385, 5)
    

حل موجز:

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

أنظر أيضا، https://stackoverflow.com/a/22186845/212950شكرا ل com.jpdymond لتقديم هذا.

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

BigDecimal value = new BigDecimal("2.3");
value = value.setScale(0, RoundingMode.UP);
BigDecimal value1 = new BigDecimal("-2.3");
value1 = value1.setScale(0, RoundingMode.UP);
System.out.println(value + "n" + value1);

يشير إلى: http://www.javabeat.net/precise-rounding-of-decimals-using-rounding-mode-enumeration/

جرب هذا:org.apache.commons.math3.util.Precision.round(مزدوج x، مقياس كثافة العمليات)

يرى: http://commons.apache.org/proper/commons-math/apidocs/org/apache/commons/math3/util/Precision.html

الصفحة الرئيسية لمكتبة أباتشي كومنز للرياضيات هي: 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;
        }
    }
}

إذا كنت تريد حقًا أرقامًا عشرية للحساب (وليس فقط للمخرجات)، فلا تستخدم تنسيق الفاصلة العائمة الثنائي مثل double.

Use BigDecimal or any other decimal-based format.

أنا أستخدم BigDecimal للحسابات ، لكن ضع في اعتبارك أنه يعتمد على حجم الأرقام التي تتعامل معها.في معظم تطبيقاتي ، أجد أن التحليل من مزدوج أو عدد صحيح إلى طويل يكفي بما يكفي لحسابات عدد كبير جدًا.

في الواقع ، لقد استخدمت مؤخرًا محجوزًا طويلًا للحصول على تمثيلات دقيقة (على عكس نتائج HEX) في واجهة المستخدم الرسومية للأرقام الكبيرة مثل #################### أحرف ############# (كمثال).

نظرًا لعدم العثور على إجابة كاملة حول هذا الموضوع، فقد قمت بتجميع فصل دراسي يجب أن يتعامل مع هذا الأمر بشكل صحيح، مع دعم:

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

الاستخدام بسيط جدًا:

(من أجل هذا المثال أستخدم لغة مخصصة)

public static final int DECIMAL_PLACES = 2;

NumberFormatter formatter = new NumberFormatter(DECIMAL_PLACES);

String value = formatter.format(9.319); // "9,32"
String value2 = formatter.format(0.0000005); // "5,00E-7"
String value3 = formatter.format(1324134123); // "1,32E9"

double parsedValue1 = formatter.parse("0,4E-2", 0); // 0.004
double parsedValue2 = formatter.parse("0,002", 0); // 0.002
double parsedValue3 = formatter.parse("3423,12345", 0); // 3423.12345

هنا هو الفصل:

import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.ParseException;
import java.util.Locale;

public class NumberFormatter {

    private static final String SYMBOL_INFINITE           = "\u221e";
    private static final char   SYMBOL_MINUS              = '-';
    private static final char   SYMBOL_ZERO               = '0';
    private static final int    DECIMAL_LEADING_GROUPS    = 10;
    private static final int    EXPONENTIAL_INT_THRESHOLD = 1000000000; // After this value switch to exponential notation
    private static final double EXPONENTIAL_DEC_THRESHOLD = 0.0001; // Below this value switch to exponential notation

    private DecimalFormat decimalFormat;
    private DecimalFormat decimalFormatLong;
    private DecimalFormat exponentialFormat;

    private char groupSeparator;

    public NumberFormatter(int decimalPlaces) {
        configureDecimalPlaces(decimalPlaces);
    }

    public void configureDecimalPlaces(int decimalPlaces) {
        if (decimalPlaces <= 0) {
            throw new IllegalArgumentException("Invalid decimal places");
        }

        DecimalFormatSymbols separators = new DecimalFormatSymbols(Locale.getDefault());
        separators.setMinusSign(SYMBOL_MINUS);
        separators.setZeroDigit(SYMBOL_ZERO);

        groupSeparator = separators.getGroupingSeparator();

        StringBuilder decimal = new StringBuilder();
        StringBuilder exponential = new StringBuilder("0.");

        for (int i = 0; i < DECIMAL_LEADING_GROUPS; i++) {
            decimal.append("###").append(i == DECIMAL_LEADING_GROUPS - 1 ? "." : ",");
        }

        for (int i = 0; i < decimalPlaces; i++) {
            decimal.append("#");
            exponential.append("0");
        }

        exponential.append("E0");

        decimalFormat = new DecimalFormat(decimal.toString(), separators);
        decimalFormatLong = new DecimalFormat(decimal.append("####").toString(), separators);
        exponentialFormat = new DecimalFormat(exponential.toString(), separators);

        decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
        decimalFormatLong.setRoundingMode(RoundingMode.HALF_UP);
        exponentialFormat.setRoundingMode(RoundingMode.HALF_UP);
    }

    public String format(double value) {
        String result;
        if (Double.isNaN(value)) {
            result = "";
        } else if (Double.isInfinite(value)) {
            result = String.valueOf(SYMBOL_INFINITE);
        } else {
            double absValue = Math.abs(value);
            if (absValue >= 1) {
                if (absValue >= EXPONENTIAL_INT_THRESHOLD) {
                    value = Math.floor(value);
                    result = exponentialFormat.format(value);
                } else {
                    result = decimalFormat.format(value);
                }
            } else if (absValue < 1 && absValue > 0) {
                if (absValue >= EXPONENTIAL_DEC_THRESHOLD) {
                    result = decimalFormat.format(value);
                    if (result.equalsIgnoreCase("0")) {
                        result = decimalFormatLong.format(value);
                    }
                } else {
                    result = exponentialFormat.format(value);
                }
            } else {
                result = "0";
            }
        }
        return result;
    }

    public String formatWithoutGroupSeparators(double value) {
        return removeGroupSeparators(format(value));
    }

    public double parse(String value, double defValue) {
        try {
            return decimalFormat.parse(value).doubleValue();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return defValue;
    }

    private String removeGroupSeparators(String number) {
        return number.replace(String.valueOf(groupSeparator), "");
    }

}

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

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

}

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

يوضح مقتطف الكود أدناه كيفية عرض أرقام 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();

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

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

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

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

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

كيفية تقريب رقم في جافا

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

Math.round(3.7) // 4

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

دائري

وكما ذكر أعلاه، يتم تقريب هذا إلى أقرب عدد صحيح. .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

سقف

يتم تقريب أي قيمة عشرية إلى العدد الصحيح التالي.يذهب إلى سقفعمل.ترجع هذه الطريقة أ 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

أرضية

يتم تقريب أي قيمة عشرية إلى العدد الصحيح التالي.ترجع هذه الطريقة أ 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

رينت

وهذا مشابه لتقريب تلك القيم العشرية إلى أقرب عدد صحيح.ومع ذلك، على عكس 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 ***

ولتحقيق ذلك يمكننا استخدام هذا المنسق:

 DecimalFormat df = new DecimalFormat("#.00");
 String resultado = df.format(valor)

أو:

DecimalFormat df = new DecimalFormat("0.00"); :

استخدم هذه الطريقة لتحصل دائمًا على رقمين عشريين:

   private static String getTwoDecimals(double value){
      DecimalFormat df = new DecimalFormat("0.00"); 
      return df.format(value);
    }

تعريف هذه القيم:

91.32
5.22
11.5
1.2
2.6

باستخدام الطريقة يمكننا الحصول على هذه النتائج:

91.32
5.22
11.50
1.20
2.60

التجريبي على الانترنت.

وأنا أتفق مع الإجابة المختارة للاستخدام DecimalFormat --- أو بدلا من ذلك BigDecimal.

يرجى القراءة تحديث أدناه أولا!

ولكن إذا كنت يفعل تريد تقريب القيمة المزدوجة والحصول على double نتيجة القيمة، يمكنك استخدامها org.apache.commons.math3.util.Precision.round(..) كما ذكر أعلاه.يستخدم التنفيذ BigDecimal, ، بطيء ويخلق القمامة.

يتم توفير طريقة مشابهة ولكنها سريعة وخالية من القمامة بواسطة DoubleRounder الأداة المساعدة في مكتبة Decimal4j:

 double a = DoubleRounder.round(2.0/3.0, 3);
 double b = DoubleRounder.round(2.0/3.0, 3, RoundingMode.DOWN);
 double c = DoubleRounder.round(1000.0d, 17);
 double d = DoubleRounder.round(90080070060.1d, 9);
 System.out.println(a);
 System.out.println(b);
 System.out.println(c);
 System.out.println(d);

سوف الإخراج

 0.667
 0.666
 1000.0
 9.00800700601E10

يرىhttps://github.com/tools4j/decimal4j/wiki/DoubleRounder-Utility

تنصل: أنا منخرط في مشروع Decimal4j.

تحديث:كما أشارiaforek إلى أن DoubleRounder يُرجع أحيانًا نتائج غير بديهية.والسبب هو أنه يقوم بالتقريب الصحيح رياضيًا.على سبيل المثال DoubleRounder.round(256.025d, 2) سيتم تقريبه إلى 256.02 لأن القيمة المزدوجة الممثلة بـ 256.025d أصغر إلى حد ما من القيمة المنطقية 256.025 وبالتالي سيتم تقريبها للأسفل.

ملحوظات:

  • هذا السلوك مشابه جدًا لسلوك BigDecimal(double) منشئ (ولكن ليس ل valueOf(double) الذي يستخدم منشئ السلسلة).
  • يمكن التحايل على المشكلة بخطوة تقريب مزدوجة لدقة أعلى أولا، لكن الأمر معقد ولن أخوض في التفاصيل هنا

لتلك الأسباب وكل ما ذكر أعلاه في هذا المنشور أنا لا يمكن التوصية باستخدام DoubleRounder.

إذا كنت تستخدم تقنية تحتوي على الحد الأدنى من JDK.إليك طريقة بدون أي Java libs:

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

يعد 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 العودة 0.3000000000000004.

أين موانئ دبي = مكان عشري تريده ، و قيمة هو مزدوج.

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

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

ضع في اعتبارك أن String.format() وDecimalFormat ينتجان سلسلة باستخدام اللغة الافتراضية.لذلك يمكنهم كتابة رقم منسق بنقطة أو فاصلة كفاصل بين الأجزاء الصحيحة والعشرية.للتأكد من أن السلسلة المستديرة بالتنسيق الذي تريده، استخدم java.text.NumberFormat على النحو التالي:

  Locale locale = Locale.ENGLISH;
  NumberFormat nf = NumberFormat.getNumberInstance(locale);
  // for trailing zeros:
  nf.setMinimumFractionDigits(2);
  // round to 2 digits:
  nf.setMaximumFractionDigits(2);

  System.out.println(nf.format(.99));
  System.out.println(nf.format(123.567));
  System.out.println(nf.format(123.0));

ستتم الطباعة باللغة الإنجليزية (بغض النظر عن لغتك):0.99 123.57 123.00

المثال مأخوذ من Farenda - كيفية تحويل مزدوج إلى سلسلة بشكل صحيح.

إذا كنت تنظر إلى 5 أو n عدد عشري.ربما تكون هذه الإجابة هي الحل لمشكلتك.

    double a = 123.00449;
    double roundOff1 = Math.round(a*10000)/10000.00;
    double roundOff2 = Math.round(roundOff1*1000)/1000.00;
    double roundOff = Math.round(roundOff2*100)/100.00;

    System.out.println("result:"+roundOff);

سيكون الإخراج: 123.01
يمكن حل هذا باستخدام الحلقة والوظيفة العودية.

بشكل عام، يتم التقريب عن طريق القياس: 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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top