// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file implements rat-to-string conversion functions.

package big

import (
	
	
	
	
	
)

func ratTok( rune) bool {
	return strings.ContainsRune("+-/0123456789.eE", )
}

var ratZero Rat
var _ fmt.Scanner = &ratZero // *Rat must implement fmt.Scanner

// Scan is a support routine for fmt.Scanner. It accepts the formats
// 'e', 'E', 'f', 'F', 'g', 'G', and 'v'. All formats are equivalent.
func ( *Rat) ( fmt.ScanState,  rune) error {
	,  := .Token(true, ratTok)
	if  != nil {
		return 
	}
	if !strings.ContainsRune("efgEFGv", ) {
		return errors.New("Rat.Scan: invalid verb")
	}
	if ,  := .SetString(string()); ! {
		return errors.New("Rat.Scan: invalid syntax")
	}
	return nil
}

// SetString sets z to the value of s and returns z and a boolean indicating
// success. s can be given as a (possibly signed) fraction "a/b", or as a
// floating-point number optionally followed by an exponent.
// If a fraction is provided, both the dividend and the divisor may be a
// decimal integer or independently use a prefix of “0b”, “0” or “0o”,
// or “0x” (or their upper-case variants) to denote a binary, octal, or
// hexadecimal integer, respectively. The divisor may not be signed.
// If a floating-point number is provided, it may be in decimal form or
// use any of the same prefixes as above but for “0” to denote a non-decimal
// mantissa. A leading “0” is considered a decimal leading 0; it does not
// indicate octal representation in this case.
// An optional base-10 “e” or base-2 “p” (or their upper-case variants)
// exponent may be provided as well, except for hexadecimal floats which
// only accept an (optional) “p” exponent (because an “e” or “E” cannot
// be distinguished from a mantissa digit). If the exponent's absolute value
// is too large, the operation may fail.
// The entire string, not just a prefix, must be valid for success. If the
// operation failed, the value of z is undefined but the returned value is nil.
func ( *Rat) ( string) (*Rat, bool) {
	if len() == 0 {
		return nil, false
	}
	// len(s) > 0

	// parse fraction a/b, if any
	if  := strings.Index(, "/");  >= 0 {
		if ,  := .a.SetString([:], 0); ! {
			return nil, false
		}
		 := strings.NewReader([+1:])
		var  error
		if .b.abs, _, _,  = .b.abs.scan(, 0, false);  != nil {
			return nil, false
		}
		// entire string must have been consumed
		if _,  = .ReadByte();  != io.EOF {
			return nil, false
		}
		if len(.b.abs) == 0 {
			return nil, false
		}
		return .norm(), true
	}

	// parse floating-point number
	 := strings.NewReader()

	// sign
	,  := scanSign()
	if  != nil {
		return nil, false
	}

	// mantissa
	var  int
	var  int // fractional digit count; valid if <= 0
	.a.abs, , ,  = .a.abs.scan(, 0, true)
	if  != nil {
		return nil, false
	}

	// exponent
	var  int64
	var  int
	, ,  = scanExponent(, true, true)
	if  != nil {
		return nil, false
	}

	// there should be no unread characters left
	if _,  = .ReadByte();  != io.EOF {
		return nil, false
	}

	// special-case 0 (see also issue #16176)
	if len(.a.abs) == 0 {
		return .norm(), true
	}
	// len(z.a.abs) > 0

	// The mantissa may have a radix point (fcount <= 0) and there
	// may be a nonzero exponent exp. The radix point amounts to a
	// division by base**(-fcount), which equals a multiplication by
	// base**fcount. An exponent means multiplication by ebase**exp.
	// Multiplications are commutative, so we can apply them in any
	// order. We only have powers of 2 and 10, and we split powers
	// of 10 into the product of the same powers of 2 and 5. This
	// may reduce the size of shift/multiplication factors or
	// divisors required to create the final fraction, depending
	// on the actual floating-point value.

	// determine binary or decimal exponent contribution of radix point
	var ,  int64
	if  < 0 {
		// The mantissa has a radix point ddd.dddd; and
		// -fcount is the number of digits to the right
		// of '.'. Adjust relevant exponent accordingly.
		 := int64()
		switch  {
		case 10:
			 = 
			fallthrough // 10**e == 5**e * 2**e
		case 2:
			 = 
		case 8:
			 =  * 3 // octal digits are 3 bits each
		case 16:
			 =  * 4 // hexadecimal digits are 4 bits each
		default:
			panic("unexpected mantissa base")
		}
		// fcount consumed - not needed anymore
	}

	// take actual exponent into account
	switch  {
	case 10:
		 += 
		fallthrough // see fallthrough above
	case 2:
		 += 
	default:
		panic("unexpected exponent base")
	}
	// exp consumed - not needed anymore

	// apply exp5 contributions
	// (start with exp5 so the numbers to multiply are smaller)
	if  != 0 {
		 := 
		if  < 0 {
			 = -
			if  < 0 {
				// This can occur if -n overflows. -(-1 << 63) would become
				// -1 << 63, which is still negative.
				return nil, false
			}
		}
		if  > 1e6 {
			return nil, false // avoid excessively large exponents
		}
		 := .b.abs.expNN(natFive, nat(nil).setWord(Word()), nil, false) // use underlying array of z.b.abs
		if  > 0 {
			.a.abs = .a.abs.mul(.a.abs, )
			.b.abs = .b.abs.setWord(1)
		} else {
			.b.abs = 
		}
	} else {
		.b.abs = .b.abs.setWord(1)
	}

	// apply exp2 contributions
	if  < -1e7 ||  > 1e7 {
		return nil, false // avoid excessively large exponents
	}
	if  > 0 {
		.a.abs = .a.abs.shl(.a.abs, uint())
	} else if  < 0 {
		.b.abs = .b.abs.shl(.b.abs, uint(-))
	}

	.a.neg =  && len(.a.abs) > 0 // 0 has no sign

	return .norm(), true
}

