একটি তালিকা তৈরির সর্বোত্তম উপায় <ডাবল> দেওয়া শুরু, শেষ এবং পদক্ষেপের মানগুলির ক্রম?


14

আমি আসলে খুব অবাক হয়েছি আমি এখানে এর উত্তর খুঁজে নিতে পারিনি, যদিও আমি কেবল ভুল অনুসন্ধানের শব্দ বা কিছু ব্যবহার করছি। নিকটতম আমি খুঁজে পাইনি এই , কিন্তু তারা একটি নির্দিষ্ট সীমার উৎপাদিত সম্পর্কে জিজ্ঞাসা doubleএকটি নির্দিষ্ট পদক্ষেপ আকার সঙ্গে s, এবং উত্তর যেমন এটা আচরণ। আমার এমন কিছু দরকার যা স্বেচ্ছাসেবী শুরু, শেষ এবং ধাপের আকারের সাথে সংখ্যাগুলি তৈরি করবে।

আমি চিন্তা সেখানে রয়েছে কোথাও ইতিমধ্যে একটি লাইব্রেরিতে এই মত কিছু পদ্ধতি, কিন্তু যদি তাই আমি এটিকে সহজে খুঁজে পেতে সক্ষম ছিল না (আবার, হয়তো আমি শুধু ভুল খঁোজা বা কিছু ব্যবহার করছি)। এটি করার জন্য আমি কয়েক মিনিটের মধ্যে নিজের থেকে কী রান্না করেছি তা এখানে:

import java.lang.Math;
import java.util.List;
import java.util.ArrayList;

public class DoubleSequenceGenerator {


     /**
     * Generates a List of Double values beginning with `start` and ending with
     * the last step from `start` which includes the provided `end` value.
     **/
    public static List<Double> generateSequence(double start, double end, double step) {
        Double numValues = (end-start)/step + 1.0;
        List<Double> sequence = new ArrayList<Double>(numValues.intValue());

        sequence.add(start);
        for (int i=1; i < numValues; i++) {
          sequence.add(start + step*i);
        }

        return sequence;
    }

    /**
     * Generates a List of Double values beginning with `start` and ending with
     * the last step from `start` which includes the provided `end` value.
     * 
     * Each number in the sequence is rounded to the precision of the `step`
     * value. For instance, if step=0.025, values will round to the nearest
     * thousandth value (0.001).
     **/
    public static List<Double> generateSequenceRounded(double start, double end, double step) {

        if (step != Math.floor(step)) {
            Double numValues = (end-start)/step + 1.0;
            List<Double> sequence = new ArrayList<Double>(numValues.intValue());

            double fraction = step - Math.floor(step);
            double mult = 10;
            while (mult*fraction < 1.0) {
                mult *= 10;
            }

            sequence.add(start);
            for (int i=1; i < numValues; i++) {
              sequence.add(Math.round(mult*(start + step*i))/mult);
            }

            return sequence;
        }

        return generateSequence(start, end, step);
    }

}

এই পদ্ধতিগুলি stepসিক্যুয়েন্স সূচক দ্বারা গুণিত করে startঅফসেটে যোগ করে একটি সাধারণ লুপ চালায় । এটি ক্রমবর্ধমান ভাসমান-পয়েন্ট ত্রুটিগুলি হ্রাস করে যা ক্রমাগত বর্ধনের সাথে ঘটে (যেমন stepপ্রতিটি পুনরাবৃত্তির উপর একটি ভেরিয়েবল যুক্ত করে)।

আমি generateSequenceRoundedcases ক্ষেত্রেগুলির জন্য পদ্ধতিটি যুক্ত করেছি যেখানে ভগ্নাংশের পদক্ষেপের আকারটি লক্ষণীয় ভাসমান-পয়েন্ট ত্রুটির কারণ হতে পারে। এটির জন্য আরও কিছু গাণিতিক প্রয়োজন, সুতরাং আমাদের মতো চূড়ান্ত পারফরম্যান্স সংবেদনশীল পরিস্থিতিতে, যখন গোলটি অপ্রয়োজনীয় হয় তখন সহজ পদ্ধতিটি ব্যবহার করার বিকল্পটি পাওয়া ভাল। আমার সন্দেহ হয় যে বেশিরভাগ সাধারণ ব্যবহারের ক্ষেত্রে গোলাকার ওভারহেডটি নগণ্য হবে।

