Pregunta

I'm creating a RandomDecimal function that allows you to specify a max value and the precision of the decimal. However, if the last random digit that is chosen happens to be zero, it is dropped and the precision is off. Is it possible to not lose this zero? I tried converting it to a string then back to a decimal but it's still dropped.

    public static decimal RandomDecimal(int maxValue, int precision)
    {
        decimal result = new Random().Next(maxValue);

        if (maxValue == 0)
        {
            return result;
        }

        int i = 1;

        decimal digit = 0;

        while (i <= precision)
        {
            digit = new Random().Next(10);
            digit = (digit / (Convert.ToDecimal(Math.Pow(10, i))));
            result = result + digit;
            i++;
        }

    //    if (digit == 0)
    //    {
    //     string resultstring = Convert.ToString(result) + '0';
   //      result = Convert.ToDecimal(resultstring);
   //       } This code doesn't do anything because the zero is still dropped.

        return result;
    }
¿Fue útil?

Solución

If you want a representation of a number that has not only a value, but knows how many significant digits it has you are better off using something other than double/float/decimal. You'll want to create your own type that has both a value and a SignificantDigits property.

You simply want information decimal wasn't designed to have users using. In certain situations (where you have no leading/trailing zeros) you coincidentally end up with the same result despite [decimal] not knowing the information, but that's irrelevant to you solving your problem.

Otros consejos

What you want can only be done (with built-in types) by returning a string instead of a decimal. You should also declare a Random object once, not creating new ones multiple times within a single method.

    static Random r = new Random();
    public static string RandomDecimal(int maxValue, int precision)
    {
        decimal result = r.Next(maxValue);

        if (maxValue != 0)
        {
            int i = 1;

            decimal digit = 0;

            while (i <= precision)
            {
                digit = r.Next(10);
                digit = (digit / (Convert.ToDecimal(Math.Pow(10, i))));
                result = result + digit;
                i++;
            }
        }
        var sb = new StringBuilder("0.");
        sb.Append('0', precision);
        return result.ToString(sb.ToString());
    }

The Decimal struct stores a scaling factor internally as a power of 10. According to MSDN,

The scaling factor also preserves any trailing zeroes in a Decimal number. Trailing zeroes do not affect the value of a Decimal number in arithmetic or comparison operations. However, trailing zeroes can be revealed by the ToString method if an appropriate format string is applied.

It's not obvious to me that there's any way to directly set the scaling factor, except by using the Decimal (Int32, Int32, Int32, Boolean, Byte) constructor, which takes the scaling factor as the last argument. So, in theory, you could create a decimal with significant trailing 0s by creating your Decimals with that constructor.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top