Click here to Skip to main content
15,886,693 members
Articles / Programming Languages / C# 4.0
Tip/Trick

Beware of Decimal Bytes

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
1 Jun 2012CPOL1 min read 14.8K   2   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.

C#
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Poland Poland
I graduated from the Jagiellonian University. After defence of master thesis (link to presentation) I have started professional programming in C and C++ using OpenGL. After that, my Company gave me a chance to switch to .Net framework and C# and I have betrayed my passion for computer graphics. Now I'm C#, SQL and sometimes ASP.NET programmer.

Comments and Discussions

 
Questionreal numbers are not suitable for hash (neither hash-code nor hash-table) Pin
Andreas Gieriet1-Jun-12 9:22
professionalAndreas Gieriet1-Jun-12 9:22 
AnswerRe: real numbers are not suitable for hash (neither hash-code nor hash-table) Pin
CoperNick3-Jun-12 21:59
CoperNick3-Jun-12 21:59 
Thanks Andreas,
You are right. I just wanted to point out that there is some other unexpected behaviours of decimals:
First: The same calculation -> different hash code
Second: The same function -> different hash codes on different compilers

I just wanted to point out that decimals are even worse than floats for hash calculation.

I discovered this when moving old existing code to Visual Studio 2010. It just stop working for old data generated by the same application compiled on Visual Studio 2005 . When I've encountered this error I just wanted to cry Cry | :(( , but when I discovered why, I decided to publish the exact reason Shucks | :-\ .

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.