লক্ষ্য করুন আমি ইচ্ছাকৃতভাবে হ্যান্ডলিং যেমন "অস্বাভাবিক" আর্গুমেন্ট জন্য যুক্তিবিজ্ঞান বহির্ভূত Infinity, NaN, start> end, অথবা একটি নেতিবাচক stepসরলীকরণের জন্য আকার এবং হাতের প্রশ্ন উপর ফোকাস করার ইচ্ছা।

এখানে কয়েকটি ব্যবহার এবং সম্পর্কিত আউটপুট উদাহরণ রয়েছে:

System.out.println(DoubleSequenceGenerator.generateSequence(0.0, 2.0, 0.2))
System.out.println(DoubleSequenceGenerator.generateSequenceRounded(0.0, 2.0, 0.2));
System.out.println(DoubleSequenceGenerator.generateSequence(0.0, 102.0, 10.2));
System.out.println(DoubleSequenceGenerator.generateSequenceRounded(0.0, 102.0, 10.2));
[0.0, 0.2, 0.4, 0.6000000000000001, 0.8, 1.0, 1.2000000000000002, 1.4000000000000001, 1.6, 1.8, 2.0]
[0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0]
[0.0, 10.2, 20.4, 30.599999999999998, 40.8, 51.0, 61.199999999999996, 71.39999999999999, 81.6, 91.8, 102.0]
[0.0, 10.2, 20.4, 30.6, 40.8, 51.0, 61.2, 71.4, 81.6, 91.8, 102.0]

ইতিমধ্যে এই ধরনের কার্যকারিতা সরবরাহ করে এমন কোনও গ্রন্থাগার রয়েছে কি?

যদি তা না হয় তবে আমার পদ্ধতির সাথে কোনও সমস্যা আছে?

কারও কি এই সম্পর্কে আরও ভাল পদ্ধতির থাকতে পারে?

উত্তর:


17

জাভা 11 স্ট্রিম এপিআই ব্যবহার করে সিকোয়েন্সগুলি সহজেই তৈরি করা যায়।

সোজা পদ্ধতি ব্যবহার করা হয় DoubleStream:

public static List<Double> generateSequenceDoubleStream(double start, double end, double step) {
  return DoubleStream.iterate(start, d -> d <= end, d -> d + step)
      .boxed()
      .collect(toList());
}

বিপুল সংখ্যক পুনরাবৃত্তি সহ রেঞ্জগুলিতে, doubleনির্ভুল ত্রুটিটি পরিসীমাটির শেষের কাছাকাছি হওয়ার ফলে আরও বড় ত্রুটি জমে যেতে পারে। IntStreamপূর্ণসংখ্যা এবং একক ডাবল গুণককে স্যুইচ করে এবং ব্যবহার করে ত্রুটিটি হ্রাস করা যায় :

public static List<Double> generateSequenceIntStream(int start, int end, int step, double multiplier) {
  return IntStream.iterate(start, i -> i <= end, i -> i + step)
      .mapToDouble(i -> i * multiplier)
      .boxed()
      .collect(toList());
}

doubleযথার্থ ত্রুটি থেকে মুক্তি পাওয়ার জন্য BigDecimalব্যবহার করা যেতে পারে:

public static List<Double> generateSequenceBigDecimal(BigDecimal start, BigDecimal end, BigDecimal step) {
  return Stream.iterate(start, d -> d.compareTo(end) <= 0, d -> d.add(step))
      .mapToDouble(BigDecimal::doubleValue)
      .boxed()
      .collect(toList());
}

উদাহরণ:

public static void main(String[] args) {
  System.out.println(generateSequenceDoubleStream(0.0, 2.0, 0.2));
  //[0.0, 0.2, 0.4, 0.6000000000000001, 0.8, 1.0, 1.2, 1.4, 1.5999999999999999, 1.7999999999999998, 1.9999999999999998]

  System.out.println(generateSequenceIntStream(0, 20, 2, 0.1));
  //[0.0, 0.2, 0.4, 0.6000000000000001, 0.8, 1.0, 1.2000000000000002, 1.4000000000000001, 1.6, 1.8, 2.0]

  System.out.println(generateSequenceBigDecimal(new BigDecimal("0"), new BigDecimal("2"), new BigDecimal("0.2")));
  //[0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0]
}

