2012-03-15 1 views
3

я решил воссоздать мой вопрос:Правильно круглые финансовые данные

decimal dTotal = 0m; 
foreach (DictionaryEntry item in _totals) 
    { 
     if (!string.IsNullOrEmpty(item.Value.ToString())) 
     { 
      dTotal += Convert.ToDecimal(item.Value); 
     } 
    } 
    Console.WriteLine(dTotal/3600m); 
    Console.WriteLine(decimal.Round(dTotal/3600m, 2)); 
    Console.WriteLine(decimal.Divide(dTotal, 3600m)); 

Приведенный выше код возвращает:

579,99722222222222222222222222

580,00

579.99722222222222222222222222

Итак, вот откуда у меня проблемы, мне действительно нужно просто показать 579.99; но любой раунд, будь то decimal.Round или Math.Round все еще возвращает 580; даже строковые форматы для {0:F} return 580.00.

Как я могу это сделать правильно?

+1

Попробуйте делить на 3600.0 и посмотреть, работает ли это? – simchona

+0

@simchona it woudln't work, что int получает повышение в два раза – BlackBear

+0

Это может быть ошибка округления, вызванная самим внутренним представлением. Вы пробовали с десятичной запятой? – BlackBear

ответ

10

Новый ответ (на новый вопрос)

Итак, вы получили значение 579.99722222222222222222222222 - и вы спрашиваете, что округляется до двух знаков после запятой. Не является ли 580,00 естественным ответом? Это ближе к исходному значению, чем 579.99. Похоже, вы по существу хотите полы поведение, но с заданным количеством цифр. Для этого, вы можете использовать:

var floored = Math.Floor(original * 100)/100; 

В этом случае, вы можете сделать и в один шаг:

var hours = Math.Floor(dTotal/36)/100; 

... что эквивалентно

var hours = Math.Floor((dTotal/3600) * 100)/100; 

Оригинальный ответ (оригинальному вопросу)

Похоже, вы, вероятно, получили payTotal в несоответствующей форме, чтобы начать с:

using System; 

class Test 
{ 
    static void Main() 
    { 
     decimal pay = 2087975.7m; 
     decimal time = pay/3600; 
     Console.WriteLine(time); // Prints 579.99325 
    } 
} 

Это проблема:

var payTotal = 2087975.7; 

Вот назначая payTotal к double переменной. Фактически вы получили 2087975.69999999995343387126922607421875, чего вы не хотели. Каждый раз, когда вы обнаруживаете, что вы кастинг от double до decimal или наоборот, вы должны быть обеспокоены: скорее всего, вы где-то использовали неправильный тип. Значения валюты должны абсолютно быть сохранены в decimal, а не double (и есть различные другие вопросы переполнения стека, говорящие о том, когда им пользоваться).

Смотрите мои две статьи с плавающей точкой для дополнительной информации:

(После того, как вы получили правильные результаты, их форматирование другое дело, конечно, но это не должно быть слишком плохо ...)

+0

@zackrspv: Как я вижу, значение равно 2087990 ... и это первый раз, когда вы даже упоминали 'dTotal'. Я дал короткую, но полную программу, показывающую, что расчет работает. Можете ли вы дать аналогичный с ним * не * работать? –

+0

@zackrspv: * Полностью * меняя вопрос, я чувствую себя против духа сайта для меня - он делает все существующие ответы совершенно неправильными. Как бы то ни было, я собираюсь изменить свой ответ, но в будущем я бы предложил отредактировать вопрос, чтобы * включить * старый. (По крайней мере, вы признали, что он «воссоздан».) –

+0

@zackrspv: Нет, вам следует научиться создавать короткие, но полные программы, которые демонстрируют одну и ту же проблему, но без использования каких-либо проприетарных решений. В этом случае это особенно удобно. Кстати, я обновил свой ответ. –

 Смежные вопросы

  • Нет связанных вопросов^_^