π§Ύ Definiton
Type conversion is the process of changing one data type to another.
There are two types:
β Implicit Type Conversion (done automatically by the compiler)
β Explicit Type Conversion (done manually by the programmer β also called type casting)
β Implicit Type Conversion (Automatic)
When you perform operations between different data types, the C compiler automatically converts the smaller or lower-ranked type to a larger or higher-ranked type to prevent data loss.
This is called type promotion.
π Real-Life Analogy:
Suppose you're putting water from a small cup (int) into a large glass (float) β it's easy and nothing is lost. This is implicit conversion.
But doing the reverse (glass to cup)? You'll spill water (i.e., data loss). Thatβs explicit conversion.
π§± Type Promotion Hierarchy in C:
C promotes types in this order (from lower to higher):
char < short < int < unsigned int < long < float < double < long double
π‘ Example 1: Mixing int and float
int a = 10;
float b = 5.5;
float result = a + b; // `a` is automatically promoted to floatπ Behind the scenes:
10 (int) β 10.0 (float) + 5.5 (float) = 15.5 (float
π‘ Example 2: char promoted to int
char letter = 'A'; // ASCII value = 65
int x = letter + 1; // letter ('A') promoted to int β 65 + 1 = 66Even though letter is a char, it's promoted to int because int has higher rank.
β Explicit Type Conversion (Type Casting)
When you (the programmer) forcefully convert one data type into another using type casting syntax, it's called explicit conversion.
π§Ύ Syntax:
(type_name) expressionπ Example:
float a = 3.14;
int b = (int)a; // forcibly convert float to intπ Output:
b becomes 3, and decimal part (.14) is discarded.
π¨ Why Use Type Casting?
To avoid warnings when mixing types
To ensure precision or control data truncation
To convert one type to another for calculation or display
π‘ Example: Avoid integer division
int a = 5, b = 2;
float result = a / b; // result = 2.000000 β
float result2 = (float)a / b; // β
5.0 / 2 = 2.5Without casting, a / b is integer division (5 / 2 = 2)
With casting, it becomes 5.0 / 2 = 2.5
π£ Watch Out! Data Loss Risk
int a = 100;
char b = (char)a;Since char can store only 1 byte (0β255), values larger than that may overflow or behave unexpectedly.
π§ͺ Type Conversion in Expressions
Sometimes you'll see mixed-type arithmetic, like this:
int x = 3;
float y = 4.2;
double z = x + y;Hereβs how C handles it:
x(int) is promoted tofloatThen both are promoted to
doubleFinal result stored in
z
<div class="infographic-ctconv">
<style>
.infographic-ctconv {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--code-bg: #1e1e2e;
--code-text: #d4d4e0;
--syn-keyword: #c586c0;
--syn-func: #dcdcaa;
--ok-color: #7fdb8a;
--ok-soft: #1f3a24;
--warn-color: #e0a458;
--warn-soft: #4a3620;
}
.infographic-ctconv[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--code-bg: #0d0d14;
--code-text: #d4d4e0;
}
.infographic-ctconv {
box-sizing: border-box;
max-width: 780px;
margin: 0 auto;
background: var(--paper);
color: var(--ink);
font-family: 'Inter', -apple-system, sans-serif;
padding: 0 clamp(1.25rem, 5vw, 3rem);
}
.infographic-ctconv *, .infographic-ctconv *::before, .infographic-ctconv *::after {
box-sizing: border-box;
}
.infographic-ctconv h1 {
font-family: 'Fraunces', Georgia, serif;
font-weight: 600;
font-size: clamp(1.6rem, 4vw, 2.2rem);
margin: 2rem 0 0.25rem;
}
.infographic-ctconv .subhead {
color: var(--ink-soft);
font-size: 0.95rem;
margin-bottom: 1.75rem;
}
.infographic-ctconv h2 {
font-family: 'Fraunces', Georgia, serif;
font-weight: 600;
font-size: 1.15rem;
margin: 0 0 0.9rem;
}
.infographic-ctconv section { margin-bottom: 2.25rem; }
.infographic-ctconv section + section {
border-top: 1px solid var(--line);
padding-top: 2rem;
}
.infographic-ctconv .legend {
display: flex;
gap: 1.25rem;
font-size: 0.82rem;
color: var(--ink-soft);
margin-bottom: 1rem;
}
.infographic-ctconv .legend span { display: flex; align-items: center; gap: 0.4rem; }
.infographic-ctconv .legend-dot { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }
.infographic-ctconv .legend-dot.ok { background: var(--ok-color); }
.infographic-ctconv .legend-dot.warn { background: var(--warn-color); }
/* Reference grid */
.infographic-ctconv .grid-wrap { overflow-x: auto; margin-bottom: 0.5rem; }
.infographic-ctconv table.conv-grid {
border-collapse: collapse;
width: 100%;
font-size: 0.82rem;
min-width: 420px;
}
.infographic-ctconv table.conv-grid th, .infographic-ctconv table.conv-grid td {
border: 1px solid var(--line);
padding: 0.5rem 0.4rem;
text-align: center;
}
.infographic-ctconv table.conv-grid th {
background: var(--paper-alt);
font-family: 'IBM Plex Mono', monospace;
font-weight: 600;
}
.infographic-ctconv table.conv-grid th.corner {
background: transparent;
border: none;
}
.infographic-ctconv table.conv-grid td.same {
color: var(--ink-soft);
background: var(--paper-alt);
}
.infographic-ctconv .grid-cell {
all: unset;
cursor: pointer;
display: block;
width: 100%;
padding: 0.4rem 0.2rem;
border-radius: 4px;
font-family: 'IBM Plex Mono', monospace;
font-weight: 600;
font-size: 0.76rem;
transition: transform 0.15s, box-shadow 0.15s;
}
.infographic-ctconv .grid-cell.ok { background: var(--ok-soft); color: var(--ok-color); }
.infographic-ctconv .grid-cell.warn { background: var(--warn-soft); color: var(--warn-color); }
.infographic-ctconv .grid-cell:hover { transform: scale(1.06); }
.infographic-ctconv .grid-cell.is-selected { box-shadow: 0 0 0 2px var(--accent); }
/* Sandbox */
.infographic-ctconv .chip-row { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 0.9rem; }
.infographic-ctconv .chip {
all: unset;
cursor: pointer;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.85rem;
font-weight: 600;
padding: 0.4rem 0.85rem;
border-radius: 20px;
border: 1px solid var(--line);
color: var(--ink-soft);
transition: background 0.2s, color 0.2s, border-color 0.2s;
}
.infographic-ctconv .chip:hover { border-color: var(--accent); }
.infographic-ctconv .chip.is-active { background: var(--accent); border-color: var(--accent); color: #fff; }
.infographic-ctconv .picker-row {
display: flex;
gap: 2rem;
flex-wrap: wrap;
margin-bottom: 1rem;
}
.infographic-ctconv .picker-label {
font-size: 0.78rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.03em;
color: var(--ink-soft);
margin-bottom: 0.5rem;
}
.infographic-ctconv .value-row {
display: flex;
align-items: center;
gap: 0.75rem;
margin-bottom: 1.1rem;
flex-wrap: wrap;
}
.infographic-ctconv .value-row label { font-size: 0.88rem; color: var(--ink-soft); }
.infographic-ctconv .value-row input {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.95rem;
padding: 0.4rem 0.6rem;
border-radius: 6px;
border: 1px solid var(--line);
background: var(--paper);
color: var(--ink);
width: 8rem;
}
.infographic-ctconv .value-row input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.infographic-ctconv .code-panel {
background: var(--code-bg);
color: var(--code-text);
border-radius: 8px;
padding: 1rem 1.15rem;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.88rem;
line-height: 1.85;
margin-bottom: 0.9rem;
}
.infographic-ctconv .code-panel .code-line { white-space: pre; }
.infographic-ctconv .result-panel {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
padding: 0.9rem 1.1rem;
border-radius: 8px;
background: var(--paper-alt);
flex-wrap: wrap;
}
.infographic-ctconv .result-side {
font-family: 'IBM Plex Mono', monospace;
font-size: 1rem;
font-weight: 600;
}
.infographic-ctconv .result-side small {
display: block;
font-family: 'Inter', sans-serif;
font-weight: 400;
font-size: 0.7rem;
text-transform: uppercase;
letter-spacing: 0.03em;
color: var(--ink-soft);
margin-bottom: 0.15rem;
}
.infographic-ctconv .result-tag {
font-size: 0.75rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.03em;
padding: 0.3rem 0.7rem;
border-radius: 20px;
}
.infographic-ctconv .result-tag.ok { background: var(--ok-soft); color: var(--ok-color); }
.infographic-ctconv .result-tag.warn { background: var(--warn-soft); color: var(--warn-color); }
.infographic-ctconv .result-note {
width: 100%;
font-size: 0.82rem;
color: var(--ink-soft);
margin-top: 0.3rem;
}
.infographic-ctconv .takeaway { font-size: 0.95rem; color: var(--ink-soft); }
.infographic-ctconv .takeaway strong { color: var(--ink); }
@media (prefers-reduced-motion: reduce) {
.infographic-ctconv * { transition: none !important; }
}
</style>
<h1>π Type Conversion Playground</h1>
<p class="subhead">Every char / int / float / double pairing β pick one, plug in a value, watch it convert for real.</p>
<section>
<h2>All Possible Conversions</h2>
<div class="legend">
<span><span class="legend-dot ok"></span>Implicit β automatic, safe</span>
<span><span class="legend-dot warn"></span>Explicit β needs a cast, may lose data</span>
</div>
<div class="grid-wrap">
<table class="conv-grid" id="conv-grid">
<tr>
<th class="corner">from β© / to β</th>
<th>char</th><th>int</th><th>float</th><th>double</th>
</tr>
</table>
</div>
</section>
<section>
<h2>Try It Yourself</h2>
<div class="picker-row">
<div>
<div class="picker-label">From</div>
<div class="chip-row" id="from-chips">
<button class="chip is-active" data-type="char">char</button>
<button class="chip" data-type="int">int</button>
<button class="chip" data-type="float">float</button>
<button class="chip" data-type="double">double</button>
</div>
</div>
<div>
<div class="picker-label">To</div>
<div class="chip-row" id="to-chips">
<button class="chip" data-type="char">char</button>
<button class="chip is-active" data-type="int">int</button>
<button class="chip" data-type="float">float</button>
<button class="chip" data-type="double">double</button>
</div>
</div>
</div>
<div class="value-row">
<label for="tc-char-input">Enter a character:</label>
<input type="text" id="tc-char-input" maxlength="1" value="A">
<input type="number" id="tc-num-input" value="5.8" step="0.1" style="display:none;">
</div>
<div class="code-panel">
<span class="code-line" id="tc-code-from"></span>
<span class="code-line" id="tc-code-to"></span>
</div>
<div class="result-panel">
<div class="result-side">
<small id="tc-from-label">Stored as char</small>
<span id="tc-from-value">65</span>
</div>
<div class="result-tag ok" id="tc-tag">Implicit</div>
<div class="result-side" style="text-align:right;">
<small id="tc-to-label">Result as int</small>
<span id="tc-to-value">65</span>
</div>
<div class="result-note" id="tc-note"></div>
</div>
</section>
<p class="takeaway"><strong>The rule behind every cell:</strong> moving to a type that can hold more is implicit and safe; moving to one that holds less needs an explicit cast and can lose data.</p>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-ctconv')
|| document.querySelector('.infographic-ctconv');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') { dark = true; }
else if (bodyAttr === 'false') { dark = false; }
else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
const TYPES = ['char', 'int', 'float', 'double'];
const RANK = { char: 0, int: 1, float: 2, double: 3 };
function representAs(type, num) {
if (isNaN(num)) num = 0;
switch (type) {
case 'char': return new Int8Array([Math.trunc(num)])[0];
case 'int': return new Int32Array([Math.trunc(num)])[0];
case 'float': return Math.fround(num);
case 'double': return num;
default: return num;
}
}
function formatVal(type, val) {
if (type === 'char') return val;
if (type === 'int') return String(val);
// float / double
if (Number.isInteger(val)) return val.toFixed(1);
const s = val.toPrecision(7).replace(/0+$/, '').replace(/\.$/, '.0');
return s;
}
function classify(from, to) {
if (from === to) return 'same';
return RANK[to] > RANK[from] ? 'implicit' : 'explicit';
}
// ---- Reference grid ----
const gridTable = wrapper.querySelector('#conv-grid');
TYPES.forEach(fromType => {
const row = document.createElement('tr');
const th = document.createElement('th');
th.textContent = fromType;
row.appendChild(th);
TYPES.forEach(toType => {
const td = document.createElement('td');
if (fromType === toType) {
td.textContent = 'β';
td.className = 'same';
} else {
const kind = classify(fromType, toType);
const btn = document.createElement('button');
btn.className = 'grid-cell ' + (kind === 'implicit' ? 'ok' : 'warn');
btn.textContent = kind === 'implicit' ? 'Implicit' : 'Explicit';
btn.dataset.from = fromType;
btn.dataset.to = toType;
td.appendChild(btn);
}
row.appendChild(td);
});
gridTable.appendChild(row);
});
// ---- Sandbox state ----
let fromType = 'char';
let toType = 'int';
const fromChips = wrapper.querySelectorAll('#from-chips .chip');
const toChips = wrapper.querySelectorAll('#to-chips .chip');
const charInput = wrapper.querySelector('#tc-char-input');
const numInput = wrapper.querySelector('#tc-num-input');
const codeFrom = wrapper.querySelector('#tc-code-from');
const codeTo = wrapper.querySelector('#tc-code-to');
const fromLabel = wrapper.querySelector('#tc-from-label');
const fromValueEl = wrapper.querySelector('#tc-from-value');
const toLabel = wrapper.querySelector('#tc-to-label');
const toValueEl = wrapper.querySelector('#tc-to-value');
const tagEl = wrapper.querySelector('#tc-tag');
const noteEl = wrapper.querySelector('#tc-note');
const gridCells = wrapper.querySelectorAll('.grid-cell');
function rawInputValue() {
if (fromType === 'char') {
const ch = charInput.value.slice(-1) || 'A';
return ch.charCodeAt(0);
}
return parseFloat(numInput.value);
}
function updateInputMode() {
if (fromType === 'char') {
charInput.style.display = '';
numInput.style.display = 'none';
} else {
charInput.style.display = 'none';
numInput.style.display = '';
if (fromType === 'int' && numInput.step !== '1') {
numInput.step = '1';
numInput.value = '10';
} else if ((fromType === 'float' || fromType === 'double') && numInput.step === '1') {
numInput.step = '0.1';
numInput.value = '5.8';
}
}
}
function refresh() {
gridCells.forEach(c => {
c.classList.toggle('is-selected', c.dataset.from === fromType && c.dataset.to === toType);
});
const raw = rawInputValue();
const storedFrom = representAs(fromType, raw);
const storedTo = representAs(toType, storedFrom);
const kind = classify(fromType, toType);
fromLabel.textContent = 'Stored as ' + fromType;
toLabel.textContent = 'Result as ' + toType;
fromValueEl.textContent = fromType === 'char' ? "'" + String.fromCharCode(((storedFrom % 256) + 256) % 256) + "'" : formatVal(fromType, storedFrom);
toValueEl.textContent = toType === 'char' ? "'" + String.fromCharCode(((storedTo % 256) + 256) % 256) + "'" : formatVal(toType, storedTo);
tagEl.textContent = kind === 'same' ? 'Same type' : (kind === 'implicit' ? 'Implicit' : 'Explicit');
tagEl.className = 'result-tag ' + (kind === 'implicit' || kind === 'same' ? 'ok' : 'warn');
const varName = { char: 'c', int: 'i', float: 'f', double: 'd' };
codeFrom.innerHTML = '<span class="syn-keyword">' + fromType + '</span> ' + varName[fromType] + 'a = ' +
(fromType === 'char' ? "'" + String.fromCharCode(((storedFrom % 256) + 256) % 256) + "'" : formatVal(fromType, storedFrom)) + ';';
codeTo.innerHTML = '<span class="syn-keyword">' + toType + '</span> ' + varName[toType] + 'b = ' +
(kind === 'explicit' ? '<span class="syn-func">(' + toType + ')</span> ' : '') + varName[fromType] + 'a;';
let note = '';
if (kind === 'same') {
note = 'Same type β nothing to convert.';
} else if (kind === 'implicit') {
note = 'Fits safely β no cast needed.';
if (fromType === 'double' && toType === 'float') note = '';
} else {
if ((fromType === 'float' || fromType === 'double') && (toType === 'int' || toType === 'char')) {
note = 'Decimal part dropped β truncated toward zero.';
}
if (toType === 'char' && (storedFrom > 127 || storedFrom < -128)) {
note = 'Out of char range β value wrapped around (overflow).';
}
if (toType === 'int' && Math.abs(storedFrom) > 2147483647) {
note = 'Out of int range β value wrapped around (overflow).';
}
}
noteEl.textContent = note;
}
fromChips.forEach(chip => {
chip.addEventListener('click', () => {
fromChips.forEach(c => c.classList.remove('is-active'));
chip.classList.add('is-active');
fromType = chip.dataset.type;
updateInputMode();
refresh();
});
});
toChips.forEach(chip => {
chip.addEventListener('click', () => {
toChips.forEach(c => c.classList.remove('is-active'));
chip.classList.add('is-active');
toType = chip.dataset.type;
refresh();
});
});
gridCells.forEach(cell => {
cell.addEventListener('click', () => {
fromType = cell.dataset.from;
toType = cell.dataset.to;
fromChips.forEach(c => c.classList.toggle('is-active', c.dataset.type === fromType));
toChips.forEach(c => c.classList.toggle('is-active', c.dataset.type === toType));
updateInputMode();
refresh();
});
});
charInput.addEventListener('input', () => {
charInput.value = charInput.value.slice(-1);
refresh();
});
numInput.addEventListener('input', refresh);
updateInputMode();
refresh();
})();
</script>β Tips to Remember
Implicit conversion promotes smaller types to larger ones.
Use explicit casting when:
You want to control rounding/truncation
You're doing division between integers
You're converting between incompatible types
Always be careful when casting to a smaller type β you might lose data!