Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
intconv.go256 linesDownload Raw Back to big
1// Copyright 2015 The Go Authors. All rights reserved.2// Use of this source code is governed by a BSD-style3// license that can be found in the LICENSE file.4 5// This file implements int-to-string conversion functions.6 7package big8 9import (10	"errors"11	"fmt"12	"io"13)14 15// Text returns the string representation of x in the given base.16// Base must be between 2 and 62, inclusive. The result uses the17// lower-case letters 'a' to 'z' for digit values 10 to 35, and18// the upper-case letters 'A' to 'Z' for digit values 36 to 61.19// No prefix (such as "0x") is added to the string. If x is a nil20// pointer it returns "<nil>".21func (x *Int) Text(base int) string {22	if x == nil {23		return "<nil>"24	}25	return string(x.abs.itoa(x.neg, base))26}27 28// Append appends the string representation of x, as generated by29// x.Text(base), to buf and returns the extended buffer.30func (x *Int) Append(buf []byte, base int) []byte {31	if x == nil {32		return append(buf, "<nil>"...)33	}34	return append(buf, x.abs.itoa(x.neg, base)...)35}36 37// String returns the decimal representation of x as generated by38// x.Text(10).39func (x *Int) String() string {40	return x.Text(10)41}42 43// write count copies of text to s.44func writeMultiple(s fmt.State, text string, count int) {45	if len(text) > 0 {46		b := []byte(text)47		for ; count > 0; count-- {48			s.Write(b)49		}50	}51}52 53var _ fmt.Formatter = intOne // *Int must implement fmt.Formatter54 55// Format implements [fmt.Formatter]. It accepts the formats56// 'b' (binary), 'o' (octal with 0 prefix), 'O' (octal with 0o prefix),57// 'd' (decimal), 'x' (lowercase hexadecimal), and58// 'X' (uppercase hexadecimal).59// Also supported are the full suite of package fmt's format60// flags for integral types, including '+' and ' ' for sign61// control, '#' for leading zero in octal and for hexadecimal,62// a leading "0x" or "0X" for "%#x" and "%#X" respectively,63// specification of minimum digits precision, output field64// width, space or zero padding, and '-' for left or right65// justification.66func (x *Int) Format(s fmt.State, ch rune) {67	// determine base68	var base int69	switch ch {70	case 'b':71		base = 272	case 'o', 'O':73		base = 874	case 'd', 's', 'v':75		base = 1076	case 'x', 'X':77		base = 1678	default:79		// unknown format80		fmt.Fprintf(s, "%%!%c(big.Int=%s)", ch, x.String())81		return82	}83 84	if x == nil {85		fmt.Fprint(s, "<nil>")86		return87	}88 89	// determine sign character90	sign := ""91	switch {92	case x.neg:93		sign = "-"94	case s.Flag('+'): // supersedes ' ' when both specified95		sign = "+"96	case s.Flag(' '):97		sign = " "98	}99 100	// determine prefix characters for indicating output base101	prefix := ""102	if s.Flag('#') {103		switch ch {104		case 'b': // binary105			prefix = "0b"106		case 'o': // octal107			prefix = "0"108		case 'x': // hexadecimal109			prefix = "0x"110		case 'X':111			prefix = "0X"112		}113	}114	if ch == 'O' {115		prefix = "0o"116	}117 118	digits := x.abs.utoa(base)119	if ch == 'X' {120		// faster than bytes.ToUpper121		for i, d := range digits {122			if 'a' <= d && d <= 'z' {123				digits[i] = 'A' + (d - 'a')124			}125		}126	}127 128	// number of characters for the three classes of number padding129	var left int  // space characters to left of digits for right justification ("%8d")130	var zeros int // zero characters (actually cs[0]) as left-most digits ("%.8d")131	var right int // space characters to right of digits for left justification ("%-8d")132 133	// determine number padding from precision: the least number of digits to output134	precision, precisionSet := s.Precision()135	if precisionSet {136		switch {137		case len(digits) < precision:138			zeros = precision - len(digits) // count of zero padding139		case len(digits) == 1 && digits[0] == '0' && precision == 0:140			return // print nothing if zero value (x == 0) and zero precision ("." or ".0")141		}142	}143 144	// determine field pad from width: the least number of characters to output145	length := len(sign) + len(prefix) + zeros + len(digits)146	if width, widthSet := s.Width(); widthSet && length < width { // pad as specified147		switch d := width - length; {148		case s.Flag('-'):149			// pad on the right with spaces; supersedes '0' when both specified150			right = d151		case s.Flag('0') && !precisionSet:152			// pad with zeros unless precision also specified153			zeros = d154		default:155			// pad on the left with spaces156			left = d157		}158	}159 160	// print number as [left pad][sign][prefix][zero pad][digits][right pad]161	writeMultiple(s, " ", left)162	writeMultiple(s, sign, 1)163	writeMultiple(s, prefix, 1)164	writeMultiple(s, "0", zeros)165	s.Write(digits)166	writeMultiple(s, " ", right)167}168 169// scan sets z to the integer value corresponding to the longest possible prefix170// read from r representing a signed integer number in a given conversion base.171// It returns z, the actual conversion base used, and an error, if any. In the172// error case, the value of z is undefined but the returned value is nil. The173// syntax follows the syntax of integer literals in Go.174//175// The base argument must be 0 or a value from 2 through MaxBase. If the base176// is 0, the string prefix determines the actual conversion base. A prefix of177// “0b” or “0B” selects base 2; a “0”, “0o”, or “0O” prefix selects178// base 8, and a “0x” or “0X” prefix selects base 16. Otherwise the selected179// base is 10.180func (z *Int) scan(r io.ByteScanner, base int) (*Int, int, error) {181	// determine sign182	neg, err := scanSign(r)183	if err != nil {184		return nil, 0, err185	}186 187	// determine mantissa188	z.abs, base, _, err = z.abs.scan(r, base, false)189	if err != nil {190		return nil, base, err191	}192	z.neg = len(z.abs) > 0 && neg // 0 has no sign193 194	return z, base, nil195}196 197func scanSign(r io.ByteScanner) (neg bool, err error) {198	var ch byte199	if ch, err = r.ReadByte(); err != nil {200		return false, err201	}202	switch ch {203	case '-':204		neg = true205	case '+':206		// nothing to do207	default:208		r.UnreadByte()209	}210	return211}212 213// byteReader is a local wrapper around fmt.ScanState;214// it implements the ByteReader interface.215type byteReader struct {216	fmt.ScanState217}218 219func (r byteReader) ReadByte() (byte, error) {220	ch, size, err := r.ReadRune()221	if size != 1 && err == nil {222		err = fmt.Errorf("invalid rune %#U", ch)223	}224	return byte(ch), err225}226 227func (r byteReader) UnreadByte() error {228	return r.UnreadRune()229}230 231var _ fmt.Scanner = intOne // *Int must implement fmt.Scanner232 233// Scan is a support routine for [fmt.Scanner]; it sets z to the value of234// the scanned number. It accepts the formats 'b' (binary), 'o' (octal),235// 'd' (decimal), 'x' (lowercase hexadecimal), and 'X' (uppercase hexadecimal).236func (z *Int) Scan(s fmt.ScanState, ch rune) error {237	s.SkipSpace() // skip leading space characters238	base := 0239	switch ch {240	case 'b':241		base = 2242	case 'o':243		base = 8244	case 'd':245		base = 10246	case 'x', 'X':247		base = 16248	case 's', 'v':249		// let scan determine the base250	default:251		return errors.New("Int.Scan: invalid verb")252	}253	_, _, err := z.scan(byteReader{s}, base)254	return err255}256 
codekingpro/portable-devtools · Team Ai