// scanExponent scans the longest possible prefix of r representing a base 10
// (“e”, “E”) or a base 2 (“p”, “P”) exponent, if any. It returns the
// exponent, the exponent base (10 or 2), or a read or syntax error, if any.
//
// If sepOk is set, an underscore character “_” may appear between successive
// exponent digits; such underscores do not change the value of the exponent.
// Incorrect placement of underscores is reported as an error if there are no
// other errors. If sepOk is not set, underscores are not recognized and thus
// terminate scanning like any other character that is not a valid digit.
//
//	exponent = ( "e" | "E" | "p" | "P" ) [ sign ] digits .
//	sign     = "+" | "-" .
//	digits   = digit { [ '_' ] digit } .
//	digit    = "0" ... "9" .
//
// A base 2 exponent is only permitted if base2ok is set.
func scanExponent( io.ByteScanner, ,  bool) ( int64,  int,  error) {
	// one char look-ahead
	,  := .ReadByte()
	if  != nil {
		if  == io.EOF {
			 = nil
		}
		return 0, 10, 
	}

	// exponent char
	switch  {
	case 'e', 'E':
		 = 10
	case 'p', 'P':
		if  {
			 = 2
			break // ok
		}
		fallthrough // binary exponent not permitted
	default:
		.UnreadByte() // ch does not belong to exponent anymore
		return 0, 10, nil
	}

	// sign
	var  []byte
	,  = .ReadByte()
	if  == nil && ( == '+' ||  == '-') {
		if  == '-' {
			 = append(, '-')
		}
		,  = .ReadByte()
	}

	// prev encodes the previously seen char: it is one
	// of '_', '0' (a digit), or '.' (anything else). A
	// valid separator '_' may only occur after a digit.
	 := '.'
	 := false

	// exponent value
	 := false
	for  == nil {
		if '0' <=  &&  <= '9' {
			 = append(, )
			 = '0'
			 = true
		} else if  == '_' &&  {
			if  != '0' {
				 = true
			}
			 = '_'
		} else {
			.UnreadByte() // ch does not belong to number anymore
			break
		}
		,  = .ReadByte()
	}

	if  == io.EOF {
		 = nil
	}
	if  == nil && ! {
		 = errNoDigits
	}
	if  == nil {
		,  = strconv.ParseInt(string(), 10, 64)
	}
	// other errors take precedence over invalid separators
	if  == nil && ( ||  == '_') {
		 = errInvalSep
	}

	return
}

// String returns a string representation of x in the form "a/b" (even if b == 1).
func ( *Rat) () string {
	return string(.marshal(nil))
}

// marshal implements [Rat.String] returning a slice of bytes.
// It appends the string representation of x in the form "a/b" (even if b == 1) to buf,
// and returns the extended buffer.
func ( *Rat) ( []byte) []byte {
	 = .a.Append(, 10)
	 = append(, '/')
	if len(.b.abs) != 0 {
		 = .b.Append(, 10)
	} else {
		 = append(, '1')
	}
	return 
}

