Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 42 additions & 1 deletion num2words.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,47 @@ var (
}
)

// ConvertDecimal converts decimal number into the words representation
// reference: https://www.jawapos.com/opini/28/04/2019/membaca-desimal/
func ConvertDecimal(number float64, precision int) (string, error) {
if precision < 1 {
return Convert(int64(number))
}

format := "%." + fmt.Sprintf("%d", precision) + "f"
fractions := fmt.Sprintf(format, number)
fractions = strings.Split(fractions, ".")[1]

words := ""
for precision > 0 {
v := fractions[precision-1] - 48
if v > 0 {
break
}
precision--
}

fractions = fractions[:precision]

for i := 1; i <= precision; i++ {
v := fractions[precision-i] - 48
words = smallNumbers[v] + " " + words
}

if words == "" {
return Convert(int64(number))
}

words = words[:len(words)-1]

numString, err := Convert(int64(number))
if err != nil {
return "", err
}

return numString + " koma " + words, nil
}

// Convert converts number into the words representation
func Convert(number int64) (string, error) {

Expand Down Expand Up @@ -63,7 +104,7 @@ func Convert(number int64) (string, error) {
func splitIntoThreeDigitGroups(number int64) []uint16 {
var digitGroups []uint16
for i := 0; i < len(scales); i++ {
digitGroups = append(digitGroups,uint16(number % 1000))
digitGroups = append(digitGroups, uint16(number%1000))
number = number / 1000
}
return digitGroups
Expand Down
41 changes: 40 additions & 1 deletion num2words_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ func TestConvert(t *testing.T) {
assert.Equal(t, tt.Words, w)
})
}

}

func TestConvertMinus(t *testing.T) {
Expand All @@ -132,4 +131,44 @@ func TestConvertError(t *testing.T) {
w, err := Convert(1000000000000000)
assert.NotNil(t, err)
assert.Equal(t, "", w)

w, err = ConvertDecimal(1000000000000000.1, 1)
assert.NotNil(t, err)
assert.Equal(t, "", w)
}

var fractionTest = []struct {
Number float64
Precision int
Words string
}{
{0.1, 1, "nol koma satu"},
{5.1, 1, "lima koma satu"},
{155.25, 1, "seratus lima puluh lima koma dua"},
{0.25, 2, "nol koma dua lima"},
{0.128, 3, "nol koma satu dua delapan"},
{0.128, 4, "nol koma satu dua delapan"},
{0.128, 0, "nol"},
{0.12345, 5, "nol koma satu dua tiga empat lima"},
{23.12345, 5, "dua puluh tiga koma satu dua tiga empat lima"},
{1.123456, 6, "satu koma satu dua tiga empat lima enam"},
{0.1234563, 6, "nol koma satu dua tiga empat lima enam"},
{0.1234563, 7, "nol koma satu dua tiga empat lima enam tiga"},
{0.12345639, 8, "nol koma satu dua tiga empat lima enam tiga sembilan"},
{0.02345639, 1, "nol"},
{0.02345639, 2, "nol koma nol dua"},
{0.00000, 5, "nol"},
{0.00001, 5, "nol koma nol nol nol nol satu"},
{0.10000, 5, "nol koma satu"},
}

func TestFraction(t *testing.T) {
t.Parallel()
for _, tt := range fractionTest {
t.Run("testconvert", func(t *testing.T) {
w, err := ConvertDecimal(tt.Number, tt.Precision)
assert.Nil(t, err)
assert.Equal(t, tt.Words, w)
})
}
}