This is the 10th day of my participation in the August More Text Challenge

Basic Data Types (1)

While the underlying computer is, of course, all bits, actual operations are based on values in fixed-size cells called words, which can be interpreted as integers, floating-point numbers, bitsets or memory addresses to form larger aggregates representing packets, pixels, files and much more. Go has broad data types and is organized in a variety of ways, matching hardware features downward and programmers’ needs upward, making it easy to represent complex data structures

Go data types fall into four categories: Basic type, Aggregate Type, Reference type, and interface type. Basic types include: number, string, and Boolen. Aggregate types include arrays and structs — more complex data types obtained by combining various simple types. A reference is a large category that includes many different types, such as pointer, slice, map, function, and channel

The integer

Go has both signed and unsigned integers. The signed integer is divided into four sizes: 8-bit, 16-bit, 32-bit and 64-bit. It is represented by int8, INT16, int32 and int64. The corresponding unsigned integers are uint8, Uint16, unint332 and uint64

There are also two types of int and uint. On a particular platform, the size is the same as the native signed integer \ unsigned integer, or equal to the most efficient value on that platform. Int is by far the most widely used numeric type. Both types are of equal size and are either 32-bit or 64-bit, but you can’t assume that they are necessarily 32-bit or 64-bit; Even on the same hardware platform, different compilers may choose different sizes

The rune type is a synonym for int32 and is often used to indicate that a value is a Unicode code point (this article is strongly recommended if you are not familiar with Unicode code points). The two names are used interchangeably. Similarly, the byte type is a synonym for the uint8 type, emphasizing that a value is raw data, not a quantum value

Finally, there is an unsigned integer uintptr that is undefined in size but large enough to hold the pointer in its entirety. The Uintptr type is used only for low-level programming, such as in Go programs that interface with C libraries or operating systems

Int, uint, and uintptr are all distinct types from similar types whose sizes are explicit. That is, int and int32 are different types, even though int is naturally 32 bits in size and an int value must be explicitly converted to be used as int32. And vice versa

The signed integer is represented by the complement, and the highest bit is reserved as the sign bit. The value of the n bit ranges from -2^(n-1) to 2^(n-1)-1. The unsigned integer consists of all bits and is non-negative, ranging from 0 to 2^n – 1. For example, int8 can be taken from -128 to 127 and unit8 from 0 to 255

Binary operator

The binary operators of Go cover arithmetic, logic, and comparison operations. In descending order of priority:

* / % < < > > && ^ + - | ^ = =! = < < = > > = && | | other operators follow do associative law at the same levelCopy the code

The arithmetic operators +, -, *, and/can be applied to integers, floating-point numbers, and complex numbers, while the modular operator % can only be applied to integers. The behavior of the modulo operator % varies by programming language. For Go, the plus or minus sign of the modulus remainder is always the same as the dividend, so -5 percent 3 and -5 percent -3 both get -2. The behavior of the division operation depends on whether the operands are all integers. If the integers are divided, the decimal part is discarded, so 5.0/4.0 gives 1.25, and 5/4 gives 1

When the number of bits needed to represent the result of an arithmetic operation, whether signed or unsigned, is outside the range of the type, it is called an overflow. The high portion of the overflow is discarded without prompting. If the original calculation result is signed, and the leftmost bit is 1, it will form a negative value, take INT8 as an example:

var u uint8 =255
fmt. Println(u, u+1, u*u) // 255   0   1 

var i int8 =127
fmt. Println(i, i+1, i*i) //127   -128   1
Copy the code

An operator

Go also has the following bitwise operators. The first four operations on operands are bitwise independent and do not involve arithmetic carries or signs

& bit operations AND | a operation OR ^ bit operations XOR & ^ bit operations (AND NOT) < < left > > moves to the rightCopy the code

As a binary operator, the operator ^ represents bitwise XOR; When used as a unary prefix operator, it represents bitwise inversion or bitwise complement, resulting in bitwise inversion of operands. The &^ operator is bitwise clear (AND NOT) : in the expression z = x &, if one of y is 1, then the corresponding bit of z is 0

