1. ভূমিকা

Go ডেসিমাল লাইব্রেরি হলো Go ভাষায় সাময়িক-পরিমাপন কর্ণসংখ্যা নিয়ন্ত্রণের জনক একটি শক্তিশালী সরঞ্জাম। এটা যোগ, বিয়োগ, গুণ, ভাগ সহ সংখ্যার বিপরিতা ক্ষুদ্রফলন বিবেচনা করে। উল্লিখিত এইরকম, এটি ডাটাবেস/SQL সিরিয়ালাইজেশান/ডিসিরিয়ালাইজেশান, এবং JSON/XML সিরিয়ালাইজেশান/ডিসিরিয়ালাইজেশান প্রদান করে।

2. ইনস্টলেশন

Go ডেসিমাল লাইব্রেরি ইনস্টল করতে আপনি নিম্নলিখিত কমান্ডটি ব্যবহার করতে পারেন:

go get github.com/shopspring/decimal

দয়া করে মন করুন যে ডেসিমাল লাইব্রেরিটি Go সংস্করণ >=1.7 প্রয়োজন।

3. মৌলিক ব্যবহার

Go প্রোগ্রামে ডেসিমাল লাইব্রেরি ব্যবহার করতে, "github.com/shopspring/decimal" প্যাকেজ ইম্পোর্ট করুন। নিচে মৌলিক ব্যবহার প্রদর্শন করার জন্য একটি সাধারণ উদাহরণ কোড দেওয়া হল:

package main

import (
	"fmt"
	"github.com/shopspring/decimal"
)

func main() {
	price, err := decimal.NewFromString("136.02")
	if err != nil {
		panic(err)
	}

	quantity := decimal.NewFromInt(3)

	fee, _ := decimal.NewFromString(".035")
	taxRate, _ := decimal.NewFromString(".08875")

	subtotal := price.Mul(quantity)
	preTax := subtotal.Mul(fee).Add(decimal.NewFromFloat(1))
	total := preTax.Mul(taxRate).Add(decimal.NewFromFloat(1))

	fmt.Println("Subtotal:", subtotal)                  // Subtotal: 408.06
	fmt.Println("Pre-tax:", preTax)                     // Pre-tax: 422.3421
	fmt.Println("Taxes:", total.Sub(preTax))            // Taxes: 37.482861375
	fmt.Println("Total:", total)                         // Total: 459.824961375
	fmt.Println("Tax rate:", total.Sub(preTax).Div(preTax)) // Tax rate: 0.08875
}

4. ডেসিমাল ভ্যারিয়েবল তৈরী করা

ডেসিমাল লাইব্রেরিটি ডেসিমাল ভ্যারিয়েবল তৈরী করার জন্য বিভিন্ন পদ্ধতি প্রদান করে। নিম্নলিখিতগুলি সমর্থিত API গুলি:

  • decimal.NewFromBigInt(value *big.Int, exp int32) Decimal
  • decimal.NewFromFloat(value float64) Decimal
  • decimal.NewFromFloat32(value float32) Decimal
  • decimal.NewFromFloatWithExponent(value float64, exp int32) Decimal
  • decimal.NewFromFormattedString(value string, replRegexp *regexp.Regexp) (Decimal, error)
  • decimal.NewFromInt(value int64) Decimal
  • decimal.NewFromInt32(value int32) Decimal
  • decimal.NewFromString(value string) (Decimal, error)
  • decimal.RequireFromString(value string) Decimal

5. গণিতিক কার্য

Go ডেসিমাল লাইব্রেরি ডেসিমাল ভ্যারিয়েবল সর্বনিম্ন গণিতিক কর্যার জন্য একাধিক গণিতিক ক্রিয়া প্রদান করে। এই কিছু সমর্থিত কার্যকে নিম্নলিখিত করা হয়:

  • Add(d2 Decimal) Decimal: দুটি ডেসিমাল মান যোগ করে এবং ফলাফলটি প্রদান করে।
  • Sub(d2 Decimal) Decimal: একটি ডেসিমাল মান থেকে অন্যান্যটি বিয়োগ করে এবং ফলাফলটি প্রদান করে।
  • Div(d2 Decimal) Decimal: একটি ডেসিমাল মান অন্য একটি ডেসিমাল মান দ্বারা ভাগ করে এবং ফলাফলটি প্রদান করে।
  • DivRound(d2 Decimal, precision int32) Decimal: একটি ডেসিমাল মান অন্য একটি ডেসিমাল মান দ্বারা ভাগ করে এবং নির্দিষ্ট নির্দিষ্ট এক্সপোনেন্ট দিয়ে ফলাফল প্রদান করে।
  • Mod(d2 Decimal) Decimal: একটি ডেসিমাল মান অন্য একটি ডেসিমাল মান দ্বারা ভাগ করে অবশিষ্ট (সাশ্রয়) গণনা করে এবং ফলাফলটি প্রদান করে।
  • Mul(d2 Decimal) Decimal: দুটি ডেসিমাল মান গুণ করে এবং ফলাফলটি প্রদান করে।

