12,447,778 members (62,897 online)
Tip/Trick
alternative version

5.4K views
3 bookmarked
Posted

# Converting a value to an SI unit string

, 2 Jul 2012 CPOL
 Rate this:
Converting a value to an SI unit string.

## Introduction

Displaying some data statistics, I wanted a way to display the bytes involved in terms of SI units: Kilo, Mega, Giga and so on, just to give a feel for the number size. So I set to to write a simple method: if...else if...else if...   ...boring...and easy to get wrong!

Then I remembered something from school...

## Background

I didn't think I remembered much from my schooling - it was a long time ago, and I haven't used it since - but then I remembered what a Log is:

Logn(x) = y

means:

`"How many times do I have to multiply 'n' by itself to get 'x'?"`

So, if you take the Log base 10 of any number, the integral portion of the result is the number of digits between the highest value digit, and the decimal point.

So

Log10(100) is 2

Log10(1000) is 3

Log10(1000000) is 6

and the integral part of Log10(845405107478) is 11

In mathematics parlance, this is called the "characteristic".

Otherwise known as the exponent of the original value...Ah!

## Using the code

```using System;

namespace UtilityControls
{
public static partial class ExtensionMethods
{
/// <summary>
/// Prefixes for numbers
/// Since a long can only hold 9.2E18 (ie., exa territory) we
/// don't need zetta, yotta, xona, weka, vunda, uda, treda, sorta,
/// rinta, quexa, pepta, ocha, nena, minga, or luma
/// Just so you know...
/// </summary>
private static string[] sizes = { " ", "Kilo", "Mega",
"Giga", "Tera", "Peta", "Exa" };
/// <summary>
/// Format a set of bytes into a human readable format
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static string ToReadableSIUnit(this long value)
{
// Get the exponent
// Since logn(x) = y means "Multiply 'n' by itself 'y' times to get 'x'",
// the integer part of the log base 10 of any number is the exponent.
// (This is called the "characteristic" in math parlance)
// Since we are using longs which don't have a faractional part, this can't be negative.
int exponent = (int)Math.Log10(value);
int group = exponent / 3;
if (group >= sizes.Length)
{
throw new ApplicationException("64 bit numbers are bigger than they should be...");
}
double divisor = Math.Pow(10, group * 3);
return string.Format("{0:0.0} {1}", value / divisor, sizes[group]);
}
}
}```

Include the static class in your application, and use the extension method:

```long val = 845405107478;

Will print:

`854.4Gigabytes`

## How it works

Log base 10 is used to get the exponent, and an integer divide changes that into a Engineering style group of three (so E0 (digits), E1(tens) and E2(hundreds) are in group 0; E3, E4 and E5 are in group 1, and so on).

The group is used to generate the divisor to format the original number as just three digits to the right of the decimal point, and then as an index into the strings array directly to provide the suffix.

## Warnings

This isn't going to be the fastest version - I suspect that it will be slower than the equivalent if...else if...else if... version, simply because of the need to calculate the log and power functions.

However, since it is only going to be used for presentation of a number to a user, that may not matter to you!

Maybe I did pay more attention at school than I thought I did...

## History

Original version

V1.0 Type changed from Article to Tip - not sure how it became an article in the first place...

V1.1 Minor formatting problem in the "Log(100) is 2" etc. section.

## Share

 CEO Wales
Born at an early age, he grew older. At the same time, his hair grew longer, and was tied up behind his head.
Has problems spelling the word "the".
Invented the portable cat-flap.
Currently, has not died yet. Or has he?

## You may also be interested in...

 Pro Pro

 First Prev Next
 Excellent Mike Hankey10-Mar-15 21:57 Mike Hankey 10-Mar-15 21:57
 Re: Excellent OriginalGriff10-Mar-15 22:54 OriginalGriff 10-Mar-15 22:54
 Last Visit: 31-Dec-99 18:00     Last Update: 25-Aug-16 3:57 Refresh 1