«Интеллектуальное» приведение к двум разным форматированным строкам? - PullRequest
1 голос
/ 28 октября 2009

Я работаю с базой данных, у которой есть ограничение, которое может хранить только (числовой) тип данных : double . Что я хочу сделать, это выбрать номер для определенной строки и поместить его в запрос HTTP. Проблема заключается в том, что я не могу знать, должно ли это число иметь или не иметь десятичные дроби.

Например, если double является идентификатором, у меня не может быть никакого вида форматирования, так как сайт, который получает HTTP-запрос , будет сбит с толку. Обратите внимание на следующие примеры:

site.com/showid.php?id=12300000 // OK
site.com/showid.php?id=1.23E7 // Bad; scientific notation
site.com/showid.php?id=12300000.0 // Bad; trailing decimal

Решением этой проблемы будет приведение к длинному . Игнорируя проблему переполнения длинных, она решает научную нотацию и (очевидно) конечный десятичный. Это может быть приемлемым решением, но было бы неплохо, если бы код не предполагал, что это идентификаторы, с которыми мы имеем дело. Что, если, например, я должен был запросить сайт, который показывает карту, а число - это координаты, где десятичные дроби очень важны? Тогда приведение к длинному больше не приемлемо.

Короче говоря;

  • Если у двойного нет десятичных дробей, не добавляйте конечный десятичный.
  • Если есть десятичные дроби, сохраните их все.
  • Ни в одном случае не должно быть научных обозначений или тысяч разделителей.

Это решение будет перенесено на C # и Java, поэтому я принимаю ответы на обоих языках. (О, и я понятия не имел, как назвать этот вопрос, не стесняйтесь переименовывать, если у вас есть что-то лучше.)

Ответы [ 6 ]

3 голосов
/ 28 октября 2009

Чтобы дополнить ответ gustafc (который избил меня на 1 минуту), вот соответствующая строка кода для C #:

MyDouble.ToString("0.################")

или

string.Format("{0:0.################}", MyDouble);
2 голосов
/ 28 октября 2009

Поскольку безопасно форматировать значение без конечных нулей, если оно целое (независимо от того, представляет ли оно идентификатор или координату), почему бы просто не кодифицировать логику, которую вы описываете в пунктах с маркерами? Например (C #, но должен легко переводиться на Java):

// Could also use Math.Floor, etc., to determine if it is integral
long integralPart = (long)doubleValue;
if ((double)integralPart == doubleValue)
{
  // has no decimals: format it as an integer e.g. integralPart.ToString("D") in C#
}
else
{
  // has decimals: keep them all e.g. doubleValue.ToString("F17")
}
1 голос
/ 28 октября 2009

Как насчет инкапсуляции числа в пользовательском типе?

public class IntelligentNumber
{
    private readonly double number;

    public IntelligentNumber(double number)
    {
        this.number = number;
    }

    public override string ToString()
    {
        long integralPart = (long)this.number;
        if((double)integralPart == this.number)
        {
            return integralPart.ToString();
        }
        else
        {
            return this.number.ToString();
        }
    }
}

См. Также ответ Вилкса для лучшего алгоритма, чем приведенный выше.

0 голосов
/ 28 октября 2009

Вот мой вывод:

0 голосов
/ 28 октября 2009

В Java вы можете сделать это с помощью DecimalFormat .

static String format(double n) { 
    return new DecimalFormat("0.###########################").format(n); 
}

Заполнители # не будут отображаться, если не указано число, отличное от нуля, и десятичная точка не будет отображаться, если за ним не будет ничего.

0 голосов
/ 28 октября 2009

проверить, есть ли num == round (num)

...