আপনি এই কার্যগুলি ব্যবহার করে ডেসিমাল মানগুলির উপর সাধারণ গণিতিক গণনা করতে পারেন। নিচের উদাহরণে এই কার্যগুলির ব্যবহার দেখানো হয়:

price, _ := decimal.NewFromString("136.02")
quantity := decimal.NewFromInt(3)

subtotal := price.Mul(quantity)
tax := subtotal.Mul(decimal.NewFromFloat(0.08875))

total := subtotal.Add(tax)

fmt.Println("Subtotal:", subtotal) // Subtotal: 408.06
fmt.Println("Tax:", tax)           // Tax: 36.244985
fmt.Println("Total:", total)       // Total: 444.304985

উপরের উদাহরণে, আমরা Mul() মেথডটি ব্যবহার করে price এবং quantity ধনাত্মক গণনা করে subtotal গণনা করি। তারপরে আমরা subtotal এর সাথে কর হার্য করে tax গণনা করি। শেষে, আমরা subtotal এবং tax যোগ করে total গণনা করি।

6. ঘর পরিষ্কার অপারেশন

Go Decimal লাইব্রেরি বিভিন্ন ঘটক পরিষ্কার অপারেশন সরবরাহ করে যা ব্যবহৃত হতে পারে যেহেতু নির্দিষ্ট নির্দিষ্ট প্রেসিশনে ডেসিমাল মানের পরিষ্কার করতে। এখানে কিছু উপলব্ধ পরিষ্কার অপারেশন দেওয়া হল:

  • Round(places int32) Decimal: এখানে প্রদত্ত ডেসিমাল মানটি নির্দিষ্ট সংখ্যক দশমিক স্থানে পরিষ্কার করে।
  • RoundBank(places int32) Decimal: ব্যাঙ্কারের পরিষ্কার ব্যবহার করে প্রদত্ত সংখ্যক দশমিক স্থানে পরিষ্কার করে।
  • RoundCash(interval uint8) Decimal: নির্দিষ্ট অন্তরালে পরিষ্কার করে, উদাহরণস্বরূপ 5 সেন্ট, 10 সেন্ট, 25 সেন্ট, 50 সেন্ট বা 1 ডলার।
  • RoundCeil(places int32) Decimal: ডেসিমালকে ধনাত্মক অমিনিকে পরিষ্কার করে।
  • RoundDown(places int32) Decimal: ডেসিমালকে শূন্যের দিকে পরিষ্কার করে।
  • RoundFloor(places int32) Decimal: ডেসিমালকে নেতিবাচক অমিনিকে পরিষ্কার করে।
  • RoundUp(places int32) Decimal: ডেসিমালকে শূন্য থেকে দূরে পরিষ্কার করে।

6.1. পরিসূচিত করা হচ্ছে

Round ডেসিমালকে নির্দিষ্ট সংখ্যক দশমিক স্থানে পরিষ্কার করে। যদি places < 0 হয়, তবে উপাদানটির প্রান্ত অংশটি নিকটতম 10^(-places) এর দিকে পরিষ্কার হবে।

NewFromFloat(5.45).Round(1).String() // আউটপুট: "5.5"
NewFromFloat(545).Round(-1).String() // আউটপুট: "550"

6.2. RoundBank

RoundBank প্রদত্ত places সংখ্যক দশমিক স্থানে পরিষ্কার করে। যদি পরিষ্কার করার সময় পর্যাপ্ত দূরত্ব দুটি পূর্ণসংখ্যা মাঝের মধ্যে সমান হয়, তাহলে পরিষ্কার মানটি জোড় সংখ্যা গ্রহণ করবে।

