জাভাতে অর্থের জন্য কী ডেটা ব্যবহার করতে হয়? [বন্ধ]


183

জাভাতে অর্থের জন্য আপনার কোন ডেটা টাইপ ব্যবহার করা উচিত?


2
এটি নির্ভর করে আপনি কী পরিচালনা করতে যাচ্ছেন। আরও তথ্য অফার করুন।
Eversor

@Eversor আপনি কি আমাকে বিভিন্ন ক্রিয়াকলাপের জন্য ডেটা টাইপ ব্যবহার করা উচিত তার বর্ণনা দিতে পারেন?
কোয়েস্টবার্ন

1
গণনা করছি যা আমার সঠিকভাবে সেন্ট উপস্থাপন করা প্রয়োজন।
কোয়েস্টবার্ন

আপনার অ্যাপ্লিকেশনটি যে পরিমাণ অর্থের প্রয়োজন হবে তা কী আপনি পূর্বাভাস দিতে সক্ষম? এবং, আপনার গণনা, তারা কি সরল (অ্যাডিশন ইত্যাদি) বা আরও জটিল আর্থিক ক্রিয়াকলাপ হতে চলেছে?
eversor

উত্তর:


133

জাভাতে Currencyক্লাস রয়েছে যা আইএসও 4217 মুদ্রা কোড উপস্থাপন করে। BigDecimalদশমিক মানগুলি উপস্থাপনের জন্য সেরা ধরণ।

জোদা মানি অর্থ উপস্থাপনের জন্য একটি লাইব্রেরি সরবরাহ করেছে।


5
কেন আমরা তার পরিবর্তে ভাসা বা ডাবল ব্যবহার করতে পারি না?
এরান মোরাড

20
@ বোরাট সাগদিয়েভ এই কারণেই । এছাড়াও, আপনি উল্লেখ করতে পারেন এই
বুহাকে সিন্ধি

2
@ ব্রারাট: আপনি কী করছেন তা যদি আপনি জানতে পারেন তবে পিটার লরির এই নিবন্ধটি দেখুন । তবে বিগডিসিমালগুলি ব্যবহার করার মতো সমস্ত বৃত্তাকারটি করা কমপক্ষে একটি ঝামেলা হিসাবে মনে হচ্ছে।
নাথান হিউজেস

35
"যদি আমার প্রত্যেকবার মুদ্রা সংরক্ষণের জন্য ফুল ব্যবহার করতে দেখা যায় তার জন্য যদি আমার কাছে একটি ডাইম থাকে তবে আমার কাছে $ 999.997634 থাকত" - বিল কারভিন
কলিন ক্রল

36

আপনি অর্থ এবং মুদ্রার এপিআই (জেএসআর 354) ব্যবহার করতে পারেন । আপনি যদি আপনার প্রকল্পে যথাযথ নির্ভরতা যুক্ত করেন তবে আপনি এই API এ ব্যবহার করতে পারেন।

জাভা 8 এর জন্য, আপনার উপর নির্ভরতা হিসাবে নিম্নলিখিত রেফারেন্স প্রয়োগটি যুক্ত করুন pom.xml:

<dependency>
    <groupId>org.javamoney</groupId>
    <artifactId>moneta</artifactId>
    <version>1.0</version>
</dependency>

এই নির্ভরতা ট্রানজিটিভভাবে নির্ভরতা javax.money:money-apiহিসাবে যুক্ত করবে ।

তারপরে আপনি এপিআই ব্যবহার করতে পারেন:

package com.example.money;

import static org.junit.Assert.assertThat;
import static org.hamcrest.CoreMatchers.is;

import java.util.Locale;

import javax.money.Monetary;
import javax.money.MonetaryAmount;
import javax.money.MonetaryRounding;
import javax.money.format.MonetaryAmountFormat;
import javax.money.format.MonetaryFormats;

import org.junit.Test;

public class MoneyTest {

