0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Go言語 数値の書式(オリジナル関数)

Posted at

数値の書式

Go言語では、数値をカンマ区切りするのは、ローカライズで作れる。"golang.org/x/text/language"を参照
日本で数値を読む場合は、一,十,百,万のように4桁区切りが使われる。3桁カンマ区切りだと非常に読みづらい。
そこで、区切り位置,区切り文字を自由に設定できる関数を作ってみた。

FtoA関数

※注意: 指数表現(ex E03)には対応していない。
引数2(kind)のパターン (引数1 f64 = 1234567.890123 の場合)
0: 1,234,567.890 123 (ISOモデル 英, 日本など).
1: 1 234 567,890 123 (仏など).
2: 1.234.567,890 123 (独など).
3: 1'234'567,890 123 (スイスなど).
-1: 123'4567.8901 23 (今回の目的 4桁 区切り).

小数点以下の区切りが必要ない場合は、変数esを""にすれば良い。

import (
	"strconv"
	"strings"
)

func FtoA(f64 float64, kind int) string {
	var result string
	var wl int
	var sl int
	var ps string
	var ss string
	var es string

	switch kind {
	case 0: //[0] ISO,en,ja: 1,234,567.890
		sl = 3
		ps = "."
		ss = ","
		es = " "
	case 1: //[1] fr: 1 234 567,89
		sl = 3
		ps = ","
		ss = " "
		es = " "
	case 2: //[2] de: 1.234.567,89
		sl = 3
		ps = ","
		ss = "."
		es = " "
	case 3: //[3] ch: 1'234'567,89
		sl = 3
		ps = "."
		ss = "'"
		es = " "
	case -1: //[-1] ja4: 123'4567.890
		sl = 4
		ps = "."
		ss = "'"
		es = " "
	}

	w := strconv.FormatFloat(f64, 'f', -1, 64)

	sign := false
	if w[:1] == "-" {
		sign = true
		wl = len(w)
		w = w[1:wl]
	}
	wl = len(w)

	point := strings.Index(w, ".")
	if point < 0 {
		point = len(w)
	}
	ww := strings.Split(w, "")

	for i := range ww {

		if i < point {
			result = result + ww[i]

			j := point - i - 1
			if (j%sl == 0) && (j > 0) {
				result = result + ss
			}
		} else if i == point {
			result = result + ps
		} else {
			result = result + ww[i]

			j := i - point
			if (j%sl == 0) && (i+1 < wl) {
				result = result + es
			}
		}
	}

	if sign {
		result = "-" + result
	}

	return result
}

整数型(int,int8 ... int64)の場合は、float64(int)で変換する

  i64 := int64(123456789)
  num := FtoA(float64(i64), -1)
  fmt.Println(num)

出力結果は 1'2345'6789 となる。
日本語の読みは、1億 2千 3百 4十 5万 6千 7百 8十 9とかになる。
読む時に 1億2千万円 とか、下の桁を省略しやすくなる。

AtoF関数

FtoA関数の逆も欲しい。
※注意: 指数表現(ex E00)には対応していない。

func AtoF(s string, kind int) float64 {
	var result float64
	var w string
	var ww []string
	var ps string

	switch kind {
	case 0: //[0] ISO,en,ja: 1,234,567.890
		ps = "."
	case 1: //[1] fr: 1 234 567,89
		ps = ","
	case 2: //[2] de: 1.234.567,89
		ps = ","
	case 3: //[3] ch: 1'234'567,89
		ps = "."
	case -1: //[-1] ja4: 123'4567.890
		ps = "."
	}

	ww = strings.Split(s, "")

	if ww[0] == "-" {
		w = ww[0]
	}

	for i := range ww {
		switch ww[i] {
		case "0", "1", "2", "3", "4", "5", "6", "7", "8", "9":
			w = w + ww[i]
		case ps:
			w = w + "."
		}
	}

	result, _ = strconv.ParseFloat(w, 64)
	return result
}

この AtoF関数は、単位などが含まれていてもOK!

  s := "123,456.789(kg)"
  f64 := AtoF(s, 0)
  fmt.Println(f64)

出力結果は 123456.789 となる。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?