Преобразование двойного в десятичное - PullRequest
3 голосов
/ 14 июля 2010

У меня проблема с преобразованием из двойного в десятичное:

 public class CartesianCoordinates
    {
        public int LatitudeHours { get; set;}
        public int LatitudeMinutes { get; set; }
        public int LatitudeSeconds { get; set; }
        public GeoDirectionLongtitude LongitudeDirection { get; set; }

        public int LongitudeHours { get; set; }
        public int LongitudeMinutes { get; set; }
        public int LongitudeSeconds { get; set; }
        public GeoDirectionLatitude LatitudeDirection { get; set; }
    }

public class DecimalCoordinates
    {
        public decimal Latitude { get; set; }
        public decimal Longitude { get; set; }
    }

CartesianCoordinates CartesianCoordinates=new CartesianCoordinates(){LatitudeHours =12,LatitudeMinutes =34,LatitudeSeconds=56 }

     converterDecimalCoordinates.Latitude = CartesianCoordinates.LatitudeHours + (CartesianCoordinates.LatitudeMinutes + (CartesianCoordinates.LatitudeSeconds / 60)) / 60;

Почему я получаю 12?Я хочу 12,55

Ответы [ 5 ]

9 голосов
/ 14 июля 2010

Все ваши вычисления являются целочисленными и округляются (точнее, усечены). Попробуйте заменить свои буквальные значения 60 на 60m, чтобы форсировать десятичное вычисление, или 60.0, чтобы форсировать двойное вычисление (в этом случае вам потребуется преобразовать в десятичное число в конце).

7 голосов
/ 14 июля 2010
Int32 x = 10;

Decimal y = x / 4;  // Performs an integer devision - result is 2.0
Decimal z = x / 4M; // Performs a decimal devision - result is 2.25

Вы получаете целочисленное деление, если оба операнда являются целыми числами.Добавляя суффикс M к числу, вы можете явно указать, что число следует интерпретировать как десятичное число, и, следовательно, вы получите десятичное отклонение.

3 голосов
/ 14 июля 2010

Как побочный продукт моей дискуссии с Дэвидом М. и Даниэлем Брюкнером под этим ответом и частично неверным утверждением мной под этого ответа Адама стало ясно, чтосказать, что все ответы являются только частично правильными.Происходит следующее:

// example (all  x, y, z ar ints):
Decimal d = x + y + z / 60M;

// is left to right evaluated as
Decimal d = x + y + (((Decimal) z) / 60M);

// when doing addition, this is what happens when you add integers and something else:
Decimal d = x + y + (int) (((Decimal) z) / 60M);

// which will yield a truncated result.

Результат: просто добавление 60M или 60.0 ко всему утверждению, как было предложено , не будет (илине может) дать желаемый результат, в зависимости от порядка выполнения оператора и / или наличия сложения / вычитания, как в случае с вопросом ОП.

Чтобы исправить это, следуйте советам Адама и преобразуйте каждоешаг сложения / вычитания в десятичные дроби, используйте десятичные дроби все время (не очень понятно) или поместите вычисление в небольшую функцию, которая принимает десятичные дроби в качестве параметров, вызывая неявное преобразование:короче и добавляет читабельности.Назовите это следующим утверждением:

converterDecimalCoordinates.Latitude = GetDecimalLatitude(
    CartesianCoordinates.LatitudeHours, 
    CartesianCoordinates.LatitudeMinutes,
    CartesianCoordinates.LatitudeSeconds);
3 голосов
/ 14 июля 2010

Вы получаете 12, потому что для определенных частей вычисления используются типы int и, следовательно, он не может содержать точность - значение усекается до int.Я бы преобразовал все ваши значения в десятичные числа до вычисления - или, как предлагали другие ответы, укажите ваши литералы в виде десятичных чисел.

Обновление: , как выделено в других сообщениях, это в настоящее время выполняетсяцелочисленное деление - я не знал технического термина, поэтому, как и вы, я кое-что узнал сегодня lol

1 голос
/ 14 июля 2010

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

converterDecimalCoordinates.Latitude = CartesianCoordinates.LatitudeHours + (CartesianCoordinates.LatitudeMinutes + (CartesianCoordinates.LatitudeSeconds / 60)) / (decimal)60;
...