Tarkibga o'tish

Go’da matematik hisob-kitoblar

Oldingi darslarda sonlar, operatorlar va konsoldan qiymat kiritishni o‘rgandik. Qo‘shish, ayirish, ko‘paytirish va bo‘lish kabi oddiy amallar operatorlar bilan bajariladi. Kvadrat ildiz, daraja, sinus yoki yaxlitlash kabi hisoblar uchun esa Go standart kutubxonasidagi math paketi ishlatiladi.

Bu darsda math paketini ulash, uning funksiyalaridan foydalanish va natijani kerakli ko‘rinishda chiqarishni ko‘rib chiqamiz.

Paket va modul farqi

Paket (package) — odatda bitta katalogda joylashgan, bir vazifaga tegishli Go fayllari to‘plami. Paket kodni qismlarga ajratish va tayyor imkoniyatlardan qayta foydalanishga yordam beradi. fmt va math — Go standart kutubxonasidagi paketlar.

Modul (module) esa birgalikda versiyalanadigan bir yoki bir nechta paketlar to‘plami. Modul odatda go.mod fayli bilan aniqlanadi. Hozir biz modul yaratmaymiz, standart kutubxonadagi math paketini import qilamiz. Modullar keyingi alohida darsda batafsil tushuntiriladi.

math paketini import qilish

Paketdagi nomlardan foydalanish uchun uni import qilish kerak:

1
2
3
4
5
6
7
package main

import "math"

func main() {
    _ = math.Pi
}

Go import qilingan har bir paket ishlatilishini talab qiladi. Agar mathni import qilib, undan hech qayerda foydalanmasak, kompilyator "math" imported and not used mazmunidagi xato qaytaradi.

Yuqoridagi _ = math.Pi qatori math.Pi qiymatini bo‘sh identifikatorga beradi. U faqat paket ishlatilganini ko‘rsatish uchun yozildi. Amaliy dasturda math funksiyasi yoki o‘zgarmasidan bevosita foydalanamiz.

math.Pi o‘zgarmasi

math paketida π sonining tayyor qiymati bor:

main.go
package main

import (
    "fmt"
    "math"
)

func main() {
    fmt.Println(math.Pi)
}

Natija:

3.141592653589793

math.Pi yozuvida nuqta Pi nomi math paketiga tegishli ekanini bildiradi. Boshqa paketdan foydalanish mumkin bo‘lgan, katta harf bilan boshlanuvchi nom eksport qilingan nom deyiladi. Masalan, math.Pi, math.Sqrt() va fmt.Println() eksport qilingan nomlar.

math.Pi — o‘zgarmas qiymat. Uni chaqirmaymiz, shu sababli qavs yozilmaydi. math.Sqrt() esa funksiya, unga argument berish uchun qavs ishlatiladi.

Natijadagi kasr xonalarini boshqarish

fmt.Println() math.Pining mavjud raqamlarini chiqaradi. Faqat ikki kasr xonasi kerak bo‘lsa, fmt.Printf() va %.2f formatidan foydalanamiz:

main.go
package main

import (
    "fmt"
    "math"
)

func main() {
    fmt.Printf("Pi: %.2f\n", math.Pi)
}

Natija:

Pi: 3.14

%.2f kasrli sonni verguldan keyin ikki xona bilan ko‘rsatadi. %.3f uch xona, %.4f esa to‘rt xona chiqaradi. Bu faqat ekrandagi ko‘rinishni o‘zgartiradi; math.Pining asl qiymati qisqarmaydi.

Bir nechta paketni import qilish

Bir nechta paket alohida import qilinishi mumkin:

import "fmt"
import "math"

Go kodida odatda ular bitta import blokida yoziladi:

import (
    "fmt"
    "math"
)

gofmt importlar va koddagi chekinishlarni standart ko‘rinishga keltiradi.

Ko‘p ishlatiladigan matematik funksiyalar

math paketidagi funksiyalarning aksariyati float64 qiymat qabul qiladi va float64 qaytaradi.

