package slownie import ( "errors" "fmt" "math" "strings" ) var _smallNumbers = []string{ "zero", "jeden", "dwa", "trzy", "cztery", "pięć", "sześć", "siedem", "osiem", "dziewięć", "dziesięć", "jedenaście", "dwanaście", "trzynaście", "czternaście", "piętnaście", "szesnaście", "siedemnaście", "osiemnaście", "dziewiętnaście"} var _tens = []string{ "", "", "dwadzieścia", "trzydzieści", "czterdzieści", "pięćdziesiąt", "sześćdziesiąt", "siedemdziesiąt", "osiemdziesiąt", "dziewięćdziesiąt"} var _hundrets = []string{ "", "sto", "dwieście", "trzysta", "czterysta", "pięćset", "sześćset", "siedemset", "osiemset", "dziewięćset"} var _bigones = [][]string{ {"", "", ""}, {"tysiąc", "tysiące", "tysięcy"}, {"milion", "miliony", "milionów"}, {"miliard", "miliardy", "miliardów"}, {"bilion", "biliony", "bilionów"}, } var _zlotyWord = []string{"złoty", "złote", "złotych"} var _groszyWord = []string{"grosz", "grosze", "groszy"} func round(num float64) int { return int(num + math.Copysign(0.5, num)) } func toFixed(num float64, precision int) float64 { output := math.Pow(10, float64(precision)) return float64(round(num*output)) / output } func split(value float64) (int64, int64) { pre := int64(value) // post := int32((value - float64(pre)) * 100) post := int64((round(value*100) % 100)) return pre, post } func caseWord(value int) int32 { single := value % 10 tens := (value / 10) % 10 var caseWord int32 if value == 1 { caseWord = 0 } else if tens == 1 && single > 1 { caseWord = 2 } else if 2 <= single && single <= 4 { caseWord = 1 } else { caseWord = 2 } return caseWord } func threeNumberWord(value int32) string { single := value % 10 tens := (value / 10) % 10 hundrets := (value / 100) % 10 var words []string if hundrets > 0 { words = append(words, _hundrets[hundrets]) } if tens == 1 { words = append(words, _smallNumbers[single+10]) } else { if tens > 0 { words = append(words, _tens[tens]) } if single > 0 { words = append(words, _smallNumbers[single]) } } return strings.Join(words, " ") } func slownie(value int64) string { var threePairs []int32 if value == 0 { return "zero" } for value > 0 { threePairs = append(threePairs, int32(value%1000)) value = value / 1000 } var words []string for i, n := range threePairs { if n > 0 { if i > 0 { words = append(words, threeNumberWord(n)+" "+_bigones[i][caseWord(int(n))]) } else { words = append(words, threeNumberWord(n)) } } } //reverse for i := len(words)/2 - 1; i >= 0; i-- { opp := len(words) - 1 - i words[i], words[opp] = words[opp], words[i] } return strings.Join(words, " ") } func someSlownie(value int64, some []string) string { return slownie(value) + " " + some[caseWord(int(value))] } // KwotaSlownie - return value in words of zloty and groszy func KwotaSlownie(input float64, numbers bool) (output string, err error) { input = toFixed(input, 2) defer func() { if r := recover(); r != nil { err = errors.New("too big number") } }() var minusword = "" if input < 0 { minusword = "minus " input = -input } zloty, grosze := split(input) if numbers { return minusword + someSlownie(zloty, _zlotyWord) + fmt.Sprintf(" %02d/100", grosze), nil } return minusword + someSlownie(zloty, _zlotyWord) + " " + someSlownie(grosze, _groszyWord), nil }