Var uint8 x = 1 < < | 1 < < 5 var uint8 y = 1 < < | 1 < < 2 FMT) Printf (" % 08 b \ n ", x) / / 00100010 set {1, 5} FMT. Printf (" % 08 b \ n ", y) / / 00000110 set {1, 2} FMT) Printf (" % 08 b \ n ", x&y) / / 00000010 intersection {1} FMT) Printf (" % 08 b \ n ", X | y) / / 00100110 and the set {1, 2, 5} FMT) Printf (" % 08 b \ n ", x ^ y) / / 00100100 symmetric difference {2, 5} FMT) Printf (" % 08 b \ n ", // uint1 = 1) // uint1 = 1 i < 8; i++ { if x&(1<<i) ! Println(I) //"1", "5"}} FMT. Printf (" % 08 b \ n ", x < < 1) / / 01000100 set {2, 6} FMT) Printf (" % 08 b \ n ", x > > 1) / / 00010001 set {0, 4}Copy the code

In the shift operations x << n and x >> n, the operand n determines the amount of displacement and n must be unsigned. The operand x can be either signed or unsigned. Arithmetically, the left shift operation x << n is equivalent to x times 2 to the n; And the right shift x >> n is the same thing as x over 2 to the n, rounded down. A left shift fills the right space with 0, and a right shift of an unsigned integer fills the left space with 0, but a right shift of a signed number fills the space with the value of the signed bit. Therefore, note that unsigned integers must be used if integers are processed in bitwise mode

An explicit conversion is usually required to convert one data type to another. For arithmetic and logical binary operators, the type of operation must be the same

Var apples int32 = 1 var oranges int16 = 2 var apples = apple + orangesCopy the code

Floating point Numbers

Go has floating-point numbers of two sizes, FLOAT32 and float64. Its arithmetic features comply with IEEE 754 standard. The values of these two types can range from extremely small to extremely large. The Math package gives the limits of floating point values. The constant math. MaxFloat32 is the maximum value of float32, which is about 3. 4e38, while math. MaxFloat64 is about 1.8e308. Correspondingly, the smallest positive floating-point values are about 1.4E-45 and 4.9E-324

In decimal, the number of valid digits in Float32 is about 6 and that in Float64 is about 15. In most cases, preference should be given to float64, because unless care is taken, errors can quickly accumulate in float32. And there is a limited range of positive integers that Float32 can accurately represent:

var f float32 = 16777216 // 1 << 24
fmt.Println(f == f+1) // true
Copy the code

Floating point numbers can be written as decimals in the source code

Const e = 2.71828// approximationCopy the code

Very small or very large numbers are best represented using scientific notation, in which the letter E or E is written before the order of magnitude exponent

Const Avogadro = 6.02214129e23 const Planck = 6.62606957E-34Copy the code

Floating-point values can be conveniently printed using Printf’s %g predicate, which automatically maintains sufficient precision (see formatting output here) and selects the most concise representation. For tables, however, the form %e (with indices) or %f (without indices) is more appropriate, and all three predicates control output width and numeric precision

for x:=0; x < 8; X++ {FMT. Printf (" x = % d e ^ x = % 8.3 f \ n ", x, math. J Exp (float64 (x)))} output: X = 0 e^x = 1.000 x = 1 e^x = 2.718 x = 2 e^x = 7.389 x = 3 e^x = 20.086 x = 4 e^x = 54.598 x = 5 e^x = 148.413 x = 6 E ^x is equal to 403.429 x is equal to 7 e^x is equal to 1096.633Copy the code

In addition to a number of common mathematical functions, the Math package has functions for creating and determining special values defined by the IEEE 754 standard: positive and negative infinity, which represent numbers beyond the maximum allowable value and the quotient divided by zero; And NaN(Not a Number), which represents the result of a mathematically meaningless operation (such as 0/0 or Sqrt(-i))

var z float64
fmt.Println(z,-z, 1/z, -1/z, z/z) // 0 -0 +Inf -Inf NaN
Copy the code

The math.IsNaN function determines whether its argument is non-numeric, and the Math. NaN function returns non-numeric (NaN). In numerical operations, we tend to treat NaN as a sentinel value, but directly determining whether a specific computed result is a NaN can lead to potential errors because comparisons to NaN are always false (except! =, which is always the opposite of ==) :

nan := math.NaN()
fmt.Println(nan == nan, nan < nan, nan > nan) // false false false
Copy the code

The plural

I think you learned about complex numbers in high school math, but here’s a quick look at what a complex number is in math. The first thing we know is that we usually treat any point on the X-axis as a real number (integer or floating point), whereas complex numbers are not just numbers on the X-axis, but numbers in two dimensions

What can achieve, very key point is provision

I = square root of minus 1Copy the code

The square root of minus one we know doesn’t exist, it’s a real number that doesn’t exist, and then we have an imaginary number called I, which is equal to the square root of minus one. So 3 plus 4i, 3 is the real part of this complex number, and 4 is the imaginary part of this complex number. So what’s 3 plus 4i?

So it’s going to look like this. You go 3 along the number line of the real number, and then you go up 4. The length of the yellow slash here is 5. How did you figure that out?

| | I = 3 + 4) 4 ^ 2 + 3) ^ 2 = 5Copy the code