Funksiya yoki o‘zgarmas Vazifasi
math.Abs(x) xning modulini, ya’ni manfiy bo‘lmagan qiymatini qaytaradi
math.Sqrt(x) xning kvadrat ildizini hisoblaydi
math.Cbrt(x) xning kub ildizini hisoblaydi
math.Pow(x, y) xni y darajaga oshiradi
math.Pow10(n) 10 ning n-darajasini hisoblaydi
math.Min(x, y) ikki sondan kichigini qaytaradi
math.Max(x, y) ikki sondan kattasini qaytaradi
math.Mod(x, y) kasrli sonlar uchun bo‘lish qoldig‘ini hisoblaydi
math.Floor(x) eng yaqin kichik butun qiymat tomonga yaxlitlaydi
math.Ceil(x) eng yaqin katta butun qiymat tomonga yaxlitlaydi
math.Round(x) eng yaqin butun qiymatga yaxlitlaydi
math.Sin(x) radian bilan berilgan xning sinusini hisoblaydi
math.Cos(x) radian bilan berilgan xning kosinusini hisoblaydi
math.Tan(x) radian bilan berilgan xning tangensini hisoblaydi
math.Asin(x) xning arksinusini radianlarda qaytaradi
math.Acos(x) xning arkkosinusini radianlarda qaytaradi
math.Atan(x) xning arktangensini radianlarda qaytaradi
math.Exp(x) e sonini x darajaga oshiradi
math.Log(x) xning natural logarifmini hisoblaydi
math.Log10(x) xning 10 asosli logarifmini hisoblaydi
math.Hypot(x, y) katetlari x va y bo‘lgan uchburchak gipotenuzasini hisoblaydi
math.Pi π matematik o‘zgarmasi
math.E e matematik o‘zgarmasi

Funksiya nomlari katta harf bilan boshlanishiga e’tibor bering. Go katta-kichik harflarni farqlaydi: math.E mavjud, math.e esa mavjud emas.

Modul, ildiz va daraja

Quyidagi dastur bir nechta asosiy funksiyani ko‘rsatadi:

main.go
package main

import (
    "fmt"
    "math"
)

func main() {
    son := -12.5

    fmt.Println("Modul:", math.Abs(son))
    fmt.Println("81 ning kvadrat ildizi:", math.Sqrt(81))
    fmt.Println("27 ning kub ildizi:", math.Cbrt(27))
    fmt.Println("2 ning 5-darajasi:", math.Pow(2, 5))
    fmt.Println("10 ning 3-darajasi:", math.Pow10(3))
}

Natija:

Modul: 12.5
81 ning kvadrat ildizi: 9
27 ning kub ildizi: 3
2 ning 5-darajasi: 32
10 ning 3-darajasi: 1000

math.Pow(2, 5) yozuvida 2 — asos, 5 — daraja. Ikkala argument ham hisoblash vaqtida float64 sifatida ishlatiladi.

Aylana yuzini hisoblash

Aylana yuzi S = πr² formula bilan hisoblanadi. Radiusni foydalanuvchidan olib, math.Pi va math.Pow() bilan hisoblaymiz:

main.go
package main

import (
    "fmt"
    "math"
)

func main() {
    var radius float64

    fmt.Print("Aylana radiusini kiriting: ")
    _, err := fmt.Scan(&radius)
    if err != nil {
        fmt.Println("Xato: radius son bo‘lishi kerak.")
        return
    }

    if radius < 0 {
        fmt.Println("Xato: radius manfiy bo‘lishi mumkin emas.")
        return
    }

    yuza := math.Pi * math.Pow(radius, 2)
    fmt.Printf("Aylana yuzi: %.2f\n", yuza)
}

radius uchun 5 kiritilsa, natija quyidagicha bo‘ladi:

Aylana radiusini kiriting: 5
Aylana yuzi: 78.54

Kvadratni radius * radius deb hisoblash ham mumkin. math.Pow() ixtiyoriy darajalar bilan ishlaganda foydali.

Gipotenuzani hisoblash

Pifagor teoremasiga ko‘ra, katetlari a va b bo‘lgan to‘g‘ri burchakli uchburchakning gipotenuzasi √(a²+b²)ga teng.

main.go
package main

import (
    "fmt"
    "math"
)

func main() {
    a := 3.0
    b := 4.0

    oddiyUsul := math.Sqrt(a*a + b*b)
    hypotBilan := math.Hypot(a, b)

    fmt.Println("Sqrt bilan:", oddiyUsul)
    fmt.Println("Hypot bilan:", hypotBilan)
}

Natija:

Sqrt bilan: 5
Hypot bilan: 5

math.Hypot() aynan shu hisob uchun tayyorlangan. U juda katta yoki juda kichik sonlarda oddiy formulaga qaraganda barqarorroq hisoblaydi.

Sonlarni yaxlitlash

Floor, Ceil va Round funksiyalari o‘xshash ko‘rinsa ham, turli yo‘nalishda yaxlitlaydi:

main.go
package main

import (
    "fmt"
    "math"
)

