Sunday, July 16, 2017

Literals

In the last section, we took a brief look at assignment statements, which are used to associate a value with a variable. An example of this is:

double pi = 3.14159;

which assigns the value 3.14159 to the variable pi. This variable could be used in further calculations and expressions such as:

double radius = 2.5;
double circumference = 2 * pi * radius;

But before we get into all of the interesting things we can do with expressions, let's take a look at literals, which were used in the last section, but not fully explained.

Literals are numeric, boolean, character, and string values that are expressed directly in a program. In the example above, the value 3.14159 is the literal that is assigned to pi, and 2.5 is the literal that is assigned to radius. In the last line double circumference = 2 * pi * radius, there is only one literal. The values from pi and radius get substituted with their actual values when the program is run, and 2 is the only literal. We could just as easily have written double circumference = 2 * 3.14159 * 2.5, which has three literal values. But it would be difficult for others to understand where those numbers were coming from. For that reason, it's usually not a good idea to have lots of literals in the program. Sometimes people refer to those as "magic numbers" and say that we should avoid using too many magic numbers.

It's also possible to represent integer literals using octal (base 8) and hexadecimal (base 16) notation. Since 8 and 16 are powers of 2, it's easy to see the bit structure in octal and decimal numbers. This can be useful when writing certain types of programs, but using the standard (base 10) notation is preferred in most cases, since it's easier for people to read and understand. To represent a number using octal, the first digit most be a 0 and the other digits must be 0-7. To represent a number using hexadecimal, you must use a leading 0x, followed by 0-9 or A-F for the rest of the digits. The letters x and A-F are not case sensitive, so 0X4Bc1 would be legal. Here are some examples:

int diskBlockSize = 02000; //1024
int diskBlockSize = 08000; //error, all digits must be 0-7, 8 is not allowed in octal
int diskBlockSize = 0x400; //1024
int diskBlockSize = 0X400; //1024, capital X is also allowed
int diskBlockSize = 0x40G; //error, all digits must be 0-9 or A-F. G is not allowed in hexadecimal
int magicNumber = 0xA43B; //42023 (10 * 16^3 + 4 * 16^2 + 3 * 16 + 11 * 1)

Don't worry if you're not familiar with converting between octal and decimal numbers, or hexadecimal and decimal. These notations aren't used too often, and there are many octal and hexadecimal calculators/converters available online.

Boolean literals are pretty straightforward. A boolean literal is either the value true or false. No other values are allowed. For example, boolean isRaining = 0; would result in an error, since 0 is an integer literal and cannot be assigned to a boolean variable.

A character literal is a single letter inside of single quotes ''. More specifically, any Unicode character can be used as a character literal. Unicode is a way of representing text across a variety of languages and formats. It includes digits, letters, foreign characters, and math symbols, among other things. Unicode will be discussed in more detail in a later post. Non-printable characters can be entered using an escape sequence. An escape sequence consists of a backslash \ followed by a character, which indicates that the character should not be taken literally. For example, you cannot use the enter key to represent a newline character, it must be represented by the '\n' escape sequence. Similarly, the tab character can be represented using the '\t' escape sequence, although it is legal to use the tab key directly since the literal is still on one line. However, it's good practice to use the escape sequence so it's easy for others to see what the character is. Here are some examples of character literals being used:

char letter = 'b';
char digit = '0'; //Since the 0 is in single quotes, it is a character and not a number
char chineseLetter = '丧';
char greekLetter = 'φ';
char integralSign = '∫';
char tabCharacter = '\t';
char tabCharacter = ' '; //Legal, but not recommended. It's difficult to see what key was used to create the white space.
char newLineCharacter = '
'; //error, newlines are a non-printable character and need to be represented using '\n'
char newlineCharacter = '\n';

Floating-point literals consist of a decimal value with a fractional component, as discussed in the previous post. But there is another way of representing floating-point literals using scientific notation. This is done by adding an e (or E) at the end of the number, followed by a positive or negative number, indicating the power of 10 to multiply the numeric part by. As before, float types are represented using a f or F at the end. It's not necessary to do this for doubles, but an optional d or D can be added to the end. This is because floating-point literals default to double precision. Here are some examples:

double milesInLightYear = 5.879e+12;
double milesInLightYear = 5.879E12; //Legal, E can be both uppercase or lowercase. The + sign is not required for positive exponents
float milesInLightYear = 5.879e+12; //Error, floating types must end in f or F
float milesInLightYear = 5.879e+12F; //Legal
double electronChargeInCoulombs = 1.602e-19;
double electronChargeInCoulombs = 1.602-19; //Mistake, the e was left out, so this will result in 1.602 - 19 = -17.398 instead of 1.602e-19

The last type of literals are string literals. Strings are not a primitive type in Java, and haven't been discussed up to this point. A string consists of a sequence of characters between double quotes "". They can use the same escape sequences as characters. Whereas a character consists of a single letter, a string can contain many characters, making it more powerful. However, Strings are implemented as objects in Java, and have a few gotchas/edge cases. Strings are interesting enough to deserve a separate post later on. For now, here are some examples of String literals:

String name = "Bob";
String carModel = "Ford Escape";
String chineseCharacters = "丹东乸了伩";
String multiLineSentence = "Silence\nis\ngolden.";

Now that we understand all of the different types of literals, it's time to combine them to form powerful expressions using operators.