দ্বিগুণ মানগুলির জন্য assertEquals এর অ্যাপসিলন যুক্তির অর্থ


187

আমার assertEqualsদ্বিগুণ মান পরীক্ষা করার জন্য জুনিট সম্পর্কে একটি প্রশ্ন আছে । এপিআই ডকটি পড়া আমি দেখতে পাচ্ছি:

@Deprecated
public static void assertEquals(double expected, double actual)

অননুমোদিত। পরিবর্তে assertEquals (ডাবল প্রত্যাশিত, ডাবল প্রকৃত, ডাবল এপসিলন) ব্যবহার করুন

কী epsilonমান মানে? (এপসিলন গ্রীক বর্ণমালার একটি অক্ষর, তাই না?)

কেউ কীভাবে এটি ব্যবহার করবেন তা আমাকে ব্যাখ্যা করতে পারেন?

উত্তর:


198

অ্যাপসিলন এমন মান যা 2 সংখ্যাটি বন্ধ করে দেওয়া যায়। সুতরাং এটি হিসাবে দীর্ঘ হিসাবে সত্য দৃsert়তা হবেMath.abs(expected - actual) < epsilon


3
তাই আমি অ্যাপসিলন হিসাবে কোন মান পাস করা উচিত?
পান্না

15
@ পান্না 214 যথার্থতার পরিমাণ। আপনি যদি জোড় করে বলতে চান যে ডাবল মান 0 ডি এপিসিলন 0 হবে (100% যথার্থতা, কোনও ব্যতিক্রম নয়)। আপনি যদি মার্জিনের ত্রুটি চান (ডিগ্রির জন্য বলুন) আপনি অ্যাপসিলনটিকে 1 তে সেট করতে পারেন যার অর্থ, উদাহরণস্বরূপ, .2৪.২ 64 .8৪.৮ as এর সমান (যেহেতু অ্যাবস (.864..8-64৪.২) <1)
পিটার ডি

3
ডকুমেন্টেশনটি বলে, "ব-দ্বীপ - প্রত্যাশিত এবং বাস্তবের মধ্যে সর্বাধিক ব-দ্বীপ যার জন্য উভয় সংখ্যা সমান বলে বিবেচিত হয়।" তাই আমি মনে করি এটি একটি হওয়া উচিত <=নয় <
অ্যান্ড্রু চিউং

কোডটি দেখে, আমি দেখতে পাচ্ছি এটি পদ্ধতিটিকে doubleIsDifferent(দ্বিগুণ মানের তুলনা করার জন্য) কল করে এবং এটি ফিরে আসে Math.abs(d1 - d2) > delta। সুতরাং যদি ডি 1 এবং ডি 2 এর মধ্যে পার্থক্যটি ব-দ্বীপের চেয়ে বেশি হয়, তার মানে মানগুলি পৃথক এবং সত্য ফিরে আসবে। মানগুলি সমান বিবেচিত হলে এটি মিথ্যা প্রত্যাবর্তন করবে। সেই পদ্ধতিটি assertEquals এ ডাইরেক্টভাবে ডাকা হয় এবং এটি যদি সত্য হয়, assertEquals কল করবে failNotEqualsএবং পরীক্ষার ফলাফল ব্যর্থ হবে।
অ্যান্থোম্যাক্সকুল

1
@ জবার্ট কেউ যদি পরামর্শ দিতে পারেন যে আমি যদি প্রচুর সংখ্যার গড় গড় বা স্ট্যান্ডার্ড বিচ্যুতি নিয়ে কাজ করে থাকি তবে সাধারণ এপসিলনের দ্বিগুণ মূল্য কী হতে পারে?
অনুমানকারী

121

JUnit এর কোন সংস্করণ এটি? আমি কেবল কখনও ডেল্টা দেখেছি, এপসিলন নয় - তবে এটি একটি পার্শ্ব সমস্যা!

JUnit থেকে javadoc :

ব-দ্বীপ - প্রত্যাশিত এবং বাস্তবের মধ্যে সর্বাধিক ব-দ্বীপ যার জন্য উভয় সংখ্যা সমান বলে বিবেচিত হয়।

এটি সম্ভবত ওভারকিল, তবে আমি সাধারণত খুব কম সংখ্যক ব্যবহার করি, যেমন

private static final double DELTA = 1e-15;

@Test
public void testDelta(){
    assertEquals(123.456, 123.456, DELTA);
}

আপনি যদি হ্যামক্রেস্ট সংস্থান ব্যবহার করছেন , আপনি কেবলমাত্র equalTo()দুটি ডাবল সহ স্ট্যান্ডার্ডটি ব্যবহার করতে পারেন (এটি একটি ব-দ্বীপ ব্যবহার করে না)। তবে আপনি যদি একটি ব-দ্বীপ চান, আপনি কেবল ব্যবহার করতে পারেন closeTo()( জাভাদোক দেখুন ), যেমন

private static final double DELTA = 1e-15;

@Test
public void testDelta(){
    assertThat(123.456, equalTo(123.456));
    assertThat(123.456, closeTo(123.456, DELTA));
}

এফওয়াইআই আসন্ন জুনিয়ট 5 দুটি ডাবল সহ কল করার সময় ব- দ্বীপটিকে alচ্ছিকও করবে assertEquals()বাস্তবায়ন (আপনি আগ্রহী হন, তাহলে) হল:

private static boolean doublesAreEqual(double value1, double value2) {
    return Double.doubleToLongBits(value1) == Double.doubleToLongBits(value2);
}

57