জাভা 9-এ এই স্বাক্ষর (3 পরামিতি) সহ পদ্ধতি পুনরাবৃত্তি যুক্ত করা হয়েছিল So সুতরাং, জাভা 8-র জন্য কোডটি দেখে মনে হচ্ছে

DoubleStream.iterate(start, d -> d + step)
    .limit((int) (1 + (end - start) / step))

এটি ভাল পদ্ধতির হয়।
বিশ্ব রত্না

আমি বিভিন্ন সংকলন ত্রুটি (JDK 1.8.0) এইজন্য করছি: error: method iterate in interface DoubleStream cannot be applied to given types; return DoubleStream.iterate(start, d -> d <= end, d -> d + step) required: double,DoubleUnaryOperator. found: double,(d)->d <= end,(d)->d + step. reason: actual and formal argument lists differ in lengthIntStream.iterateএবং এর জন্য অনুরূপ ত্রুটি Stream.iterate। এছাড়াও non-static method doubleValue() cannot be referenced from a static context,।
ন্যানো উইজার্ড


@ ন্যানো উইজার্ড জাভা 8
এভেজেনি খাইস্ট

তিন যুক্তিযুক্ত পুনরাবৃত্তকারীটি জাভা 9-এ যুক্ত করা হয়েছে
থরবজর্ন রাভন অ্যান্ডারসন

3

আমাকে ব্যক্তিগতভাবে, আমি সংক্ষিপ্ত করা হবে ডাবল সিক্যুইয়েন্স জেনারেটর ক্লাসটি অন্য গুডির জন্য কিছুটা দিয়েছি এবং কেবলমাত্র একটি সিকোয়েন্স জেনারেটর পদ্ধতি ব্যবহার করব যাতে পছন্দসই নির্ভুলতা যা চায় তা ব্যবহার করতে বা কোনও নির্ভুলতা ব্যবহার করতে পারে না:

নীচের জেনারেটর পদ্ধতিতে, nothing চ্ছিক সেটপ্রেসিশন প্যারামিটারে যদি কিছুই (বা 0 এর চেয়ে কম মান ) সরবরাহ করা হয় না তবে কোনও দশমিক নির্ভুলতা রাউন্ডিং করা হয় না। যদি 0 একটি নির্ভুল মানের জন্য সরবরাহ করা হয় তবে সংখ্যাগুলি তাদের নিকটতম সম্পূর্ণ সংখ্যায় বৃত্তাকার হয় (যেমন: 89.674 গোলটি 90.0 তে হয়)। যদি 0 এর চেয়ে বেশি নির্দিষ্ট কোনও যথার্থ মান সরবরাহ করা হয় তবে মানগুলি দশমিক নির্ভুলতায় রূপান্তরিত হয়।

বিগডিসিমাল এখানে ... ভাল .... নির্ভুলতার জন্য ব্যবহৃত হয়

import java.util.List;
import java.util.ArrayList;
import java.math.BigDecimal;
import java.math.RoundingMode;

public class DoubleSequenceGenerator {

     public static List<Double> generateSequence(double start, double end, 
                                          double step, int... setPrecision) {
        int precision = -1;
        if (setPrecision.length > 0) {
            precision = setPrecision[0];
        }
        List<Double> sequence = new ArrayList<>();
        for (double val = start; val < end; val+= step) {
            if (precision > -1) {
                sequence.add(BigDecimal.valueOf(val).setScale(precision, RoundingMode.HALF_UP).doubleValue());
            }
            else {
                sequence.add(BigDecimal.valueOf(val).doubleValue());
            }
        }
        if (sequence.get(sequence.size() - 1) < end) { 
            sequence.add(end); 
        }
        return sequence;
    }    

    // Other class goodies here ....
}

এবং প্রধান ():