    @Test
    public void testMoneyApi() {
        MonetaryAmount eurAmount1 = Monetary.getDefaultAmountFactory().setNumber(1.1111).setCurrency("EUR").create();
        MonetaryAmount eurAmount2 = Monetary.getDefaultAmountFactory().setNumber(1.1141).setCurrency("EUR").create();

        MonetaryAmount eurAmount3 = eurAmount1.add(eurAmount2);
        assertThat(eurAmount3.toString(), is("EUR 2.2252"));

        MonetaryRounding defaultRounding = Monetary.getDefaultRounding();
        MonetaryAmount eurAmount4 = eurAmount3.with(defaultRounding);
        assertThat(eurAmount4.toString(), is("EUR 2.23"));

        MonetaryAmountFormat germanFormat = MonetaryFormats.getAmountFormat(Locale.GERMAN);
        assertThat(germanFormat.format(eurAmount4), is("EUR 2,23") );
    }
}

সিরিয়ালাইজেশন এবং ডিবিতে সংরক্ষণের কী হবে? ওয়্যার ওভার প্রেরণের জন্য কোন ফর্ম্যাট ব্যবহার করা উচিত?
পাউয়ে জিজকুর

1
আমি বিশ্বাস করি যে ওরাকল জাভা 9-তে জাভা মানি সহ পুনর্বার উত্সর্গ করেছিল ally সত্যই লজ্জাজনক। তবে দুর্দান্ত উত্তর। আমরা এখনও মাভেন
বোরজব 7'16

3
আপনার কাছে জাভা 9-তে জাভা মানি অন্তর্ভুক্ত করার বিরুদ্ধে সিদ্ধান্ত নেওয়ার জন্য কি কোনও উত্স আছে?
আব্দুল

26

একটি অবিচ্ছেদ্য প্রকার যা সম্ভব ক্ষুদ্রতম মানকে উপস্থাপন করে। অন্য কথায় আপনার প্রোগ্রামটি ডলার / ইউরোতে নয় সেন্টে ভাবা উচিত।

এটি আপনাকে জিআই এর ডলার / ইউরোতে আবার অনুবাদ করতে বাধা দেওয়া উচিত নয়।


মনে রাখবেন যে টাকার
পরিমাণটি

5
@ ইউভার্সারের জন্য যা প্রায় 20 মিলিয়ন ডলারের বেশি পরিমাণে প্রয়োজন তাদের বেশি পরিমাণ অ্যাপ্লিকেশন প্রয়োজন হবে না যদি তারা দীর্ঘায়িত হয় তবে আমাদের সরকার এমনকি পর্যাপ্ত অর্থকে উপচে
রাচেট ফ্রিক

4
@ratchetfreak সম্ভবত দীর্ঘ সময় ব্যবহার করা ভাল।

4
অনেক ব্যাংক প্রতিদিন অনেক বড় পরিমাণে অর্থ handle 20,000,000 ডলার পরিচালনা করে। এটি ডলারের কাছে বড় বিনিময় হারের ইয়েনের মতো মুদ্রার অ্যাকাউন্টও নেয় না। বৃত্তাকার সমস্যাগুলি এড়ানোর জন্য পূর্ণসংখ্যার প্রকারগুলি সর্বোত্তম হতে পারে যদিও তারা আগ্রহ এবং বিনিময় হারের গণনার সাথে অগোছালো হয়ে যায়। যাইহোক, অ্যাপ্লিকেশন উপর নির্ভর করে আপনার একটি 64-বিট পূর্ণসংখ্যার প্রকারের প্রয়োজন হতে পারে।
অ্যালকিমিস্ট

আদর্শভাবে মাইক্রোডোলারস, আসলে, যদি আপনি উদাহরণস্বরূপ $ 10/3 করেন তবে রাউন্ডিং ত্রুটি (3333.3 => 3333.0) চূড়ান্ত মানটিকে ততটা প্রভাবিত করে না (এই ক্ষেত্রে এটি আসল মানটিকে মোটেই প্রভাবিত করে না, যদিও এটি এটা কখনই হবে না ধরে নেওয়া বিপজ্জনক)। আপনার ব্যবহারকারী ফলাফলটি দেখার আগে আপনি যদি একনাগাড়ে অনেকগুলি গণনা করে থাকেন তবে এটি বিশেষভাবে গুরুত্বপূর্ণ, কারণ গোলাকার ত্রুটিগুলি আরও জটিল হবে।
ক্রিস ব্রাউন


