C#
string comparison
special characters
Unicode
programming tips

How to compare 'μ' and 'µ' in C

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

μ and µ look almost identical, but they are not the same Unicode character. The Greek small letter mu is U+03BC, while the micro sign is U+00B5. In C#, the correct comparison strategy depends on whether you want exact code-point equality or a normalized semantic match.

Exact Comparison in C#

If you compare the raw characters or strings with ordinal semantics, they are different values. That is the right behavior for protocols, identifiers, binary formats, and any case where the original text must be preserved exactly.

This example shows the difference clearly:

csharp
1using System;
2
3char greekMu = 'μ';   // U+03BC
4char microSign = 'µ'; // U+00B5
5
6Console.WriteLine(greekMu == microSign);               // False
7Console.WriteLine((int)greekMu);                       // 956
8Console.WriteLine((int)microSign);                     // 181
9Console.WriteLine(string.Equals("μ", "µ",
10    StringComparison.Ordinal));                        // False

StringComparison.Ordinal is usually the best default for exact technical comparisons because it compares raw Unicode values without culture-dependent behavior.

Normalize When You Want Semantic Equality

Some applications want to treat both symbols as the same thing. That often happens in scientific notation, unit parsing, search, or user input cleanup. In that case, normalize both strings before comparing them.

Compatibility normalization is important here. Canonical normalization alone does not merge these characters, but compatibility normalization does. In .NET, NormalizationForm.FormKC is the usual choice:

csharp
1using System;
2using System.Text;
3
4static string CanonicalizeMu(string input)
5{
6    return input.Normalize(NormalizationForm.FormKC);
7}
8
9string a = "5μm";
10string b = "5µm";
11
12Console.WriteLine(a == b); // False
13
14string normalizedA = CanonicalizeMu(a);
15string normalizedB = CanonicalizeMu(b);
16
17Console.WriteLine(normalizedA == normalizedB); // True
18Console.WriteLine(normalizedA);                // 5μm

After FormKC normalization, the micro sign is mapped to the Greek mu. That gives you a stable representation for comparisons, dictionary keys, and validation logic.

Pick the Rule That Matches Your Domain

The hardest part is not writing the comparison. It is deciding what "equal" should mean for your data.

If you are validating a file format, programming language token, or database key, you probably want ordinal comparison and maybe a validation error if the wrong symbol appears. That preserves exact input and avoids silent data changes.

If you are parsing user-entered units, search terms, or labels, normalization is often the better choice. Users rarely care which code point they typed; they care about meaning.

A small helper makes that intent explicit:

csharp
1using System;
2using System.Collections.Generic;
3using System.Text;
4
5static string NormalizeForLookup(string input) =>
6    input.Normalize(NormalizationForm.FormKC);
7
8var units = new Dictionary<string, string>(StringComparer.Ordinal)
9{
10    [NormalizeForLookup("μm")] = "micrometer"
11};
12
13Console.WriteLine(units[NormalizeForLookup("µm")]); // micrometer

This pattern gives you semantic equality at the application boundary while keeping the rest of the system predictable.

Common Pitfalls

A common mistake is assuming that visually similar characters are automatically equal in Unicode. C# does not compare glyph appearance; it compares actual encoded values unless you normalize first.

Another mistake is using culture-aware comparison to solve a Unicode identity problem. Culture rules are designed for sorting and linguistic comparison, not for deciding whether U+00B5 and U+03BC should collapse into one symbol.

Developers also sometimes pick NormalizationForm.FormC and expect it to merge the characters. It does not. For this pair, you need compatibility normalization such as FormKC.

Finally, do not normalize blindly if your application needs to preserve the original text for auditing, display fidelity, or round-tripping. In those cases, store the original input and create a separate normalized value for lookup.

Summary

  • 'μ and µ are different Unicode code points, so ordinal comparison returns false.'
  • Use StringComparison.Ordinal when exact text identity matters.
  • Use Normalize(NormalizationForm.FormKC) when you want semantic equality between the two symbols.
  • Choose the rule based on domain intent, not on visual similarity alone.
  • When needed, keep both the original text and a normalized lookup form.

Course illustration
Course illustration

All Rights Reserved.