System.out.println(generateSequence(0.0, 2.0, 0.2));
System.out.println(generateSequence(0.0, 2.0, 0.2, 0));
System.out.println(generateSequence(0.0, 2.0, 0.2, 1));
System.out.println();
System.out.println(generateSequence(0.0, 102.0, 10.2, 0));
System.out.println(generateSequence(0.0, 102.0, 10.2, 0));
System.out.println(generateSequence(0.0, 102.0, 10.2, 1));

এবং কনসোলটি প্রদর্শন করে:

[0.0, 0.2, 0.4, 0.6000000000000001, 0.8, 1.0, 1.2, 1.4, 1.5999999999999999, 1.7999999999999998, 1.9999999999999998, 2.0]
[0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0]
[0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0]

[0.0, 10.2, 20.4, 30.599999999999998, 40.8, 51.0, 61.2, 71.4, 81.60000000000001, 91.80000000000001, 102.0]
[0.0, 10.0, 20.0, 31.0, 41.0, 51.0, 61.0, 71.0, 82.0, 92.0, 102.0]
[0.0, 10.2, 20.4, 30.6, 40.8, 51.0, 61.2, 71.4, 81.6, 91.8, 102.0]

আকর্ষণীয় ধারণা, যদিও আমি কয়েকটি সমস্যা দেখছি see 1. valপ্রতিটি পুনরাবৃত্তিতে যোগ করে আপনি অ্যাডিটিভ নির্ভুলতা হারাচ্ছেন। খুব বড় ক্রমের জন্য, শেষ কয়েকটি সংখ্যায় ত্রুটিটি উল্লেখযোগ্য হতে পারে। ২. বার বার কল করা BigDecimal.valueOf()তুলনামূলকভাবে ব্যয়বহুল। ইনপুটগুলিকে এসগুলিতে রূপান্তর করে এবং BigDecimalএর BigDecimalজন্য ব্যবহার করে আপনি আরও ভাল পারফরম্যান্স (এবং নির্ভুলতা) পাবেন val। আসলে, এর doubleজন্য ব্যবহার করে valআপনি BigDecimalসম্ভবত গোলটি বাদ দিয়ে ব্যবহার করে কোনও নির্ভুল সুবিধা পাচ্ছেন না ।
ন্যানো উইজার্ড

2

এটা চেষ্টা কর.

public static List<Double> generateSequenceRounded(double start, double end, double step) {
    long mult = (long) Math.pow(10, BigDecimal.valueOf(step).scale());
    return DoubleStream.iterate(start, d -> (double) Math.round(mult * (d + step)) / mult)
                .limit((long) (1 + (end - start) / step)).boxed().collect(Collectors.toList());
}

এখানে,

int java.math.BigDecimal.scale()

এই বিগডিসিমালের স্কেলটি ফিরিয়ে দেয়। যদি শূন্য বা ধনাত্মক হয় তবে স্কেল হ'ল দশমিক বিন্দুর ডানদিকে অঙ্কের সংখ্যা। যদি negativeণাত্মক হয় তবে সংখ্যাটির আনসেল্ড মানকে দশ দ্বারা গুণিত করে স্কেলকে অস্বীকার করার শক্তি দেওয়া হবে। উদাহরণস্বরূপ, -3 এর স্কেল মানে আনস্কেল করা মান 1000 দ্বারা গুণিত হয়।

প্রধান ()

System.out.println(generateSequenceRounded(0.0, 102.0, 10.2));
System.out.println(generateSequenceRounded(0.0, 102.0, 10.24367));

এবং আউটপুট:

[0.0, 10.2, 20.4, 30.6, 40.8, 51.0, 61.2, 71.4, 81.6, 91.8, 102.0]
[0.0, 10.24367, 20.48734, 30.73101, 40.97468, 51.21835, 61.46202, 71.70569, 81.94936, 92.19303]

