-
Notifications
You must be signed in to change notification settings - Fork 41
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
575 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package numbers | ||
|
||
import ( | ||
"math" | ||
"strconv" | ||
) | ||
|
||
func GetAmountValue(amount string) string { | ||
value := ParseAmount(amount) | ||
return strconv.FormatInt(value, 10) | ||
} | ||
|
||
func ParseAmount(amount string) int64 { | ||
value, err := strconv.ParseInt(amount, 10, 64) | ||
if err == nil { | ||
return value | ||
} | ||
return ToSatoshi(amount) | ||
} | ||
|
||
func ToSatoshi(amount string) int64 { | ||
value, err := strconv.ParseFloat(amount, 64) | ||
if err != nil { | ||
return 0 | ||
} | ||
total := value * math.Pow10(8) | ||
return int64(total) | ||
} | ||
|
||
func AddAmount(left string, right string) (sum string) { | ||
amount1 := ParseAmount(left) | ||
amount2 := ParseAmount(right) | ||
return strconv.FormatInt(amount1+amount2, 10) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
package numbers | ||
|
||
import ( | ||
"testing" | ||
) | ||
|
||
func Test_addAmount(t *testing.T) { | ||
type args struct { | ||
left string | ||
right string | ||
} | ||
tests := []struct { | ||
name string | ||
args args | ||
wantSum string | ||
}{ | ||
{"test zero + float", args{left: "0", right: "0.33333"}, "33333000"}, | ||
{"test zero + int", args{left: "0", right: "333"}, "333"}, | ||
{"test zero + zero", args{left: "0", right: "0"}, "0"}, | ||
{"test int + float", args{left: "232", right: "0.222"}, "22200232"}, | ||
{"test int + int", args{left: "661", right: "12"}, "673"}, | ||
{"test int + zero", args{left: "131", right: "0"}, "131"}, | ||
{"test float + float", args{left: "0.4141", right: "0.11211"}, "52621000"}, | ||
{"test float + int", args{left: "3.111", right: "11"}, "311100011"}, | ||
{"test float + zero", args{left: "0.455", right: "0"}, "45500000"}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
if gotSum := AddAmount(tt.args.left, tt.args.right); gotSum != tt.wantSum { | ||
t.Errorf("AddAmount() = %v, want %v", gotSum, tt.wantSum) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func Test_ToSatoshi(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
amount string | ||
want int64 | ||
}{ | ||
{"test float", "0.33333", 33333000}, | ||
{"test int", "3333", 333300000000}, | ||
{"test zero", "0", 0}, | ||
{"test error", "trust", 0}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
if got := ToSatoshi(tt.amount); got != tt.want { | ||
t.Errorf("ToSatoshi() = %v, want %v", got, tt.want) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func Test_getValue(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
amount string | ||
want string | ||
}{ | ||
{"test float", "0.33333", "33333000"}, | ||
{"test int", "3333", "3333"}, | ||
{"test zero", "0", "0"}, | ||
{"test error", "trust", "0"}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
if got := GetAmountValue(tt.amount); got != tt.want { | ||
t.Errorf("GetAmountValue() = %v, want %v", got, tt.want) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func Test_parseAmount(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
amount string | ||
want int64 | ||
}{ | ||
{"test float", "0.33333", 33333000}, | ||
{"test int", "3333", 3333}, | ||
{"test zero", "0", 0}, | ||
{"test error", "trust", 0}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
if got := ParseAmount(tt.amount); got != tt.want { | ||
t.Errorf("ParseAmount() = %v, want %v", got, tt.want) | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
package numbers | ||
|
||
import ( | ||
"errors" | ||
"math/big" | ||
"strings" | ||
"unicode" | ||
) | ||
|
||
// DecimalToSatoshis removes the comma in a decimal string | ||
// "12.345" => "12345" | ||
// "0.0230" => "230" | ||
func DecimalToSatoshis(dec string) (string, error) { | ||
out := strings.TrimLeft(dec, " ") | ||
out = strings.TrimRight(out, " ") | ||
out = strings.Replace(out, ".", "", 1) | ||
// trim left 0's but keep last | ||
if l := len(out); l >= 2 { | ||
out = strings.TrimLeft(out[:l-1], "0") + out[l-1:l] | ||
} | ||
if len(out) == 0 { | ||
return "", errors.New("Invalid empty input: " + dec) | ||
} | ||
for _, c := range out { | ||
if !unicode.IsNumber(c) { | ||
return "", errors.New("not a number: " + dec) | ||
} | ||
} | ||
return out, nil | ||
} | ||
|
||
// DecimalExp calculates dec * 10^exp in decimal string representation | ||
func DecimalExp(dec string, exp int) string { | ||
// 0 * n = 0 | ||
if dec == "0" { | ||
return "0" | ||
} | ||
// Get comma position | ||
i := strings.IndexRune(dec, '.') | ||
if i == -1 { | ||
// Virtual comma at the end of the string | ||
i = len(dec) | ||
} else { | ||
// Remove comma from underlying number | ||
dec = strings.Replace(dec, ".", "", 1) | ||
} | ||
// Shift comma by exponent | ||
i += exp | ||
// Remove leading zeros | ||
origSize := len(dec) | ||
dec = strings.TrimLeft(dec, "0") | ||
i -= origSize - len(dec) | ||
// Fix bounds | ||
if i <= 0 { | ||
zeros := "" | ||
for ; i < 0; i++ { | ||
zeros += "0" | ||
} | ||
return "0." + zeros + dec | ||
} else if i >= len(dec) { | ||
for i > len(dec) { | ||
dec += "0" | ||
} | ||
return dec | ||
} | ||
// No bound fix needed | ||
return dec[:i] + "." + dec[i:] | ||
} | ||
|
||
// HexToDecimal converts a hexadecimal integer to a base-10 integer | ||
// "0x1fbad5f2e25570000" => "36582000000000000000" | ||
func HexToDecimal(hex string) (string, error) { | ||
var i big.Int | ||
if _, ok := i.SetString(hex, 0); !ok { | ||
return "", errors.New("invalid hex: " + hex) | ||
} | ||
return i.String(), nil | ||
} | ||
|
||
// CutZeroFractional cuts off a decimal separator and zeros to the right. | ||
// Fails if the fractional part contains contains other digits than zeros. | ||
// - CutZeroFractional("123.00000") => ("123", true) | ||
// - CutZeroFractional("123.456") => ("", false) | ||
func CutZeroFractional(dec string) (integer string, ok bool) { | ||
// Get comma position | ||
comma := strings.IndexRune(dec, '.') | ||
if comma == -1 { | ||
return dec, true | ||
} | ||
|
||
for i := len(dec) - 1; i > comma; i-- { | ||
if dec[i] != '0' { | ||
return "", false | ||
} | ||
} | ||
|
||
if comma == 0 { | ||
return "0", true | ||
} else { | ||
return dec[:comma], true | ||
} | ||
} |
Oops, something went wrong.