// RatString returns a string representation of x in the form "a/b" if b != 1,
// and in the form "a" if b == 1.
func ( *Rat) () string {
	if .IsInt() {
		return .a.String()
	}
	return .String()
}

// FloatString returns a string representation of x in decimal form with prec
// digits of precision after the radix point. The last digit is rounded to
// nearest, with halves rounded away from zero.
func ( *Rat) ( int) string {
	var  []byte

	if .IsInt() {
		 = .a.Append(, 10)
		if  > 0 {
			 = append(, '.')
			for  := ;  > 0; -- {
				 = append(, '0')
			}
		}
		return string()
	}
	// x.b.abs != 0

	,  := nat(nil).div(nat(nil), .a.abs, .b.abs)

	 := natOne
	if  > 0 {
		 = nat(nil).expNN(natTen, nat(nil).setUint64(uint64()), nil, false)
	}

	 = .mul(, )
	,  := .div(nat(nil), , .b.abs)

	// see if we need to round up
	 = .add(, )
	if .b.abs.cmp() <= 0 {
		 = .add(, natOne)
		if .cmp() >= 0 {
			 = nat(nil).add(, natOne)
			 = nat(nil).sub(, )
		}
	}

	if .a.neg {
		 = append(, '-')
	}
	 = append(, .utoa(10)...) // itoa ignores sign if q == 0

	if  > 0 {
		 = append(, '.')
		 := .utoa(10)
		for  :=  - len();  > 0; -- {
			 = append(, '0')
		}
		 = append(, ...)
	}

	return string()
}

// Note: FloatPrec (below) is in this file rather than rat.go because
//       its results are relevant for decimal representation/printing.

// FloatPrec returns the number n of non-repeating digits immediately
// following the decimal point of the decimal representation of x.
// The boolean result indicates whether a decimal representation of x
// with that many fractional digits is exact or rounded.
//
// Examples:
//
//	x      n    exact    decimal representation n fractional digits
//	0      0    true     0
//	1      0    true     1
//	1/2    1    true     0.5
//	1/3    0    false    0       (0.333... rounded)
//	1/4    2    true     0.25
//	1/6    1    false    0.2     (0.166... rounded)
func ( *Rat) () ( int,  bool) {
	// Determine q and largest p2, p5 such that d = q·2^p2·5^p5.
	// The results n, exact are:
	//
	//     n = max(p2, p5)
	//     exact = q == 1
	//
	// For details see:
	// https://en.wikipedia.org/wiki/Repeating_decimal#Reciprocals_of_integers_not_coprime_to_10
	 := .Denom().abs // d >= 1

	// Determine p2 by counting factors of 2.
	// p2 corresponds to the trailing zero bits in d.
	// Do this first to reduce q as much as possible.
	var  nat
	 := .trailingZeroBits()
	 = .shr(, )

	// Determine p5 by counting factors of 5.
	// Build a table starting with an initial power of 5,
	// and use repeated squaring until the factor doesn't
	// divide q anymore. Then use the table to determine
	// the power of 5 in q.
	const  = 13        // f == 5^fp
	var  []nat        // tab[i] == (5^fp)^(2^i) == 5^(fp·2^i)
	 := nat{1220703125} // == 5^fp (must fit into a uint32 Word)
	var ,  nat         // temporaries
	for {
		if _,  = .div(, , ); len() != 0 {
			break // f doesn't divide q evenly
		}
		 = append(, )
		 = nat(nil).sqr() // nat(nil) to ensure a new f for each table entry
	}

	// Factor q using the table entries, if any.
	// We start with the largest factor f = tab[len(tab)-1]
	// that evenly divides q. It does so at most once because
	// otherwise f·f would also divide q. That can't be true
	// because f·f is the next higher table entry, contradicting
	// how f was chosen in the first place.
	// The same reasoning applies to the subsequent factors.
	var  uint
	for  := len() - 1;  >= 0; -- {
		if ,  = .div(, , []); len() == 0 {
			 +=  * (1 << ) // tab[i] == 5^(fp·2^i)
			 = .set()
		}
	}

	// If fp != 1, we may still have multiples of 5 left.
	for {
		if ,  = .div(, , natFive); len() != 0 {
			break
		}
		++
		 = .set()
	}

	return int(max(, )), .cmp(natOne) == 0
}