B. En cuanto al llamado texto espectacular se observan también algunos aspectos que definen la especificidad del teatro infantil y
1. El nacimiento de la conciencia literaria en el teatro infantil (1910-1936)
Go provides two types of floating-point numbers and two types of complex numbers—their names and ranges are shown in Table 2.7. Floating-point numbers in Go are held in the widely used IEEE-754 format ( http://en.wiki-pedia.org/wiki/IEEE_754-2008). This format is also the native format used by many microprocessors and floating-point units, so in most cases Go is able to take direct advantage of the hardware’s floating-point support.
Table 2.7 Go’s Floating-Point Types
Type Range
float32 ±3.402823466 385 288 598 117 041 834 845 169 254 40×1038 The mantissa is reliably accurate to about 7 decimal places.
float64 ±1.797693134 862315708 145 274 237 317 043 567 981×10308 The mantissa is reliably accurate to about 15 decimal places.
complex64 The real and imaginary parts are both of typefloat32. complex128 The real and imaginary parts are both of typefloat64.
Go floating-point numbers support all the arithmetic operations listed in Table 2.4 (59 ➤ ). Most of themathpackage’s constants and all of its functions are listed in Tables 2.8 to 2.10 (➤ 65–67).
Floating-point numbers are written with a decimal point, or using exponential notation, for example, 0.0, 3., 8.2,−7.4, −6e4, .1, 5.9E−3. Computers commonly represent floating-point numbers internally using base 2—this means that some decimals can be represented exactly (such as 0.5), but others only approximately (such as 0.1 and 0.2). Furthermore, the representation uses a fixed number of bits, so there is a limit to the number of digits that can be held. This is not a Go-specific problem, but one that afflicts floating-point numbers in all mainstream programming languages. However, the imprecision isn’t always apparent, be-cause Go uses a smart algorithm for outputting floating-point numbers that uses the fewest possible digits consistent with maintaining accuracy.
ptg7913109 Table 2.8 The Math Package’s Constants and Functions #1
All themathpackage’s functions accept and returnfloat64s unless specified otherwise. All the constants are shown truncated to 15 decimal digits to fit neatly into the tables.
Syntax Description/result
math.Abs(x) |x|, i.e., the absolute value of x math.Acos(x) The arc cosine of xin radians
math.Acosh(x) The arc hyperbolic cosine of xin radians math.Asin(x) The arc sine of xin radians
math.Asinh(x) The arc hyperbolic sine of xin radians math.Atan(x) The arc tangent of xin radians math.Atan2(y, x) The arc tangent of yxin radians
math.Atanh(x) The arc hyperbolic tangent ofxin radians math.Cbrt(x) 3
√
x, the cube root of xmath.Ceil(x) ⎡x⎤ , i.e., the smallest integer greater than or equal tox; e.g.,math.Ceil(5.4) == 6.0
math.Copysign(x, y) A value withx’s magnitude andy’s sign math.Cos(x) The cosine ofxin radians
math.Cosh(x) The hyperbolic cosine of xin radians math.Dim(x, y) In effect,math.Max(x - y, 0.0)
math.E The constant e; approximately 2.718 281 828 459 045 math.Erf(x) erf(x);x’s Gauss error function
math.Erfc(x) erfc(x);x’s complementary Gauss error function math.Exp(x) ex
math.Exp2(x) 2x math.Expm1(x)
ex− 1; this is more accurate than usingmath.Exp(x) - 1 whenxis close to 0
math.Float32bits(f) The IEEE-754 binary representation of f(of type float32) as auint32
math.
Float32frombits(u)
Thefloat32represented by the IEEE-754 bits inu(of typeuint32)
math.Float64bits(x) The IEEE-754 binary representation of x(of type float64) as auint64
math.
Float64frombits(u)
Thefloat64represented by the IEEE-754 bits inu(of typeuint64)
ptg7913109 Table 2.9 The Math Package’s Constants and Functions #2
Syntax Description/result
math.Floor(x) ⎣x⎦ , i.e., the largest integer less than or equal tox; e.g., math.Floor(5.4) == 5.0
math.Frexp(x) fracof typefloat64andexpof typeintsuch that x= frac× 2 ; the inverse function isexp math.Ldexp() math.Gamma(x) Γ(x), i.e., (x − 1)!
math.Hypot(x, y) math.Sqrt(x * x, y * y)
math.Ilogb(x) The binary exponent ofxas anint; see alsomath.Logb() math.Inf(n) Afloat64of value+∞ ifnof typeintis ≥ 0; otherwise −∞
math.IsInf(x, n)
trueifxof typefloat64is+∞ andnof typeintis > 0, or ifxis−∞ andnis < 0, or ifxis either infinity andnis 0;
otherwisefalse
math.IsNaN(x) trueifxhas the IEEE-754 “not a number” value math.J0(x) J0(x), the Bessel function of the first kind math.J1(x) J1(x), the Bessel function of the first kind
math.Jn(n, x) Jn(x), the order-n(wherenis of typeint) Bessel function of the first kind
math.Ldexp(x, n)
x× 2 wheren xis of typefloat64andnis of typeint; the inverse function ismath.Frexp()
math.Lgamma(x) loge(Γ(x)) as afloat64and the sign ofΓ(x) as anint(−1 or+1)
math.Ln2 loge(2); approximately 0.693147 180 559 945 math.Ln10 loge(10); approximately 2.302585092994 045 math.Log(x) loge(x)
math.Log2E log1
e(2); approximately 1.442 695 021 629 333 math.Log10(x) log10(x)
math.Log10E log1
e(10); approximately 0.434 294 492 006 301
math.Log1p(x) loge(1 + x) but is more accurate than usingmath.Log()when xis near zero
math.Log2(x) log2(x)
math.Logb(x) The binary exponent ofx; see alsomath.Ilogb() math.Max(x, y) The larger of xandy
math.Min(x, y) The smaller ofxandy
math.Mod(x, y) The remainder ofxy; see alsomath.Remainder()
ptg7913109 Table 2.10 The Math Package’s Constants and Functions #3
Syntax Description/result
math.Modf(x) The whole and fractional parts of xasfloat64s math.NaN(x) An IEEE-754 “not a number” value
math.Nextafter(
x, y) The next representable value afterxgoing towardy math.Pi The constantπ; approximately 3.141592653589 793 math.Phi The constantφ; approximately 1.618 033988 749 984 math.Pow(x, y) xy
math.Pow10(n) 10 as an float64;nis of typeint math.Remainder(
x, y) the IEEE-754-compliant remainder ofxy; see alsomath.Mod() math.Signbit(x) Returns abool;trueifxis negative (including−0.0)
math.Sin(x) The sine ofxin radians
math.SinCos(x) The sine and cosine of xin radians math.Sinh(x) The hyperbolic sine ofxin radians math.Sqrt(x)
√
xmath.Sqrt2
√
2; approximately 1.414 213 562 373 095 math.SqrtE√
e; approximately 1.648 721 270 700 128 math.SqrtPi√
π; approximately 1.772453850 905516 math.SqrtPhi√
φ; approximately 1.272019 649 514 068 math.Tan(x) The tangent of xin radiansmath.Tanh(x) The hyperbolic tangent of xin radians math.Trunc(x) xwith its fractional part set to 0
math.Y0(x) Y0(x), the Bessel function of the second kind math.Y1(x) Y1(x), the Bessel function of the second kind
math.Yn(n, x) Yn(x), the order-n(wherenis of typeint) Bessel function of the second kind
ptg7913109 All the comparison operations listed in Table 2.3 (57 ➤ ) can be used with
floating-point numbers. Unfortunately, due to the fact that floating-point num-bers are held as approximations, comparing them for equality or inequality does not always work intuitively.
x, y := 0.0, 0.0
for i := 0; i < 10; i++ { x += 0.1
if i%2 == 0 { y += 0.2 } else {
fmt.Printf("%-5t %-5t %-5t %-5t", x == y,
EqualFloat(x, y, -1), EqualFloat(x, y, 0.000000000001), EqualFloatPrec(x, y, 6))
fmt.Println(x, y) }
}
true true true true 0.2 0.2 true true true true 0.4 0.4
false false true true 0.6 0.6000000000000001 false false true true 0.7999999999999999 0.8 false false true true 0.9999999999999999 1
Here we start with twofloat64s with initial values of 0. We add ten 0.1s to the first one and five 0.2s to the second, so at the end both should be 1. However, as the output shown below the code snippet illustrates, perfect accuracy for some floating-point numbers is not possible. In view of this we must be very careful when comparing floating-point numbers for equality or inequality using ==
and!=. Of course, there are cases where it is sensible to compare floating-point numbers for equality or inequality using the built-in operators—for example, when trying to avoid division by zero, as in, say,if y != 0.0 { return x / y }. The "%-5t" format prints a bool left-aligned in a field five characters wide—
string formatting is covered in the next chapter; §3.5,➤ 93.
func EqualFloat(x, y, limit float64) bool { if limit <= 0.0 {
limit = math.SmallestNonzeroFloat64 }
return math.Abs(x-y) <=
(limit * math.Min(math.Abs(x), math.Abs(y))) }
TheEqualFloat() function compares twofloat64s to the given accuracy—or to the greatest accuracy the machine can achieve if a negative number (e.g.,-1)
ptg7913109 is passed as the limit. It relies on functions (and a constant) from the standard
library’smathpackage.
An alternative (and slower) approach is to compare numbers as strings.
func EqualFloatPrec(x, y float64, decimals int) bool { a := fmt.Sprintf("%.*f", decimals, x)
b := fmt.Sprintf("%.*f", decimals, y) return len(a) == len(b) && a == b }
For this function the accuracy is specified as the number of digits after the dec-imal point. Thefmt.Sprintf()function’s%formatting argument can accept a* placeholder where it expects a number, so here we create two strings based on the two given float64s, formatting each with the specified number of decimal places. If the magnitudes of the numbers differ, then so will the lengths of the aandb strings (e.g., 12.32 vs. 592.85), which gives us a relatively fast short-cir-cuiting equality test. (String formatting is covered in §3.5,➤ 93.)
In most cases where floating-point numbers are needed the float64 type is the best choice—especially since all the functions in themathpackage work in terms of float64s. However, Go also provides the float32 type which may be useful when memory is at a premium and we either don’t need to use themath package, or are willing to put up with the minor inconvenience of converting to and fromfloat64s when necessary. Since Go’s floating-point types are sized it is always safe to read or write them from or to external sources such as files or network connections.
Floating-point numbers can be converted to integers using the standard Go syntax (e.g.,int(float)), in which case the fractional part is simply discarded.
Of course, if the floating-point value exceeds the range of the integer type converted to, the resultant integer will have an unpredictable value. We can address this problem using a safe conversion function. For example:
func IntFromFloat64(x float64) int {
if math.MinInt32 <= x && x <= math.MaxInt32 { whole, fraction := math.Modf(x)
if fraction >= 0.5 { whole++
}
return int(whole) }
panic(fmt.Sprintf("%g is out of the int32 range", x)) }
The Go Specification (golang.org/doc/go_spec.html) states that anint occupies the same number of bits as auintand that auintis always 32 or 64 bits. This
ptg7913109 implies that anintis at least 32 bits which means that we can safely use the
math.MinInt32andmath.MaxInt32constants as theintrange.
We use themath.Modf()function to separate the whole and fractional parts of the given number (both asfloat64s), and rather than simply returning the whole part (i.e., truncating), we perform a very simple rounding if the fractional part is ≥ 0.5.
Rather than return anerror as we did for our customUint8FromInt()function (58 ➤ ), we have chosen to treat out-of-range values as important enough to stop the program, so we have used the built-inpanic()function which will cause a runtime panic and stop the program unless the panic is caught by a recover() call (§5.5,➤ 212). This means that if the program runs successfully we know that no out-of-range conversions were attempted. (Notice also that the function does not end with areturnstatement; the Go compiler is smart enough to realize that a call topanic()means that a normal return cannot occur at that point.)
2.3.2.1. Complex Types
The two complex types supported by Go are shown in Table 2.7 (64 ➤ ). Complex numbers can be created using the built-in complex() function or by using constant literals involving imaginary numbers. Complex numbers’ components can be retrieved using the built-inreal()andimag() functions, both of which return afloat64(or afloat32forcomplex64s).
Complex numbers support all the arithmetic operations listed in Table 2.4 (59 ➤ ). The only comparison operators that can be used with complex numbers are==and!=(see Table 2.3, 57 ➤ ), but these suffer from the same issues as they do when comparing floating-point numbers. The standard library has a complex number-specific package,math/cmplx, whose functions are listed in Table 2.11.
Here are some simple examples:
f := 3.2e5 // type: float64
x := -7.3 - 8.9i // type: complex128 (literal) y := complex64(-18.3 + 8.9i) // type: complex64 (conversion) ➊
z := complex(f, 13.2) // type: complex128 (construction) ➋
fmt.Println(x, real(y), imag(z)) // Prints: (-7.3-8.9i) -18.3 13.2
Go signifies imaginary numbers using the suffixias used in pure mathemat-ics.★ Here, the numbersxandzare of typecomplex128, so their real and imag-inary parts are of typefloat64;yis of typecomplex64 so its components are of typefloat32. One subtle point to notice is that using thecomplex64type name (or any other built-in type name for that matter) as a function performs a type conversion. So here (➊), the complex number-18.3+8.9i(of typecomplex128—the
★By contrast, in engineering and in Python, imaginary numbers are indicated using j.
ptg7913109 Table 2.11 The Complex Math Package’s Functions
Import"math/cmplx". All the functions accept and returncomplex128s unless specified oth-erwise.
Syntax Description/result
cmplx.Abs(x) |x|, i.e., the absolute value of xas afloat64 cmplx.Acos(x) The arc cosine ofxin radians
cmplx.Acosh(x) The arc hyperbolic cosine of xin radians cmplx.Asin(x) The arc sine ofxin radians
cmplx.Asinh(x) The arc hyperbolic sine of xin radians cmplx.Atan(x) The arc tangent of xin radians
cmplx.Atanh(x) The arc hyperbolic tangent ofxin radians cmplx.Conj(x) The complex conjugate ofx
cmplx.Cos(x) The cosine ofxin radians
cmplx.Cosh(x) The hyperbolic cosine of xin radians cmplx.Cot(x) The cotangent of xin radians cmplx.Exp(x) ex
cmplx.Inf() complex(math.Inf(1), math.Inf(1))
cmplx.IsInf(x) trueifreal(x)orimag(x)is±∞; otherwisefalse
cmplx.IsNaN(x) trueifreal(x)orimag(x)is “not a number” and if neither is
±∞; otherwisefalse cmplx.Log(x) loge(x)
cmplx.Log10(x) log10(x)
cmplx.NaN() A complex “not a number” value
cmplx.Phase(x) The phase ofxas afloat64in the range[−π, +π]
cmplx.Polar(x) The absolute value r and phaseθ both of typefloat64, satisfying x=r× e ; phase is in the range [−π, +π]θi cmplx.Pow(x, y) xy
cmplx.Rect(r, θ) Acomplex128with polar coordinatesrandθboth of type float64
cmplx.Sin(x) The sine ofxin radians
cmplx.Sinh(x) The hyperbolic sine ofxin radians cmplx.Sqrt(x)
√
xcmplx.Tan(x) The tangent of xin radians
cmplx.Tanh(x) The hyperbolic tangent of xin radians
ptg7913109 inferred complex type for complex literals) is converted to acomplex64. However,
complex()is a function (there is no type of that name) that takes two floats and returns the correspondingcomplex128(70 ➤ , ➋).
Another subtle point is that the fmt.Println() function can print complex numbers without formality. (As we will see in Chapter 6 we can make our own types seamlessly cooperate with Go’s print functions simply by providing them with aString()method.)
In general the best complex type to use iscomplex128 since all the functions in themath/cmplxpackage work in terms ofcomplex128s. However, Go also provides thecomplex64type which may be useful when memory is very tight. Since Go’s complex types are sized it is always safe to read or write them from or to external sources such as files or network connections.
In this chapter we have looked at Go’s Boolean and numeric types and presented tables showing the operators and functions that are available to query and manipulate them. The next chapter covers Go’sstringtype, including thorough coverage of Go’s print formatting functionality (§3.5,➤ 93), which includes, of course, the printing of Booleans and numbers formatted as we want. We will see how to read and write Go data types—including Booleans and numbers—from and to files in Chapter 8. Before closing this chapter, though, we will review a small but complete working example program.