2
  1. ইতিমধ্যে এই ধরনের কার্যকারিতা সরবরাহ করে এমন কোনও গ্রন্থাগার রয়েছে কি?

    দুঃখিত, আমি জানি না, তবে অন্যান্য উত্তর দিয়ে বিচার করা, এবং তাদের আপেক্ষিক সরলতা - না, নেই isn't দরকার নেই. ভাল প্রায়...

  2. যদি তা না হয় তবে আমার পদ্ধতির সাথে কোনও সমস্যা আছে?

    হ্যা এবং না. আপনার কাছে কমপক্ষে একটি ত্রুটি রয়েছে, এবং পারফরম্যান্স বৃদ্ধির জন্য কিছু জায়গা রয়েছে, তবে এ্যাকিউশনটি নিজেই সঠিক।

    1. আপনার বাগ: rounding ত্রুটি (শুধু পরিবর্তন while (mult*fraction < 1.0)করার while (mult*fraction < 10.0)এবং যে এটা ঠিক উচিত)
    2. অন্য সমস্ত end... এ পৌঁছায় না , ঠিক আছে, সম্ভবত তারা আপনার কোডটিতে মন্তব্যগুলি পড়ার পক্ষে যথেষ্ট পর্যবেক্ষক ছিল না
    3. অন্য সব ধীরে ধীরে।
    4. শুধু প্রধান লুপ শর্ত পরিবর্তন করা থেকে int < Doubleথেকে int < intলক্ষণীয়ভাবে আপনার কোড গতি বৃদ্ধি পাবে
  3. কারও কি এই সম্পর্কে আরও ভাল পদ্ধতির থাকতে পারে?

    হুম ... কীভাবে?

    1. সরলতা? generateSequenceDoubleStream@ এভেজেনি খিস্টকে দেখতে খুব সহজ দেখাচ্ছে। এবং ব্যবহার করা উচিত ... তবে সম্ভবত না, কারণ পরবর্তী দুটি পয়েন্ট
    2. সঠিক? generateSequenceDoubleStreamএটি না! তবুও প্যাটার্ন দিয়ে সংরক্ষণ করা যায় start + step*i। এবং start + step*iনিদর্শন সুনির্দিষ্ট। কেবলমাত্র BigDoubleএবং স্থির-পয়েন্টের গাণিতিকগুলি এটি বীট করতে পারে। তবে BigDoubleগুলি ধীরে ধীরে এবং ম্যানুয়াল ফিক্সড পয়েন্ট গাণিতিক ক্লান্তিকর এবং এটি আপনার ডেটার জন্য অনুপযুক্ত হতে পারে। উপায় দ্বারা, নির্ভুলতার বিষয়ে, আপনি এটি দিয়ে নিজেকে বিনোদন দিতে পারেন: https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
    3. গতি ... ভাল এখন আমরা নড়বড়ে মাঠে আছি। এই repl টি দেখুন https://repl.it/repls/RespectfulSu کافیWorker আমার মুহুর্তে একটি শালীন পরীক্ষার স্ট্যান্ড নেই, তাই আমি repl.it ব্যবহার করেছি ... যা পারফরম্যান্স পরীক্ষার জন্য সম্পূর্ণ অপ্রতুল, তবে এটি মূল বিষয় নয়। মুল বক্তব্যটি - এর কোনও নির্দিষ্ট উত্তর নেই। আপনার ক্ষেত্রে যা সম্ভবত আপনার প্রশ্ন থেকে সম্পূর্ণ পরিষ্কার নয়, আপনি অবশ্যই বিগডিসিমাল ব্যবহার করবেন না (আরও পড়ুন)।

      আমি বড় ইনপুটগুলি খেলতে এবং অনুকূলিত করার চেষ্টা করেছি। এবং কিছু অল্প পরিবর্তন সহ আপনার মূল কোড - দ্রুততম। তবে আপনার খুব অল্প পরিমাণে দরকার List? তাহলে এটি সম্পূর্ণ আলাদা গল্প হতে পারে।

      এই কোডটি আমার স্বাদে বেশ সহজ এবং যথেষ্ট দ্রুত:

        public static List<Double> genNoRoundDirectToDouble(double start, double end, double step) {
        int len = (int)Math.ceil((end-start)/step) + 1;
        var sequence = new ArrayList<Double>(len);
        sequence.add(start);
        for (int i=1 ; i < len ; ++i) sequence.add(start + step*i);
        return sequence;
        }

    আপনি যদি আরও মার্জিত উপায়ে পছন্দ করেন (বা আমরা এটিকে idiomatic বলা উচিত), আমি ব্যক্তিগতভাবে পরামর্শ দেব:

    public static List<Double> gen_DoubleStream_presice(double start, double end, double step) {
        return IntStream.range(0, (int)Math.ceil((end-start)/step) + 1)
            .mapToDouble(i -> start + i * step)
            .boxed()
            .collect(Collectors.toList());
    }

    যাইহোক, সম্ভাব্য পারফরম্যান্সের উত্সাহগুলি হ'ল:

    1. এ থেকে স্যুইচ Doubleকরার চেষ্টা করুন doubleএবং যদি আপনার সত্যিই তাদের প্রয়োজন হয় তবে আপনি পরীক্ষার দ্বারা বিচার করে আবার ফিরে যেতে পারেন, এটি আরও দ্রুত হতে পারে। (তবে আমার উপর বিশ্বাস করবেন না, আপনার পরিবেশে আপনার ডেটা দিয়ে নিজেই চেষ্টা করুন As যেমনটি আমি বলেছি - repl.it বেঞ্চমার্কের জন্য সফলকাম)
    2. একটি সামান্য যাদু: এর জন্য পৃথক লুপ Math.round()... এটির ডেটার লোকালটির সাথে কিছু করার আছে। আমি এটির প্রস্তাব দিচ্ছি না - ফলাফলটি খুব অস্থির। তবে মজা।

      double[] sequence = new double[len];
      for (int i=1; i < len; ++i) sequence[i] = start + step*i;
      List<Double> list = new ArrayList<Double>(len);
      list.add(start);
      for (int i=1; i < len; ++i) list.add(Math.round(sequence[i])/mult);
      return list;
    3. আপনি অবশ্যই আরও অলস হিসাবে বিবেচনা করুন এবং Listএর পরে স্টোর না করে চাহিদা অনুযায়ী সংখ্যা উত্পন্ন করুন

  4. আমার সন্দেহ হয় যে বেশিরভাগ সাধারণ ব্যবহারের ক্ষেত্রে গোলাকার ওভারহেডটি নগণ্য হবে।

    যদি আপনি কিছু সন্দেহ করেন - এটি পরীক্ষা করুন :-) আমার উত্তরটি "হ্যাঁ", তবে আবার ... আমাকে বিশ্বাস করবেন না। এটা পরীক্ষা করো.

