// 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).
// 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 , 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 {
			 = -
		}
		 := .b.abs.expNN(natFive, nat(nil).setWord(Word()), nil) // 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  > 0 {
		if int64(uint()) !=  {
			panic("exponent too large")
		}
		.a.abs = .a.abs.shl(.a.abs, uint())
	} else if  < 0 {
		if int64(uint(-)) != - {
			panic("exponent too large")
		}
		.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())
}

// marshal implements String returning a slice of bytes
func ( *Rat) () []byte {
	var  []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)
	}

	 = .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()
}