11

জেএসআর 354: অর্থ এবং মুদ্রার এপিআই

জেএসআর 354 অর্থ এবং মুদ্রার সাথে ব্যাপক গণনা উপস্থাপন, পরিবহন এবং সম্পাদনের জন্য একটি এপিআই সরবরাহ করে। আপনি এই লিঙ্ক থেকে এটি ডাউনলোড করতে পারেন:

জেএসআর 354: অর্থ এবং মুদ্রার এপিআই ডাউনলোড করুন

স্পেসিফিকেশন নিম্নলিখিত জিনিস নিয়ে গঠিত:

  1. হ্যান্ডলিংয়ের জন্য একটি API যেমন আর্থিক পরিমাণ এবং মুদ্রা
  2. বিনিময়যোগ্য প্রয়োগগুলি সমর্থন করার জন্য API গুলি
  3. বাস্তবায়ন ক্লাসগুলির উদাহরণ তৈরির কারখানাগুলি
  4. গণনা, রূপান্তর এবং আর্থিক পরিমাণের বিন্যাসকরণের জন্য কার্যকারিতা
  5. মানি এবং মুদ্রার সাথে কাজ করার জন্য জাভা এপিআই, যা জাভা 9 এ অন্তর্ভুক্ত করার পরিকল্পনা করা হয়েছে।
  6. সমস্ত স্পেসিফিকেশন ক্লাস এবং ইন্টারফেস javax.money। * প্যাকেজে অবস্থিত।

জেএসআর 354 এর নমুনা উদাহরণ: অর্থ এবং মুদ্রার এপিআই:

মুদ্রাআমাউন্ট তৈরি করার এবং কনসোলে এটি মুদ্রণের উদাহরণটি দেখতে এরকম দেখাচ্ছে:

MonetaryAmountFactory<?> amountFactory = Monetary.getDefaultAmountFactory();
MonetaryAmount monetaryAmount = amountFactory.setCurrency(Monetary.getCurrency("EUR")).setNumber(12345.67).create();
MonetaryAmountFormat format = MonetaryFormats.getAmountFormat(Locale.getDefault());
System.out.println(format.format(monetaryAmount));

রেফারেন্স বাস্তবায়ন এপিআই ব্যবহার করার সময়, প্রয়োজনীয় কোডটি অনেক সহজ:

MonetaryAmount monetaryAmount = Money.of(12345.67, "EUR");
MonetaryAmountFormat format = MonetaryFormats.getAmountFormat(Locale.getDefault());
System.out.println(format.format(monetaryAmount));

এপিআই মনিটারিঅ্যামাউন্টস সহ গণনাগুলি সমর্থন করে:

MonetaryAmount monetaryAmount = Money.of(12345.67, "EUR");
MonetaryAmount otherMonetaryAmount = monetaryAmount.divide(2).add(Money.of(5, "EUR"));

কারেন্সিউইনিট এবং মুদ্রাঅ্যামাউন্ট

// getting CurrencyUnits by locale
CurrencyUnit yen = MonetaryCurrencies.getCurrency(Locale.JAPAN);
CurrencyUnit canadianDollar = MonetaryCurrencies.getCurrency(Locale.CANADA);

মানিটারাউন্টে বিভিন্ন পদ্ধতি রয়েছে যা নির্ধারিত মুদ্রা, সংখ্যার পরিমাণ, তার যথার্থতা এবং আরও অনেক কিছু অ্যাক্সেসের অনুমতি দেয়:

MonetaryAmount monetaryAmount = Money.of(123.45, euro);
CurrencyUnit currency = monetaryAmount.getCurrency();
NumberValue numberValue = monetaryAmount.getNumber();

int intValue = numberValue.intValue(); // 123
double doubleValue = numberValue.doubleValue(); // 123.45
long fractionDenominator = numberValue.getAmountFractionDenominator(); // 100
long fractionNumerator = numberValue.getAmountFractionNumerator(); // 45
int precision = numberValue.getPrecision(); // 5

// NumberValue extends java.lang.Number. 
// So we assign numberValue to a variable of type Number
Number number = numberValue;

