1

I'm working with a system that provides me with an int value which represents 1/10° Celsius. I'd like to format this as a string in °C to display to the user. Basically a function that converts:

int temperature = 2000; // => "200.0"

Is there a built in method for achieving this? My current implementation looks like the following:

    private string ConvertToFixedDecimalString(int value, int factorOfTen)
    {
        var valueString = value.ToString(NumberFormatInfo.CurrentInfo);
        if (Math.Abs(factorOfTen) > valueString.Length)
        {
            valueString = valueString.PadLeft(Math.Abs(factorOfTen) - valueString.Length, '0');
            valueString = NumberFormatInfo.CurrentInfo.NumberDecimalSeparator + valueString;
        }
        else if (factorOfTen > 0)
        {
            valueString = valueString.PadRight(factorOfTen, '0');
        }
        else
        {
            valueString = valueString.Insert(valueString.Length + factorOfTen,
                                             NumberFormatInfo.CurrentInfo.NumberDecimalSeparator);
        }
        return valueString;
    }

Used as:

ConvertToFixedDecimalString(200, -1); // => "20.0"
ConvertToFixedDecimalString(200, -4); // => ".0200"
ConvertToFixedDecimalString(200, 1); // => "2000"

And so on... but this seems to be inelegant and likely to cause issues should I get a NumberFormatInfo that has a group separator.

Additionally, I'm trying to avoid converting to double via division, since, in the general case, the underlying int value is exactly precise (from the measurement device) and I don't want to introduce precision errors in the display.

Harrison Paine
  • 611
  • 5
  • 14
  • This question appears to be off-topic because it belongs to http://codereview.stackexchange.com – Tim Schmelter Nov 25 '14 at 21:45
  • 1
    Without division, I don't see a way to do this built-in. – BradleyDotNET Nov 25 '14 at 21:46
  • 2
    `string s = (temperature / 10M).ToString("0.0");` – Michael Liu Nov 25 '14 at 21:47
  • Why don't you use `NumberFormatInfo.InvariantInfo`? – Tim Schmelter Nov 25 '14 at 21:49
  • @Tim I'm not really looking for a review of my code, per se. I only included the meat of my implementation to avoid an immediate "what have you tried" comment. The underlying question (in paragraph 2) is "Is there a built in (i.e. .NET) way to accomplish this function". Compare the question format to: http://stackoverflow.com/questions/429165/raising-a-decimal-to-a-power-of-decimal – Harrison Paine Nov 25 '14 at 21:52
  • Also, I'd like to display the value with culture setting intact at the end: calling `ToString(NumberFormatInfo.InvariantInfo)` will lose the culture setting, since the remaining operations are all on `string`s – Harrison Paine Nov 25 '14 at 21:54
  • 1
    You are right in avoiding conversion to `double` since that is a binary floating-point and precision loss will prevail (although not in the first 15 decimal digits). However, do consider converting to `decimal`, like in @MichaelLiu's comment. You can also construct your `decimal` with [this constructor overload](http://msdn.microsoft.com/en-us/library/t1de0ya1.aspx), but you will have to handle the sign (if negative values must be supported) and "scale" (your `factorOfTen`) manually before calling that constructor. – Jeppe Stig Nielsen Nov 25 '14 at 22:05
  • @MichaelLiu I like that as an answer. I'll probably refrain from using the formatting string in the `ToString()` call, and it doesn't solve the general case (i.e. the `int` is scaled by `10^x`) but it's close enough for me to use – Harrison Paine Nov 25 '14 at 22:15

1 Answers1

1

Try this.

public string ConvertToFixedDecimalString(int value, int factorOfTen)
{
    return (value * (decimal)Math.Pow(10, factorOfTen)).ToString();
}