0
0
Kotlinprogramming~15 mins

Number literal formats (underscore, hex, binary) in Kotlin - Deep Dive

Choose your learning style9 modes available
Overview - Number literal formats (underscore, hex, binary)
What is it?
Number literal formats in Kotlin let you write numbers in different ways to make them easier to read or represent. You can use underscores to separate digits for clarity, write numbers in hexadecimal (base 16) or binary (base 2) formats. These formats help you express numbers clearly, especially large ones or those related to computer hardware.
Why it matters
Without these formats, reading and understanding numbers in code can be hard and error-prone, especially for big numbers or those representing bits. Using underscores and different bases makes code clearer and reduces mistakes, making programming faster and less frustrating.
Where it fits
Before learning number literal formats, you should know basic Kotlin syntax and how to write simple numbers. After this, you can learn about number operations, bitwise operations, and how to use numbers in real applications like flags or color codes.
Mental Model
Core Idea
Number literal formats are just different ways to write numbers so humans and computers can understand them better and avoid mistakes.
Think of it like...
It's like writing a phone number with spaces or dashes (123-456-7890) instead of one long string (1234567890) to make it easier to read and remember.
Number Literal Formats in Kotlin

┌───────────────┬───────────────────────────────┐
│ Format        │ Example                       │
├───────────────┼───────────────────────────────┤
│ Decimal       │ 1_000_000                    │
│ Hexadecimal   │ 0xFF_EC_DE_5E                │
│ Binary        │ 0b1101_0101                  │
└───────────────┴───────────────────────────────┘
Build-Up - 7 Steps
1
FoundationBasic decimal numbers with underscores
🤔
Concept: Using underscores in decimal numbers to improve readability.
In Kotlin, you can place underscores (_) between digits in a number to make it easier to read. For example, instead of writing 1000000, you write 1_000_000. The underscores do not affect the value of the number. Example: val million = 1_000_000 println(million) // prints 1000000
Result
The program prints 1000000, showing underscores don't change the number's value.
Understanding that underscores are just visual aids helps you write clearer code without changing how numbers work.
2
FoundationWriting hexadecimal numbers
🤔
Concept: Representing numbers in base 16 using 0x prefix.
Hexadecimal numbers use base 16 and digits 0-9 plus letters A-F. In Kotlin, prefix a number with 0x to write it in hex. Example: val color = 0xFF_EC_DE_5E println(color) // prints decimal equivalent
Result
The program prints 4293713518, the decimal value of the hex number.
Knowing hex lets you work with colors, memory addresses, and flags more naturally.
3
IntermediateUsing binary literals with 0b prefix
🤔
Concept: Writing numbers in base 2 using 0b prefix and underscores.
Binary numbers use only 0 and 1. Kotlin lets you write them with 0b prefix. Example: val bits = 0b1101_0101 println(bits) // prints decimal equivalent
Result
The program prints 213, the decimal value of the binary number.
Binary literals help when working with low-level data like bits and masks.
4
IntermediateCombining underscores with hex and binary
🤔
Concept: Using underscores inside hex and binary literals for clarity.
You can add underscores anywhere between digits in hex and binary numbers. Example: val mask = 0b1111_0000 val address = 0xAB_CD_EF println(mask) // 240 println(address) // 11259375
Result
The program prints 240 and 11259375, showing underscores don't affect values.
This consistency across formats makes reading complex numbers easier.
5
IntermediateLimits on underscore placement
🤔
Concept: Rules about where underscores can and cannot be placed in number literals.
Underscores cannot be at the start or end of a number, next to decimal points, or next to prefixes. Invalid examples: val bad1 = _1000 val bad2 = 1000_ val bad3 = 0x_FF val bad4 = 1._0 These cause compile errors.
Result
Compiler errors if underscores are misplaced.
Knowing these rules prevents syntax errors and confusion.
6
AdvancedHow Kotlin parses number literals internally
🤔Before reading on: do you think underscores are removed before or after parsing the number? Commit to your answer.
Concept: Understanding that underscores are stripped before the number is converted to its value.
When Kotlin reads a number literal with underscores, it first removes all underscores, then parses the remaining digits according to the base (decimal, hex, binary). This means underscores have no effect on the actual value or type. Example: 1_000 is treated as 1000 internally.
Result
The number behaves exactly as if written without underscores.
Knowing this explains why underscores are purely visual and never affect calculations or storage.
7
ExpertUsing number literals in bitwise operations
🤔Before reading on: do you think writing binary literals makes bitwise code easier or just more verbose? Commit to your answer.
Concept: Applying hex and binary literals to write clear bitwise manipulation code.
Bitwise operations work on bits. Writing masks and flags in binary or hex with underscores makes the code self-explanatory. Example: val flag = 0b0000_1000 val mask = 0xFF_FF_00_00 Using these literals helps you see which bits are set or cleared at a glance.
Result
Code is easier to read and less error-prone when dealing with bits.
Understanding how literals improve bitwise code clarity helps avoid bugs in low-level programming.
Under the Hood
Kotlin's compiler reads number literals as text. It first removes underscores, then detects the base from prefixes (0x for hex, 0b for binary, none for decimal). It converts the cleaned string into a numeric value stored in memory. Underscores never reach runtime; they are purely compile-time syntax sugar.
Why designed this way?
Underscores were introduced to improve code readability without changing language semantics. Hex and binary literals were added to support common programming needs like bit manipulation and hardware interfacing. The design balances human readability with compiler simplicity by stripping underscores early.
Number Literal Parsing Flow

