Ejemplo n.º 1
0
Archivo: mpint.go Proyecto: achanda/go
func (a *Mpint) SetFloat(b *Mpflt) int {
	// avoid converting huge floating-point numbers to integers
	// (2*Mpprec is large enough to permit all tests to pass)
	if b.Val.MantExp(nil) > 2*Mpprec {
		return -1
	}

	if _, acc := b.Val.Int(&a.Val); acc == big.Exact {
		return 0
	}

	const delta = 16 // a reasonably small number of bits > 0
	var t big.Float
	t.SetPrec(Mpprec - delta)

	// try rounding down a little
	t.SetMode(big.ToZero)
	t.Set(&b.Val)
	if _, acc := t.Int(&a.Val); acc == big.Exact {
		return 0
	}

	// try rounding up a little
	t.SetMode(big.AwayFromZero)
	t.Set(&b.Val)
	if _, acc := t.Int(&a.Val); acc == big.Exact {
		return 0
	}

	return -1
}
Ejemplo n.º 2
0
Archivo: value.go Proyecto: 2thetop/go
// ToInt converts x to an Int value if x is representable as an Int.
// Otherwise it returns an Unknown.
func ToInt(x Value) Value {
	switch x := x.(type) {
	case int64Val, intVal:
		return x

	case ratVal:
		if x.val.IsInt() {
			return makeInt(x.val.Num())
		}

	case floatVal:
		// avoid creation of huge integers
		// (Existing tests require permitting exponents of at least 1024;
		// allow any value that would also be permissible as a fraction.)
		if smallRat(x.val) {
			i := newInt()
			if _, acc := x.val.Int(i); acc == big.Exact {
				return makeInt(i)
			}

			// If we can get an integer by rounding up or down,
			// assume x is not an integer because of rounding
			// errors in prior computations.

			const delta = 4 // a small number of bits > 0
			var t big.Float
			t.SetPrec(prec - delta)

			// try rounding down a little
			t.SetMode(big.ToZero)
			t.Set(x.val)
			if _, acc := t.Int(i); acc == big.Exact {
				return makeInt(i)
			}

			// try rounding up a little
			t.SetMode(big.AwayFromZero)
			t.Set(x.val)
			if _, acc := t.Int(i); acc == big.Exact {
				return makeInt(i)
			}
		}

	case complexVal:
		if re := ToFloat(x); re.Kind() == Float {
			return ToInt(re)
		}
	}

	return unknownVal{}
}