সুতরাং, মূল প্রশ্নে ফিরে আসুন: এর চেয়ে ভাল উপায় কি আছে?
হ্যা অবশ্যই!
তবে এটি নির্ভর করে।

  1. আপনার খুব বড় সংখ্যা এবং খুব অল্প সংখ্যক প্রয়োজন হলে বড় দশমিক চয়ন করুন । তবে আপনি যদি এগুলিকে পিছনে ফেলে দেন এবং তার চেয়েও বেশি কিছু এটি "সংখ্যক" কাছাকাছি মানের সাথে ব্যবহার করেন - তাদের প্রয়োজন নেই! একই প্রতিস্থাপনটি চেকআউট করুন: https://repl.it/repls/RespectfulSufficientWorker - শেষ পরীক্ষাটি ফলাফলের মধ্যে কোনও পার্থক্য দেখাবে না , তবে গতিতে একটি খননের ক্ষতি হবে।Double
  2. আপনার ডেটা বৈশিষ্ট্য, আপনার কার্য এবং আপনার পরিবেশের উপর ভিত্তি করে কিছু মাইক্রো-অপ্টিমাইজেশন করুন।
  3. সংক্ষিপ্ত এবং সাধারণ কোডটি পছন্দ করুন যদি 5-10% এর পারফরম্যান্স বুস্ট থেকে বেশি কিছু পাওয়া যায় না। আপনার সময় কোমর করবেন না
  4. আপনি যদি এটি করতে পারেন তবে এটি স্থির-পয়েন্ট পাটিগণিতটি ব্যবহার করুন এবং এটির পক্ষে মূল্যবান যদি হয়।

তা ছাড়া আপনি ভাল আছেন।

দ্রষ্টব্য । Repl এ একটি Kahan Sumration সূত্র বাস্তবায়নও আছে ... শুধু মজাদার জন্য। https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html#1346 এবং এটি কাজ করে - আপনি সামিটের ত্রুটিগুলি প্রশমিত করতে পারেন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.