1// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package math
6
7// Ldexp is the inverse of Frexp.
8// It returns frac × 2**exp.
9//
10// Special cases are:
11//	Ldexp(±0, exp) = ±0
12//	Ldexp(±Inf, exp) = ±Inf
13//	Ldexp(NaN, exp) = NaN
14
15//extern ldexp
16func libc_ldexp(float64, int32) float64
17
18func Ldexp(frac float64, exp int) float64 {
19	if exp > MaxInt32 {
20		exp = MaxInt32
21	} else if exp < MinInt32 {
22		exp = MinInt32
23	}
24	r := libc_ldexp(frac, int32(exp))
25	return r
26}
27
28func ldexp(frac float64, exp int) float64 {
29	// special cases
30	switch {
31	case frac == 0:
32		return frac // correctly return -0
33	case IsInf(frac, 0) || IsNaN(frac):
34		return frac
35	}
36	frac, e := normalize(frac)
37	exp += e
38	x := Float64bits(frac)
39	exp += int(x>>shift)&mask - bias
40	if exp < -1074 {
41		return Copysign(0, frac) // underflow
42	}
43	if exp > 1023 { // overflow
44		if frac < 0 {
45			return Inf(-1)
46		}
47		return Inf(1)
48	}
49	var m float64 = 1
50	if exp < -1022 { // denormal
51		exp += 52
52		m = 1.0 / (1 << 52) // 2**-52
53	}
54	x &^= mask << shift
55	x |= uint64(exp+bias) << shift
56	return m * Float64frombits(x)
57}
58