Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Beware of Decimal Bytes

0.00/5 (No votes)
1 Jun 2012 2  
How suprising can be conversion of decimals to bytes in C#

Introduction

This small article will present how surprising can be conversion of decimals to bytes.

Background 

Sometimes we just want the array of bytes instead of some other structure, for example to calculate MD5 hash. If you are not careful, you can get different hashes for the same decimal numbers. Even worse: you can get different hashes for the same numbers calculated in the same way in case if one number calculation is compiled on the Visual Studio 2010 and the other on Visual Studio 2005.

Using the code 

This is a simple example that the bytes representation of decimal can be different for the same number.

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Security.Cryptography;
 
namespace DecimalBits
{
    class Program
    {
        static void Main(string[] args)
        {
            decimal one = 1m;
 
            PrintBytes(one);
            PrintBytes(one + 0.0m);
            PrintBytes(1m + 0.0m);
 
            Console.ReadKey();
        }
 
        public static void PrintBytes(decimal d)
        {
            MemoryStream memoryStream = new MemoryStream();
            BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
            
            binaryWriter.Write(d);
            
            byte[] decimalBytes = memoryStream.ToArray();
 
            Console.WriteLine(BitConverter.ToString(decimalBytes) + " (" + d + ")");
        }
    }
} 

This code will print different binary representation for number one and the result will be different on Visual Studio 2005 and different on Visual Studio 2010. 

Visual Studio 2005:

01-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 (1)
0A-00-00-00-00-00-00-00-00-00-00-00-00-00-01-00 (1,0)
0A-00-00-00-00-00-00-00-00-00-00-00-00-00-01-00 (1,0)

Visual Studio 2010 (no matter which .Net framework):

01-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 (1)
01-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 (1)
0A-00-00-00-00-00-00-00-00-00-00-00-00-00-01-00 (1,0) 

As you can see decimal number one is represented in different way depending on how the calculation was made and depending on which compiler was used. You probably can find more inconsistency. Decimal number can be represented in different way. 1m is not exactly the same as 1.0m, 1.00m. etc.. You can probably find some rules example 1.0m + 1.00m = 2.00m (one zero + two zeros = two zeros). Maybe you can find some normalization of decimals. I found very simple one: d = d / 1.0000000000000000000000000m can you find better? Just leave the comment.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here