Operators and Expressions in D
D inherits most of C's operator set -- arithmetic, comparison, logical, and bitwise operators all behave much as a C or Java programmer would expect -- but adds a few operators unique to D's design, including ^^ for exponentiation, the .. range operator for slicing and iteration, and the is operator for compile-time-flavored identity and type checks. Understanding which operators work on values versus types versus ranges is essential before writing anything beyond the simplest expressions.
Cricket analogy: Like a bowler who has the standard set of deliveries, yorker, bouncer, off-cutter, every fast bowler knows, plus a signature variation like a unique release point, D has the familiar C-style operators plus signature extras like ^^ and ...
Arithmetic and Assignment Operators
D's arithmetic operators are + - * / % for addition, subtraction, multiplication, division, and modulo, plus ^^ for exponentiation (so 2 ^^ 10 is 1024, unlike C which has no power operator). Every arithmetic operator has a compound-assignment form -- += -= *= /= %= ^^= -- that both computes and reassigns in one step, and integer division between two integer operands truncates toward zero (7 / 2 is 3, not 3.5), a common source of bugs for programmers coming from Python 3, where / always produces a float.
Cricket analogy: Like calculating a required run rate where fractional runs don't exist on the scoreboard, 7 runs needed off 2 balls still displays as a whole number, D's integer division truncates 7 / 2 to 3, dropping the fractional part just like a scoreboard drops fractional runs.
import std.stdio;
void main() {
int a = 7, b = 2;
writeln(a / b); // 3 -- integer division truncates toward zero
writeln(a % b); // 1 -- remainder
writeln(2 ^^ 10); // 1024 -- exponentiation operator
int total = 10;
total += 5; // compound assignment: total is now 15
total ^^= 2; // total is now 225
double ratio = a / cast(double) b; // 3.5 -- force floating-point division
writeln(ratio);
}
Comparison and Logical Operators
Comparison operators (== != < > <= >=) return a bool, and logical operators &&, ||, and ! combine boolean expressions with short-circuit evaluation -- meaning a() && b() never calls b() if a() returns false, which is useful for guarding against null dereferences or expensive calls. D also provides a ternary conditional operator cond ? a : b, identical to C and Java, for compact conditional expressions without a full if/else block.
Cricket analogy: Like a third umpire who stops reviewing further evidence the instant the first camera angle conclusively shows the batsman is out, &&'s short-circuit evaluation stops checking b() the moment a() is already false, saving unnecessary work.
Special D Operators: is, in, and the Range Operator
The is operator checks identity or compile-time type equivalence -- is(T == int) checks whether a template parameter T is int, which is fundamentally different from ==, which compares runtime values. The in operator tests membership in an associative array and, unlike a boolean-returning in in some languages, returns a pointer to the value if found or null if not (if (auto p = "key" in map) { ... }), while the .. range operator builds a range for slicing (arr[1 .. 3]) or iterating (foreach (i; 0 .. 10)), always exclusive of the upper bound.
Cricket analogy: Like checking whether a specific player's name is on today's team sheet before letting them bat, D's in operator checks associative-array membership and returns a pointer to the entry if found, similar to how the scorer looks up a player's exact stats rather than a plain yes/no.
The .. range operator is exclusive of its upper bound (like Python's range, unlike a mathematical closed interval), so foreach (i; 0 .. 10) iterates i from 0 through 9. Array slicing with .. also does not copy -- arr[1 .. 3] produces a view over the same memory as arr, so mutating an element through the slice mutates the original array too.
- D reuses most of C's arithmetic, comparison, logical, and bitwise operators with familiar semantics.
- ^^ is D's exponentiation operator (2 ^^ 10 == 1024); C has no equivalent built-in operator.
- Every arithmetic operator has a compound-assignment form (+=, -=, ^^=, etc.) that computes and reassigns in one step.
- Integer division truncates toward zero (7 / 2 == 3); cast one operand to double for floating-point division.
- && and || short-circuit, skipping the second operand when the result is already determined by the first.
- The is operator checks compile-time type identity (is(T == int)), fundamentally different from == which compares runtime values.
- The .. range operator is exclusive of its upper bound and is used both for slicing (arr[1 .. 3]) and iteration (foreach (i; 0 .. 10)).
Practice what you learned
1. What does 2 ^^ 10 evaluate to in D?
2. What is the result of 7 / 2 when both operands are int in D?
3. What does the is operator check in D, as opposed to ==?
4. What does the in operator return when checking an associative array for a key that exists?
5. Is D's range operator .. inclusive or exclusive of its upper bound?
Was this page helpful?
You May Also Like
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics