mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-26 08:45:16 +00:00
Merge pull request #179 from c9s/util/get-num-of-fractional-digits
feature: get num of fractional parts
This commit is contained in:
commit
6858d25070
|
@ -167,7 +167,7 @@ var ErrPrecisionLoss = errors.New("precision loss")
|
|||
func Parse(input string) (num int64, numDecimalPoints int, err error) {
|
||||
var neg int64 = 1
|
||||
var digit int64
|
||||
for i := 0 ; i < len(input) ; i++ {
|
||||
for i := 0; i < len(input); i++ {
|
||||
c := input[i]
|
||||
if c == '-' {
|
||||
neg = -1
|
||||
|
@ -177,15 +177,15 @@ func Parse(input string) (num int64, numDecimalPoints int, err error) {
|
|||
return
|
||||
}
|
||||
|
||||
num = num * 10 + digit
|
||||
num = num*10 + digit
|
||||
} else if c == '.' {
|
||||
i++
|
||||
if i > len(input) - 1 {
|
||||
if i > len(input)-1 {
|
||||
err = fmt.Errorf("expect fraction numbers after dot")
|
||||
return
|
||||
}
|
||||
|
||||
for j := i ; j < len(input); j++ {
|
||||
for j := i; j < len(input); j++ {
|
||||
fc := input[j]
|
||||
if fc >= '0' && fc <= '9' {
|
||||
digit, err = strconv.ParseInt(string(fc), 10, 64)
|
||||
|
@ -194,10 +194,10 @@ func Parse(input string) (num int64, numDecimalPoints int, err error) {
|
|||
}
|
||||
|
||||
numDecimalPoints++
|
||||
num = num * 10 + digit
|
||||
num = num*10 + digit
|
||||
|
||||
if numDecimalPoints >= MaxPrecision {
|
||||
return num, numDecimalPoints,ErrPrecisionLoss
|
||||
return num, numDecimalPoints, ErrPrecisionLoss
|
||||
}
|
||||
} else {
|
||||
err = fmt.Errorf("expect digit, got %c", fc)
|
||||
|
@ -263,3 +263,15 @@ func Max(a, b Value) Value {
|
|||
|
||||
return b
|
||||
}
|
||||
|
||||
func NumFractionalDigits(a Value) int {
|
||||
numPow := 0
|
||||
for pow := int64(DefaultPow); pow%10 != 1; pow /= 10 {
|
||||
numPow++
|
||||
}
|
||||
numZeros := 0
|
||||
for v := a.Int64(); v%10 == 0; v /= 10 {
|
||||
numZeros++
|
||||
}
|
||||
return numPow - numZeros
|
||||
}
|
||||
|
|
|
@ -14,40 +14,40 @@ func TestParse(t *testing.T) {
|
|||
wantErr bool
|
||||
}{
|
||||
{
|
||||
args: args{ input: "-99.9" },
|
||||
wantNum: -999,
|
||||
args: args{input: "-99.9"},
|
||||
wantNum: -999,
|
||||
wantNumDecimalPoints: 1,
|
||||
wantErr: false,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
args: args{ input: "0.12345678" },
|
||||
wantNum: 12345678,
|
||||
args: args{input: "0.12345678"},
|
||||
wantNum: 12345678,
|
||||
wantNumDecimalPoints: 8,
|
||||
wantErr: false,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
args: args{ input: "a" },
|
||||
wantNum: 0,
|
||||
args: args{input: "a"},
|
||||
wantNum: 0,
|
||||
wantNumDecimalPoints: 0,
|
||||
wantErr: true,
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
args: args{ input: "0.1" },
|
||||
wantNum: 1,
|
||||
args: args{input: "0.1"},
|
||||
wantNum: 1,
|
||||
wantNumDecimalPoints: 1,
|
||||
wantErr: false,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
args: args{ input: "100" },
|
||||
wantNum: 100,
|
||||
args: args{input: "100"},
|
||||
wantNum: 100,
|
||||
wantNumDecimalPoints: 0,
|
||||
wantErr: false,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
args: args{ input: "100.9999" },
|
||||
wantNum: 1009999,
|
||||
args: args{input: "100.9999"},
|
||||
wantNum: 1009999,
|
||||
wantNumDecimalPoints: 4,
|
||||
wantErr: false,
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
|
@ -66,3 +66,54 @@ func TestParse(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNumFractionalDigits(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
v Value
|
||||
want int
|
||||
}{
|
||||
{
|
||||
name: "over the default precision",
|
||||
v: MustNewFromString("0.123456789"),
|
||||
want: 8,
|
||||
},
|
||||
{
|
||||
name: "ignore the integer part",
|
||||
v: MustNewFromString("123.4567"),
|
||||
want: 4,
|
||||
},
|
||||
{
|
||||
name: "ignore the sign",
|
||||
v: MustNewFromString("-123.4567"),
|
||||
want: 4,
|
||||
},
|
||||
{
|
||||
name: "ignore the trailing zero",
|
||||
v: MustNewFromString("-123.45000000"),
|
||||
want: 2,
|
||||
},
|
||||
{
|
||||
name: "no fractional parts",
|
||||
v: MustNewFromString("-1"),
|
||||
want: 0,
|
||||
},
|
||||
{
|
||||
name: "no fractional parts",
|
||||
v: MustNewFromString("-1.0"),
|
||||
want: 0,
|
||||
},
|
||||
{
|
||||
name: "only fractional part",
|
||||
v: MustNewFromString(".123456"),
|
||||
want: 6,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := NumFractionalDigits(tt.v); got != tt.want {
|
||||
t.Errorf("NumFractionalDigits() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user