func main() {
    son := 3.7

    fmt.Println("Floor:", math.Floor(son))
    fmt.Println("Ceil:", math.Ceil(son))
    fmt.Println("Round:", math.Round(son))
}

Natija:

Floor: 3
Ceil: 4
Round: 4
  • math.Floor(3.7) pastga qarab 3ga tushiradi;
  • math.Ceil(3.7) yuqoriga qarab 4ga ko‘taradi;
  • math.Round(3.7) eng yaqin butun qiymat — 4ni qaytaradi.

Bu funksiyalar float64 qaytaradi. Natija ekranda 3 ko‘rinsa ham, uning turi float64:

yaxlit := math.Floor(3.7)
fmt.Printf("Qiymat: %v, tur: %T\n", yaxlit, yaxlit)

Manfiy sonlarda yo‘nalishni unutmaslik kerak. math.Floor(-3.2) natijasi -4, math.Ceil(-3.2) natijasi esa -3.

Ma’lum kasr xonasigacha yaxlitlash

Sonni ikki kasr xonasigacha matematik yaxlitlash uchun avval 100ga ko‘paytirib, yaxlitlab, keyin 100ga bo‘lish mumkin:

main.go
package main

import (
    "fmt"
    "math"
)

func main() {
    son := 12.3456
    yaxlit := math.Round(son*100) / 100

    fmt.Println(yaxlit)
}

Natija 12.35 bo‘ladi. Bu usul qiymatning o‘zini yaxlitlaydi. fmt.Printf("%.2f", son) esa faqat chiqarilayotgan ko‘rinishni ikki xonaga keltiradi.

Warning

float64 ayrim o‘nli kasrlarni mutlaqo aniq saqlamaydi. Moliyaviy hisoblarda oddiy float64 yaxlitlash har doim yetarli bo‘lmasligi mumkin. Pulni eng kichik birlikda butun son sifatida saqlash yoki maxsus decimal yechimidan foydalanish kerak.

Eng kichik va eng katta qiymat

math.Min() va math.Max() ikkita float64 qiymatdan birini tanlaydi:

main.go
package main

import (
    "fmt"
    "math"
)

func main() {
    birinchi := 17.5
    ikkinchi := 12.8

    fmt.Println("Kichigi:", math.Min(birinchi, ikkinchi))
    fmt.Println("Kattasi:", math.Max(birinchi, ikkinchi))
}

Natija:

Kichigi: 12.8
Kattasi: 17.5

Oddiy int qiymatlar bilan ishlaganda ularni float64ga aylantirish kerak bo‘ladi. Go’ning zamonaviy standart kutubxonasida butun sonlar uchun min() va max() ichki funksiyalari ham mavjud, ammo bu darsda math paketidagi variantlarni o‘rganamiz.

Daraja va radian

math.Sin(), math.Cos() va math.Tan() burchakni darajada emas, radianda qabul qiladi. Darajani radianga aylantirish formulasi:

radian = daraja × π / 180
main.go
package main

import (
    "fmt"
    "math"
)

func main() {
    daraja := 30.0
    radian := daraja * math.Pi / 180

    fmt.Printf("sin(30°) = %.2f\n", math.Sin(radian))
    fmt.Printf("cos(30°) = %.2f\n", math.Cos(radian))
}

Natija:

sin(30°) = 0.50
cos(30°) = 0.87

math.Sin(30) deb yozish 30 darajani emas, 30 radianni hisoblaydi. Bu trigonometrik funksiyalarda keng uchraydigan xato.

Teskari trigonometrik funksiyalar

math.Asin() va math.Acos() argumenti -1 dan 1 gacha bo‘lishi kerak. Ularning natijasi radianda qaytadi. Natijani darajaga o‘tkazish uchun 180 / math.Piga ko‘paytiramiz:

main.go
package main

import (
    "fmt"
    "math"
)

func main() {
    qiymat := 0.5
    radian := math.Asin(qiymat)
    daraja := radian * 180 / math.Pi

    fmt.Printf("asin(%.1f) = %.0f°\n", qiymat, daraja)
}

Natija:

asin(0.5) = 30°

math.Asin(2.5) yoki math.Acos(2.5) kabi oraliqdan tashqaridagi argument haqiqiy natijaga ega emas. Go bunday holatda NaN qiymatini qaytaradi.

Logarifm va eksponenta

math.Exp(x) e sonining x-darajasini, math.Log(x) esa natural logarifmni hisoblaydi. Ular bir-biriga teskari amallar:

main.go
package main

import (
    "fmt"
    "math"
)