যদি places < 0 হয়, তবে পূর্ণাংশটির প্রান্ত অংশটি নিকটতম 10^(-places) এর দিকে পরিষ্কার হবে।

NewFromFloat(5.45).RoundBank(1).String() // আউটপুট: "5.4"
NewFromFloat(545).RoundBank(-1).String() // আউটপুট: "540"
NewFromFloat(5.46).RoundBank(1).String() // আউটপুট: "5.5"
NewFromFloat(546).RoundBank(-1).String() // আউটপুট: "550"
NewFromFloat(5.55).RoundBank(1).String() // আউটপুট: "5.6"
NewFromFloat(555).RoundBank(-1).String() // আউটপুট: "560"

6.3. পুরস্কার নগদ

RoundCash (অথবা ক্যাশ/পেনি/আইরিশ পরিষ্কার) পরিষ্কার করে নির্দিষ্ট ইন্টারভালে। নগদ লেনদেনের পরিশোধযোগ্য পরিমাণটি সর্বনিকেত মুদ্রা এককের নিকটতম গুণকের নিকটতম হতে পরিষ্কার করা হবে। উপলব্ধ ইন্টারভালগুলি হল: 5, 10, 25, 50 এবং 100; অন্য কোনও সংখ্যা অসম্ভব হবে।

  5:   5 সেন্ট পরিষ্কার 3.43 => 3.45
 10:  10 সেন্ট পরিষ্কার 3.45 => 3.50 (5 পরিষ্কার করা হয়েছে)
 25:  25 সেন্ট পরিষ্কার 3.41 => 3.50
 50:  50 সেন্ট পরিষ্কার 3.75 => 4.00
100: 100 সেন্ট পরিষ্কার 3.50 => 4.00

6.4. পরির্খণ করা হয়েছে

RoundCeil ডেসিমালকে ধনাত্মক অমিনিকে পরিষ্কার করে।

NewFromFloat(545).RoundCeil(-2).String()   // আউটপুট: "600"
NewFromFloat(500).RoundCeil(-2).String()   // আউটপুট: "500"
NewFromFloat(1.1001).RoundCeil(2).String() // আউটপুট: "1.11"
NewFromFloat(-1.454).RoundCeil(1).String() // আউটপুট: "-1.5"

6.5. RoundDown

RoundDown ডেসিমালকে শূন্যের দিকে পরিষ্কার করে।

NewFromFloat(545).RoundDown(-2).String()   // আউটপুট: "500"
NewFromFloat(-500).RoundDown(-2).String()   // আউটপুট: "-500"
NewFromFloat(1.1001).RoundDown(2).String() // আউটপুট: "1.1"
NewFromFloat(-1.454).RoundDown(1).String() // আউটপুট: "-1.5"

6.6. রাউন্ডফ্লোর

রাউন্ডফ্লোর দশমিককে নেগেটিভ ইনফিনিটি দিকে রাউন্ড করে।

NewFromFloat(545).RoundFloor(-2).String()   // আউটপুট: "500"
NewFromFloat(-500).RoundFloor(-2).String()   // আউটপুট: "-500"
NewFromFloat(1.1001).RoundFloor(2).String() // আউটপুট: "1.1"
NewFromFloat(-1.454).RoundFloor(1).String() // আউটপুট: "-1.4"

6.7. রাউন্ডআপ

রাউন্ডআপ দশমিককে জিরো দিকে রাউন্ড করে।

NewFromFloat(545).RoundUp(-2).String()   // আউটপুট: "600"
NewFromFloat(500).RoundUp(-2).String()   // আউটপুট: "500"
NewFromFloat(1.1001).RoundUp(2).String() // আউটপুট: "1.11"
NewFromFloat(-1.454).RoundUp(1).String() // আউটপুট: "-1.4"

7. ডেসিমাল টাইপকে স্ট্রিংএ কনভার্ট করা