MonetaryAmounts একটি বৃত্তাকার অপারেটর ব্যবহার করে বৃত্তাকার করা যেতে পারে:

CurrencyUnit usd = MonetaryCurrencies.getCurrency("USD");
MonetaryAmount dollars = Money.of(12.34567, usd);
MonetaryOperator roundingOperator = MonetaryRoundings.getRounding(usd);
MonetaryAmount roundedDollars = dollars.with(roundingOperator); // USD 12.35

মানিএমাউন্টগুলির সংগ্রহের সাথে কাজ করার সময়, ফিল্টারিং, বাছাই এবং গোষ্ঠীকরণের জন্য কয়েকটি দুর্দান্ত ইউটিলিটি পদ্ধতি উপলব্ধ।

List<MonetaryAmount> amounts = new ArrayList<>();
amounts.add(Money.of(2, "EUR"));
amounts.add(Money.of(42, "USD"));
amounts.add(Money.of(7, "USD"));
amounts.add(Money.of(13.37, "JPY"));
amounts.add(Money.of(18, "USD"));

কাস্টম মানিঅ্যামাউন্ট ক্রিয়াকলাপ

// A monetary operator that returns 10% of the input MonetaryAmount
// Implemented using Java 8 Lambdas
MonetaryOperator tenPercentOperator = (MonetaryAmount amount) -> {
  BigDecimal baseAmount = amount.getNumber().numberValue(BigDecimal.class);
  BigDecimal tenPercent = baseAmount.multiply(new BigDecimal("0.1"));
  return Money.of(tenPercent, amount.getCurrency());
};

MonetaryAmount dollars = Money.of(12.34567, "USD");

// apply tenPercentOperator to MonetaryAmount
MonetaryAmount tenPercentDollars = dollars.with(tenPercentOperator); // USD 1.234567

সম্পদ:

জেএসআর 354 এর সাহায্যে জাভাতে অর্থ এবং মুদ্রা পরিচালনা করা

জাভা 9 অর্থ এবং মুদ্রার এপিআই (জেএসআর 354) সন্ধান করছেন

আরও দেখুন: জেএসআর 354 - মুদ্রা এবং অর্থ


এগুলি দুর্দান্ত, তবে উপরে যেমন ফেডেরিকো পরামর্শ দিয়েছেন, এটি বিগডিসিমাল :-) এর চেয়ে ধীর দেখায়) তবে কেবল 1 বছর পরে এটি পরীক্ষা দেব ...
কেনসাই

6

আপনার আর্থিক মূল্যবোধ উপস্থাপনের জন্য আপনার বিগডিসিমাল ব্যবহার করা উচিত t এটি আপনাকে বিভিন্ন ধরণের রাউন্ডিং মোডগুলি ব্যবহার করতে দেয় এবং আর্থিক অ্যাপ্লিকেশনগুলিতে প্রায়শই রাউন্ডিং মোড একটি কঠোর প্রয়োজন যা এমনকি আইন দ্বারা বাধ্যতামূলকও হতে পারে।



6

পারফরম্যান্সের দিক থেকে বিগডেসিমেলের বিপরীতে মনতা (জাভা মুদ্রা জেএসআর 354 বাস্তবায়ন) তুলনা করার জন্য আমি একটি মাইক্রোব্যাঙ্কমার্ক (জেএমএইচ) করেছি।

আশ্চর্যের বিষয়, বিগডিসিমাল পারফরম্যান্স মনিতার চেয়ে ভাল বলে মনে হচ্ছে। আমি নীচে নীচে কনফিগার ব্যবহার করেছি:

org.javamoney.moneta.Money.defaults.precision = 19 org.javamoney.moneta.Money.defaults.roundingMode = HALF_UP

package com.despegar.bookedia.money;

import org.javamoney.moneta.FastMoney;
import org.javamoney.moneta.Money;
import org.openjdk.jmh.annotations.*;

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.concurrent.TimeUnit;

