2

In C#, I have a long that I need to convert to a decimal. The problem is that I want to put the decimal point at a specific position in the long.

For example, let's say I have the following number as a long:

long l = 123456789

When converting to a decimal with the floating point at the third position, I want to have the following:

decimal d = 123456.789

To give you an example, the function would ideally be something like the BigDecimal.valueOf in Java that allows you to give a long and a position to put the decimal point, and it returns the correct value.

I know one of the solution would be to format the long as a string with the correct decimal point position and then convert it back to a decimal. Another solution would be to multiply the long by 10-Decimal places wanted, but I'm wondering if there's a better alternative to this.

Cydrick Trudel
  • 9,957
  • 8
  • 41
  • 63
  • Are you trying to convert to decimal or double? They're not the same thing. – Jon Skeet Jul 29 '14 at 17:45
  • 1
    Sorry, made a mistake in the title. I fixed it. I'm attempting to convert from long to decimal. – Cydrick Trudel Jul 29 '14 at 17:47
  • Strongly related: [Int to Decimal Conversion - Insert decimal point at specified location](http://stackoverflow.com/questions/10044603/int-to-decimal-conversion-insert-decimal-point-at-specified-location) – Jeppe Stig Nielsen Jul 29 '14 at 18:20

4 Answers4

4

Why don't you divide by 1000 (or 10^N where N is the number of decimal places)?

Peter Gluck
  • 8,168
  • 1
  • 38
  • 37
  • That's the purpose of my question. I'm wondering if there's a C# function similar to BigDecimal.valueOf that allows you to convert it without you having to do these kind of calculations. – Cydrick Trudel Jul 29 '14 at 17:49
  • Apparently, even if it is a bit more work to get the sections, the Decimal constructor can do this kind of work: http://msdn.microsoft.com/en-us/library/bb1c1a6x%28v=vs.110%29.aspx – Cydrick Trudel Jul 29 '14 at 17:59
4
long l = 123456789L;
int decplaces = 3;

decimal divisor =(decimal) Math.Pow(10, decplaces);
decimal d = l/divisor;
James Curran
  • 101,701
  • 37
  • 181
  • 258
  • Probably not precise if `decplaces` is something like `25`. Or maybe the strange rules for converting into `decimal` avtually save you? – Jeppe Stig Nielsen Jul 29 '14 at 17:52
  • when int decplace = 25; d= 0.0000000000000000123456789 (LinqPad comes in very handy) – James Curran Jul 29 '14 at 17:54
  • It still works for decplaces = 28, but at 29, it throws an exception says it's too small for a decimal. – James Curran Jul 29 '14 at 17:56
  • I was considering the fact that `Math.Pow(10, 25)` returns a `double` whose value internally cannot be `1E+25` exactly. It will be `1.0000000000000000905969664E+25` instead. Then one could fear that the corresponding decimal would become `10000000000000000905969664m`. But it actually becomes `10000000000000000000000000m` by some kind of magic. So I think your method is accurate after all. – Jeppe Stig Nielsen Jul 29 '14 at 18:09
2

You could use the Decimal constructor that takes different constituent parts. You'll need to do a bit of bitshifting to get the exponent into all the relevant sections, but that shouldn't be too hard. If you know that your value won't be more than 62 bits in magnitude, that would make things easier, too.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
1

You could just write a loop to multiply by 0.1m the correct number of times, i.e. numberOfDecimalPlacesWanted iterations of the loop.

Jeppe Stig Nielsen
  • 60,409
  • 11
  • 110
  • 181