গো ডেসিমাল লাইব্রেরি ডেসিমাল মানগুলিকে স্ট্রিং প্রতিনিধিত্বে কনভাট করার মেথড প্রদান করে। এখানে কিছু উপলব্ধ মেথড দেওয়া হলো:

  • String(): string: একটি নির্দিষ্ট দশমিক পয়েন্ট সহ ডেসিমাল সংখ্যার স্ট্রিং প্রতিনিধিত্ব ফেরত দেয়।
  • StringFixed(places int32) string: নির্দিষ্ট সংখ্যক দশমিক স্থান দিয়ে সংক্ষিপ্ত স্ট্রিং প্রতিনিধিত্ব ফেরত দেয়।
  • StringFixedBank(places int32) string: নির্দিষ্ট সংখ্যক দশমিক স্থান দিয়ে সংক্ষেপিত (ব্যাংকারের রাউন্ডিং) স্ট্রিং প্রতিনিধিত্ব ফেরত দেয়।

আপনি আপনার প্রয়োজনীয়তার অনুযায়ী উপযোগী মেথড চয়ন করতে পারেন। নিচে একটি উদাহরণ দেয়া হলো যেখানে ডেসিমাল সংখ্যাকে স্ট্রিং এ কনভার্ট করা হয়েছে:

d := decimal.NewFromFloat(5.45)
str := d.String()

fmt.Println("ডেসিমাল সংখ্যার স্ট্রিং প্রতিনিধিত্ব:", str) // ডেসিমাল সংখ্যার স্ট্রিং প্রতিনিধিত্ব: 5.45

// StringFixed উদাহরণ
NewFromFloat(0).StringFixed(2) // আউটপুট: "0.00"
NewFromFloat(0).StringFixed(0) // আউটপুট: "0"
NewFromFloat(5.45).StringFixed(0) // আউটপুট: "5"
NewFromFloat(5.45).StringFixed(1) // আউটপুট: "5.5"
NewFromFloat(5.45).StringFixed(2) // আউটপুট: "5.45"
NewFromFloat(5.45).StringFixed(3) // আউটপুট: "5.450"
NewFromFloat(545).StringFixed(-1) // আউটপুট: "550"

// StringFixedBank উদাহরণ
NewFromFloat(0).StringFixedBank(2) // আউটপুট: "0.00"
NewFromFloat(0).StringFixedBank(0) // আউটপুট: "0"
NewFromFloat(5.45).StringFixedBank(0) // আউটপুট: "5"
NewFromFloat(5.45).StringFixedBank(1) // আউটপুট: "5.4"
NewFromFloat(5.45).StringFixedBank(2) // আউটপুট: "5.45"
NewFromFloat(5.45).StringFixedBank(3) // আউটপুট: "5.450"
NewFromFloat(545).StringFixedBank(-1) // আউটপুট: "540"

8. সাধারণ প্রশ্ন

প্রশ্ন: কেন প্রত্যক্ষভাবে float64 ব্যবহার করা হয় না? উত্তর: float64 সঠিকভাবে 0.1 সহ সংখ্যা প্রতিনিধিত্ব প্রদর্শন করতে পারে না, যা ছোট ভুল সৃষ্টি করতে পারে। আর্থিক গণনায় অংশগত ভুল সম্পর্কিত পরিস্থিতিতে, এই ভুলগুলি সময়ের মধ্যে সংকুচিত হতে পারে এবং গুরুত্বপূর্ণ সমস্যা সৃষ্টি করতে পারে।

প্রশ্ন: কেন big.Rat প্রত্যক্ষভাবে ব্যবহার করা হয় না? উত্তর: সকল ধরণের ভঙ্গিত সংখ্যা প্রতিনিধিত্ব করার জন্য big.Rat প্রত্যক্ষভাবে সঠিক নয়, এটি মুদ্রার প্রতিনিধিত্ব প্রদর্শনের জন্য উপযোগী নয়। ডেসিমাল সংখ্যা আর্থিক গণনাতে বেশি উপযোগী কারন পরিস্থিতিকে সঠিকভাবে প্রতিনিধিত্ব প্রদর্শন করতে পারে।

প্রশ্ন: কেন ডেসিমাল লাইব্রেরির এপিআই big.Int এর মতো না? উত্তর: ডেসিমাল লাইব্রেরির এপিআই ব্যবহারযোগ্যতা এবং সঠিকতা এবং কার্যকারিতা উপর প্রাধান্য দেয়। big.Int এর এপিআই মৌখিক অনুসন্ধানের জন্য মেমোরি আবারন কমাতে হয়, তবে এটি জটিল এবং ভুল উদ্বোধন করতে পারে। ডেসিমাল লাইব্রেরির এপিআইটি সহজ এবং সম্মতি মেলায় ডিজাইন করা হয়েছে।