@Measurement(batchSize = 5000, iterations = 10, time = 2, timeUnit =     TimeUnit.SECONDS)
@Warmup(iterations = 2)
@Threads(value = 1)
@Fork(value = 1)
@State(Scope.Benchmark)
@BenchmarkMode(Mode.Throughput)
public class BigDecimalBenchmark {

private static final Money MONEY_BASE = Money.of(1234567.3444, "EUR");
private static final Money MONEY_SUBSTRACT = Money.of(232323, "EUR");
private static final FastMoney FAST_MONEY_SUBSTRACT = FastMoney.of(232323, "EUR");
private static final FastMoney FAST_MONEY_BASE = FastMoney.of(1234567.3444, "EUR");
MathContext mc = new MathContext(10, RoundingMode.HALF_UP);

@Benchmark
public void bigdecimal_string() {
    new BigDecimal("1234567.3444").subtract(new BigDecimal("232323")).multiply(new BigDecimal("3.4"), mc).divide(new BigDecimal("5.456"), mc);
}

@Benchmark
public void bigdecimal_valueOf() {
    BigDecimal.valueOf(12345673444L, 4).subtract(BigDecimal.valueOf(232323L)).multiply(BigDecimal.valueOf(34, 1), mc).divide(BigDecimal.valueOf(5456, 3), mc);
}
@Benchmark
public void fastmoney() {
    FastMoney.of(1234567.3444, "EUR").subtract(FastMoney.of(232323, "EUR")).multiply(3.4).divide(5.456);
}

@Benchmark
public void money() {
    Money.of(1234567.3444, "EUR").subtract(Money.of(232323, "EUR")).multiply(3.4).divide(5.456);
}

@Benchmark
public void money_static(){
    MONEY_BASE.subtract(MONEY_SUBSTRACT).multiply(3.4).divide(5.456);
}

@Benchmark
public void fastmoney_static() {
    FAST_MONEY_BASE.subtract(FAST_MONEY_SUBSTRACT).multiply(3.4).divide(5.456);
    }
}

ফলাফল

Benchmark                                Mode  Cnt     Score    Error  Units
BigDecimalBenchmark.bigdecimal_string   thrpt   10   479.465 ± 26.821  ops/s
BigDecimalBenchmark.bigdecimal_valueOf  thrpt   10  1066.754 ± 40.997  ops/s
BigDecimalBenchmark.fastmoney           thrpt   10    83.917 ±  4.612  ops/s
BigDecimalBenchmark.fastmoney_static    thrpt   10   504.676 ± 21.642  ops/s
BigDecimalBenchmark.money               thrpt   10    59.897 ±  3.061  ops/s
BigDecimalBenchmark.money_static        thrpt   10   184.767 ±  7.017  ops/s

যদি আমি কিছু মিস করছি তবে দয়া করে আমাকে সংশোধন করতে দ্বিধা বোধ করবেন


আকর্ষণীয়, আমি জেডি কে 9
কেনসাই

4

সাধারণ ক্ষেত্রে (এক মুদ্রার জন্য) এটি যথেষ্ট Integer/ Long। সেন্টগুলিতে অর্থ (...) বা শততম / হাজারতম সেন্টে রাখুন (নির্দিষ্ট বিভাজকের সাথে আপনার যে কোনও নির্ভুলতা প্রয়োজন)


3

বিগডিসিমাল মুদ্রার জন্য ব্যবহারের জন্য সেরা ডেটা টাইপ।

মুদ্রার জন্য প্রচুর পরিমাণে ধারক রয়েছে তবে তারা সবাই বিগডিসিমালকে অন্তর্নিহিত ডেটা ধরণ হিসাবে ব্যবহার করে। আপনি বিগডিসিমেলের সাথে ভুল হবেন না, সম্ভবত বিগডিসিমাল ব্যবহার করুন ND_


2

আমি টিনি টাইপগুলি ব্যবহার করতে পছন্দ করি যা পূর্ববর্তী উত্তরগুলির পরামর্শ অনুসারে ডাবল, বিগডিসিমাল বা ইন্টি আঁটবে। (যথাযথ সমস্যাগুলি না কাটলে আমি দ্বিগুণ ব্যবহার করব)।

একটি ক্ষুদ্র প্রকার আপনাকে টাইপ সুরক্ষা দেয় যাতে আপনি অন্য ডাবলসের সাথে দ্বিগুণ অর্থ বিভ্রান্ত না করেন।


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