Using absolute value notation, which is usually called the magnitude, the magnitude of 3 plus 4i is equal to 3 squared plus the square root of 4 squared, so you get 5. I also has some other properties, as follows

I ^2 = -1, I ^3 = -1, I ^4 = 1...... So every time you multiply by one more I, you're going 90 degrees counterclockwiseCopy the code

Go has two complex64 and complexl28 sizes, which consist of float32 and float64, respectively. The built-in complex function creates complex numbers from the given real and imaginary parts, while the built-in real and imag functions extract the real and imaginary parts of complex numbers, respectively

var x complexl28 = complex(1, 2) // 1+2i
var y complexl28 = complex(3, 4) // 3+4i
fmt.Println(x*y) // -5+10i
fmt.PrintIn(real(x*y)) // -5
fmt.PrintIn(imag(x*y)) // 10
Copy the code

In the source code, if you write the letter I immediately after a floating point or decimal integer, such as 3.141592 I or 2i, it becomes an imaginary number, representing a complex number with a real part of 0

Println(1i * 1i) // "(-1+0i)", I ² = -1Copy the code

According to the constant operation rules, complex constants can be added to other constants (integer or floating point, real or imaginary), which allows us to write complex numbers naturally, such as 1+2i, or equivalents, 2i+1. The previous declarations of x and y can be abbreviated as:

x := 1 + 2i 
y := 3 + 4i
Copy the code

You can use == or! = Determine whether complex numbers are equivalent. Two complex numbers are equal if their real and imaginary parts are equal. The Math/CMPLX package provides library functions for complex number operations, such as the square root function for complex numbers and the curtain function for complex numbers

fmt.Printin(cmplx.Sqrt(-1)) // "(0+1i)
Copy the code

Boolean value

There are only two possibilities for a bool or Boolean: true and false. Conditions in if and for statements are Booleans, and comparison operators such as == and < also yield Booleans. Unary operator (!) Represents the logic take inverse, therefore! True is false, or you can say (! True = = = = true or false). For example, given the code style, the Boolean expression x==true is verbose and we always simplify to x

By Boolean operators && (AND) AND | | (0 r) combination operation, this could cause a short-circuit behavior: if the operator to the left of the operands have can directly determine the overall result, then the right operand will not count, the following expression is safe

s ! = "" && s[0] == 'x' where s[0] will trigger a downtime exception if applied to an empty stringCopy the code

Because am& has higher precedence than II (mnemonic tip: am& represents logical multiplication and II represents logical addition), parentheses are not required for conditions of the following form

If 'a' < c & c < 'z' | | 'a' < c & c < 'z' | | '0' < c & c < '9' {/ / ASCII letters or Numbers}Copy the code

Booleans cannot be converted implicitly to numeric values (such as 0 or 1) or vice versa. Explicit if is necessary in the following situations

I := 0 if b {I = 1} func btoi(b bool) int {if b {return 1} return 0}Copy the code

reference

The Go Programming Language — Alan A. A. Donovan

Go Language Learning Notes — Rain Marks