package strconv
type decimal struct {
d [800]byte
nd int
dp int
neg bool
trunc bool
}
func ( *decimal) () string {
:= 10 + .nd
if .dp > 0 {
+= .dp
}
if .dp < 0 {
+= -.dp
}
:= make([]byte, )
:= 0
switch {
case .nd == 0:
return "0"
case .dp <= 0:
[] = '0'
++
[] = '.'
++
+= digitZero([ : +-.dp])
+= copy([:], .d[0:.nd])
case .dp < .nd:
+= copy([:], .d[0:.dp])
[] = '.'
++
+= copy([:], .d[.dp:.nd])
default:
+= copy([:], .d[0:.nd])
+= digitZero([ : +.dp-.nd])
}
return string([0:])
}
func ( []byte) int {
for := range {
[] = '0'
}
return len()
}
func ( *decimal) {
for .nd > 0 && .d[.nd-1] == '0' {
.nd--
}
if .nd == 0 {
.dp = 0
}
}
func ( *decimal) ( uint64) {
var [24]byte
:= 0
for > 0 {
:= / 10
-= 10 *
[] = byte( + '0')
++
=
}
.nd = 0
for --; >= 0; -- {
.d[.nd] = []
.nd++
}
.dp = .nd
trim()
}
const uintSize = 32 << (^uint(0) >> 63)
const maxShift = uintSize - 4
func ( *decimal, uint) {
:= 0
:= 0
var uint
for ; >> == 0; ++ {
if >= .nd {
if == 0 {
.nd = 0
return
}
for >> == 0 {
= * 10
++
}
break
}
:= uint(.d[])
= *10 + - '0'
}
.dp -= - 1
var uint = (1 << ) - 1
for ; < .nd; ++ {
:= uint(.d[])
:= >>
&=
.d[] = byte( + '0')
++
= *10 + - '0'
}
for > 0 {
:= >>
&=
if < len(.d) {
.d[] = byte( + '0')
++
} else if > 0 {
.trunc = true
}
= * 10
}
.nd =
trim()
}
type leftCheat struct {
delta int
cutoff string
}
var leftcheats = []leftCheat{
{0, ""},
{1, "5"},
{1, "25"},
{1, "125"},
{2, "625"},
{2, "3125"},
{2, "15625"},
{3, "78125"},
{3, "390625"},
{3, "1953125"},
{4, "9765625"},
{4, "48828125"},
{4, "244140625"},
{4, "1220703125"},
{5, "6103515625"},
{5, "30517578125"},
{5, "152587890625"},
{6, "762939453125"},
{6, "3814697265625"},
{6, "19073486328125"},
{7, "95367431640625"},
{7, "476837158203125"},
{7, "2384185791015625"},
{7, "11920928955078125"},
{8, "59604644775390625"},
{8, "298023223876953125"},
{8, "1490116119384765625"},
{9, "7450580596923828125"},
{9, "37252902984619140625"},
{9, "186264514923095703125"},
{10, "931322574615478515625"},
{10, "4656612873077392578125"},
{10, "23283064365386962890625"},
{10, "116415321826934814453125"},
{11, "582076609134674072265625"},
{11, "2910383045673370361328125"},
{11, "14551915228366851806640625"},
{12, "72759576141834259033203125"},
{12, "363797880709171295166015625"},
{12, "1818989403545856475830078125"},
{13, "9094947017729282379150390625"},
{13, "45474735088646411895751953125"},
{13, "227373675443232059478759765625"},
{13, "1136868377216160297393798828125"},
{14, "5684341886080801486968994140625"},
{14, "28421709430404007434844970703125"},
{14, "142108547152020037174224853515625"},
{15, "710542735760100185871124267578125"},
{15, "3552713678800500929355621337890625"},
{15, "17763568394002504646778106689453125"},
{16, "88817841970012523233890533447265625"},
{16, "444089209850062616169452667236328125"},
{16, "2220446049250313080847263336181640625"},
{16, "11102230246251565404236316680908203125"},
{17, "55511151231257827021181583404541015625"},
{17, "277555756156289135105907917022705078125"},
{17, "1387778780781445675529539585113525390625"},
{18, "6938893903907228377647697925567626953125"},
{18, "34694469519536141888238489627838134765625"},
{18, "173472347597680709441192448139190673828125"},
{19, "867361737988403547205962240695953369140625"},
}
func ( []byte, string) bool {
for := 0; < len(); ++ {
if >= len() {
return true
}
if [] != [] {
return [] < []
}
}
return false
}
func ( *decimal, uint) {
:= leftcheats[].delta
if prefixIsLessThan(.d[0:.nd], leftcheats[].cutoff) {
--
}
:= .nd
:= .nd +
var uint
for --; >= 0; -- {
+= (uint(.d[]) - '0') <<
:= / 10
:= - 10*
--
if < len(.d) {
.d[] = byte( + '0')
} else if != 0 {
.trunc = true
}
=
}
for > 0 {
:= / 10
:= - 10*
--
if < len(.d) {
.d[] = byte( + '0')
} else if != 0 {
.trunc = true
}
=
}
.nd +=
if .nd >= len(.d) {
.nd = len(.d)
}
.dp +=
trim()
}
func ( *decimal) ( int) {
switch {
case .nd == 0:
case > 0:
for > maxShift {
leftShift(, maxShift)
-= maxShift
}
leftShift(, uint())
case < 0:
for < -maxShift {
rightShift(, maxShift)
+= maxShift
}
rightShift(, uint(-))
}
}
func ( *decimal, int) bool {
if < 0 || >= .nd {
return false
}
if .d[] == '5' && +1 == .nd {
if .trunc {
return true
}
return > 0 && (.d[-1]-'0')%2 != 0
}
return .d[] >= '5'
}
func ( *decimal) ( int) {
if < 0 || >= .nd {
return
}
if shouldRoundUp(, ) {
.RoundUp()
} else {
.RoundDown()
}
}
func ( *decimal) ( int) {
if < 0 || >= .nd {
return
}
.nd =
trim()
}
func ( *decimal) ( int) {
if < 0 || >= .nd {
return
}
for := - 1; >= 0; -- {
:= .d[]
if < '9' {
.d[]++
.nd = + 1
return
}
}
.d[0] = '1'
.nd = 1
.dp++
}
func ( *decimal) () uint64 {
if .dp > 20 {
return 0xFFFFFFFFFFFFFFFF
}
var int
:= uint64(0)
for = 0; < .dp && < .nd; ++ {
= *10 + uint64(.d[]-'0')
}
for ; < .dp; ++ {
*= 10
}
if shouldRoundUp(, .dp) {
++
}
return
}