┌───────────────┐
│ Source Code   │
│ val x = 1_000 │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Remove '_'    │
│ Result: 1000  │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Detect Base   │
│ (decimal)     │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Convert to    │
│ Numeric Value │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Store in      │
│ Memory        │
└───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Do underscores affect the numeric value of a literal? Commit to yes or no.
Common Belief:Underscores change the number's value or how it's stored.
Tap to reveal reality
Reality:Underscores are ignored by the compiler and do not affect the number's value or storage.
Why it matters:Believing underscores change values can cause confusion and bugs when debugging or reading code.
Quick: Can you put underscores anywhere in a number literal, like at the start or end? Commit to yes or no.
Common Belief:You can place underscores anywhere in a number literal.
Tap to reveal reality
Reality:Underscores cannot be at the start, end, next to decimal points, or prefixes; doing so causes errors.
Why it matters:Misplacing underscores leads to syntax errors that can be frustrating for beginners.
Quick: Does Kotlin support octal (base 8) number literals like 0o123? Commit to yes or no.
Common Belief:Kotlin supports octal literals with 0o prefix.
Tap to reveal reality
Reality:Kotlin does not support octal literals; only decimal, hex (0x), and binary (0b) are supported.
Why it matters:Assuming octal support can cause syntax errors and confusion when porting code from other languages.
Quick: Does writing binary literals make bitwise code more verbose and harder to read? Commit to yes or no.
Common Belief:Binary literals make code longer and harder to understand than decimal or hex.
Tap to reveal reality
Reality:Binary literals with underscores often make bitwise code clearer by showing exact bits set or cleared.
Why it matters:Avoiding binary literals can lead to less readable and more error-prone bitwise code.
Expert Zone
1
Underscores can improve readability but overusing them or placing them inconsistently can confuse readers.
2
Hexadecimal literals are often preferred over binary for compactness, but binary is better for precise bit-level clarity.
3
Kotlin's lack of octal literals is a deliberate choice to reduce confusion and complexity, unlike some other languages.
When NOT to use
Avoid using underscores in very small numbers where they add no clarity. Also, do not use binary literals for large numbers where hex is more compact. For octal needs, use decimal or hex instead, as Kotlin does not support octal literals.
Production Patterns
In production Kotlin code, hex literals are common for color codes and flags, binary literals for bit masks and permissions, and underscores for large constants like file sizes or time durations to improve readability.
Connections
Bitwise operations
Number literal formats build on bitwise operations by making bit patterns explicit.
Understanding number literals in binary and hex helps you write and debug bitwise code more effectively.
Human factors in programming
Number literal formats are a practical application of human factors to reduce errors and improve code clarity.
Knowing how formatting affects readability connects programming to psychology and design principles.
Digital electronics
Binary and hex number formats directly relate to how computers represent data at the hardware level.
Understanding these formats bridges software code and physical hardware concepts.
Common Pitfalls
#1Placing underscores incorrectly causing syntax errors.
Wrong approach:val badNumber = _1000 val anotherBad = 1000_ val hexBad = 0x_FF
Correct approach:val goodNumber = 1_000 val hexGood = 0xFF
Root cause:Misunderstanding that underscores cannot be at the start, end, or next to prefixes.
#2Assuming underscores change the numeric value.
Wrong approach:val x = 1_000 val y = 1000 println(x == y) // false (wrong assumption)
Correct approach:val x = 1_000 val y = 1000 println(x == y) // true
Root cause:Not realizing underscores are ignored by the compiler.
#3Trying to use octal literals in Kotlin.
Wrong approach:val octal = 0o123
Correct approach:val decimal = 83 // equivalent decimal value
Root cause:Assuming Kotlin supports octal literals like some other languages.
Key Takeaways
Number literal formats in Kotlin let you write numbers clearly using underscores, hex (0x), and binary (0b).
Underscores are purely visual and do not affect the number's value or how it is stored.
Hexadecimal and binary literals help represent data related to bits, colors, and hardware more naturally.
There are rules about where underscores can be placed to avoid syntax errors.
Using these formats improves code readability and reduces mistakes, especially in complex or low-level programming.