ভাসমান পয়েন্ট গণনা সঠিক নয় - প্রায়শই গোল-বন্ধ ত্রুটি এবং প্রতিনিধিত্বের কারণে ত্রুটি থাকে is (উদাহরণস্বরূপ, 0.1 বাইনারি ভাসমান পয়েন্টে হুবহু উপস্থাপন করা যাবে না))

এর কারণে, সাম্যতার জন্য দুটি ভাসমান পয়েন্টের মানগুলির সরাসরি তুলনা করা ভাল ধারণা নয়, কারণ তারা কীভাবে গণনা করা হয়েছিল তার উপর নির্ভর করে অল্প পরিমাণে তারা আলাদা হতে পারে।

"ডেল্টা", যেমন এটি ইউনাইট জাভাদোকগুলিতে বলা হয় , মানগুলি এখনও সমান বলে বিবেচিত হওয়ার জন্য আপনি যে পরিমাণ পার্থক্য সহ্য করতে পারেন তা বর্ণনা করে। এই মানটির আকারটি আপনি যে মানের সাথে তুলনা করছেন তার উপর সম্পূর্ণ নির্ভর করে। দ্বিগুণ তুলনা করার সময়, আমি সাধারণত প্রত্যাশিত মানটি 10 ​​^ 6 দ্বারা বিভক্ত করে ব্যবহার করি।


11

জিনিসটি হ'ল ভাসমান পয়েন্ট সংখ্যার অন্তর্নিহিত নির্ভুলতার কারণে দুটি ডাবল ঠিক সমান হতে পারে না। এই ডেল্টা মানটির সাহায্যে আপনি ত্রুটির কারণের ভিত্তিতে সমতার মূল্যায়ন নিয়ন্ত্রণ করতে পারেন।

এছাড়াও কিছু ভাসমান-পয়েন্টের মানগুলিতে বিশেষ মান থাকতে পারে যেমন এনএএন এবং -আইনফিনিটি / ইনফিনিটি যা ফলাফলকে প্রভাবিত করতে পারে।

আপনি যদি সত্যিই তুলনা করতে চান যে দুটি দ্বিগুণ ঠিক সমান এটি লম্বা উপস্থাপনা হিসাবে তাদের তুলনায় সেরা

Assert.assertEquals(Double.doubleToLongBits(expected), Double.doubleToLongBits(result));

অথবা

Assert.assertEquals(0, Double.compareTo(expected, result));

যা এই সূক্ষ্মতাকে আমলে নিতে পারে।

আমি প্রশ্নের মধ্যে থাকা দাবী পদ্ধতিতে উত্সাহিত করি নি, তবে আমি কেবলমাত্র ধরে নিতে পারি যে পূর্ববর্তী এই ধরণের সমস্যার জন্য অবহেলিত ছিল এবং নতুনটি সেগুলি অ্যাকাউন্টে নেবে না।


2

অ্যাপসিলন হ'ল expectedএবং actualমানগুলির মধ্যে একটি পার্থক্য যা আপনি তাদের সমান বলে ভেবে মেনে নিতে পারেন। আপনি .1উদাহরণস্বরূপ সেট করতে পারেন ।


2

মনে রাখবেন যে আপনি যদি গণিত করছেন না, সঠিক ভাসমান পয়েন্টের মানগুলি বলার সাথে কোনও ভুল নেই। এই ক্ষেত্রে:

public interface Foo {
    double getDefaultValue();
}

public class FooImpl implements Foo {
    public double getDefaultValue() { return Double.MIN_VALUE; }
}

এই ক্ষেত্রে, আপনি নিশ্চিত করতে চান যে এটি সত্যই MIN_VALUE, শূন্য নয় -MIN_VALUEবা MIN_NORMALবা অন্য কোনও খুব সামান্য মান। তুমি বলতে পারো

double defaultValue = new FooImpl().getDefaultValue();
assertEquals(Double.MIN_VALUE, defaultValue);

তবে এটি আপনাকে অবমূল্যায়নের সতর্কতা দেবে। এটি এড়াতে, আপনি assertEquals(Object, Object)পরিবর্তে কল করতে পারেন :

// really you just need one cast because of autoboxing, but let's be clear
assertEquals((Object)Double.MIN_VALUE, (Object)defaultValue);

এবং, আপনি যদি সত্যিই চতুর দেখতে চান:

assertEquals(
    Double.doubleToLongBits(Double.MIN_VALUE), 
    Double.doubleToLongBits(defaultValue)
);

অথবা আপনি কেবল হামক্রস্টের সাবলীল-শৈলীর অবস্থান ব্যবহার করতে পারেন:

// equivalent to assertEquals((Object)Double.MIN_VALUE, (Object)defaultValue);
assertThat(defaultValue, is(Double.MIN_VALUE));

মান তুমি পরীক্ষণ যদি না কিছু গণিত এর করছেন থেকে আসা, যদিও, Epsilon ব্যবহার করুন।


7
আপনি যদি ঠিক সমান হিসাবে পরীক্ষা করতে চান তবে এপসিলনকে 0.0 এ সেট করুন - অবজেক্ট ভেরিয়েন্টের প্রয়োজন নেই is
মেল নিকোলসন

-2
Assert.assertTrue(Math.abs(actual-expected) == 0)

ভাসমান পয়েন্ট নম্বর ব্যবহার করার সময় (যেমন ভাসা বা ডাবল), এটি নির্ভরযোগ্যভাবে কাজ করে না। আপনি জাভাতে ভাসমান পয়েন্ট সংখ্যা কীভাবে সংরক্ষণ করা হয় এবং গাণিতিক ক্রিয়াকলাপগুলি কীভাবে তাদের উপর কাজ করে তা পর্যালোচনা করতে চাইতে পারেন। (স্পয়লার: কিছু গোলাকার ত্রুটিগুলি আশা করুন!)
আটটিলা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.