func main() {
    x := 2.0
    eDaraja := math.Exp(x)

    fmt.Printf("e^%.0f = %.4f\n", x, eDaraja)
    fmt.Printf("log(%.4f) = %.4f\n", eDaraja, math.Log(eDaraja))
    fmt.Println("10 asosli logarifm:", math.Log10(1000))
}

math.Log(x) uchun x musbat bo‘lishi kerak. math.Log(0) manfiy cheksizlik, manfiy argument esa NaN qaytaradi.

NaN va cheksizlik

Ayrim matematik amallarning haqiqiy sonlarda javobi yo‘q. math.Sqrt(-1) bunga misol. math paketi bunday holatda ko‘pincha NaN — “son emas” (Not a Number) qiymatini qaytaradi:

main.go
package main

import (
    "fmt"
    "math"
)

func main() {
    natija := math.Sqrt(-1)

    fmt.Println(natija)
    fmt.Println("NaN qiymatmi?", math.IsNaN(natija))
}

Natija:

NaN
NaN qiymatmi? true

math.IsNaN() qiymat NaN ekanini tekshiradi. Cheksiz qiymatni math.IsInf() bilan tekshirish mumkin. Amaliy dasturda funksiyaga beriladigan argument ruxsat etilgan oraliqda ekanini hisoblashdan oldin tekshirish yaxshiroq.

Funksiyalarni bir dasturda ko‘rish

Quyidagi misol yuqoridagi funksiyalarning ko‘pini bir joyda ko‘rsatadi. Teskari trigonometrik funksiyalar uchun alohida trigQiymat ishlatilgan, chunki Asin() va Acos() faqat [-1, 1] oralig‘ini qabul qiladi:

main.go
package main

import (
    "fmt"
    "math"
)

func main() {
    x := 2.5
    y := 3.0
    trigQiymat := 0.5

    fmt.Printf("math.Abs(-%v) = %v\n", x, math.Abs(-x))
    fmt.Printf("math.Sin(%v) = %.4f\n", x, math.Sin(x))
    fmt.Printf("math.Cos(%v) = %.4f\n", x, math.Cos(x))
    fmt.Printf("math.Tan(%v) = %.4f\n", x, math.Tan(x))
    fmt.Printf("math.Asin(%v) = %.4f\n", trigQiymat, math.Asin(trigQiymat))
    fmt.Printf("math.Acos(%v) = %.4f\n", trigQiymat, math.Acos(trigQiymat))
    fmt.Printf("math.Atan(%v) = %.4f\n", x, math.Atan(x))
    fmt.Printf("math.Exp(%v) = %.4f\n", x, math.Exp(x))
    fmt.Printf("math.Log(%v) = %.4f\n", x, math.Log(x))
    fmt.Printf("math.Pow(%v, %v) = %.4f\n", x, y, math.Pow(x, y))
    fmt.Printf("math.Pow10(3) = %.4f\n", math.Pow10(3))
    fmt.Printf("math.Sqrt(%v) = %.4f\n", x, math.Sqrt(x))
    fmt.Printf("math.Floor(%v) = %.4f\n", x, math.Floor(x))
    fmt.Printf("math.Ceil(%v) = %.4f\n", x, math.Ceil(x))
    fmt.Printf("math.Round(%v) = %.4f\n", x, math.Round(x))
    fmt.Printf("math.Pi = %.4f\n", math.Pi)
    fmt.Printf("math.E = %.4f\n", math.E)
    fmt.Printf("math.Min(%v, %v) = %.4f\n", x, y, math.Min(x, y))
    fmt.Printf("math.Max(%v, %v) = %.4f\n", x, y, math.Max(x, y))
    fmt.Printf("math.Mod(%v, %v) = %.4f\n", x, y, math.Mod(x, y))
}

Bu misolda argumentlar funksiya talab qiladigan oraliqqa mos tanlangan. Natijadagi raqamlar %.4f yordamida to‘rt kasr xonasi bilan chiqariladi.

Xulosa

math Go standart kutubxonasidagi matematik paket. Unda π va e o‘zgarmaslari, ildiz, daraja, yaxlitlash, trigonometrik va logarifmik hisoblar uchun tayyor funksiyalar bor. Funksiyalarning aksariyati float64 bilan ishlaydi. Trigonometrik funksiyalar burchakni radianda qabul qiladi, ayrim funksiyalar esa argument uchun ma’lum oraliq talab qiladi.

Keyingi darsda hisob natijasiga qarab turli kod qismlarini bajarish uchun if, else if va else shartlaridan foydalanamiz.