Округлить двойные до 2 десятичных знаков [дубликаты]

Выполнять левые внешние соединения в linq C # // Выполнять левые внешние соединения

class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

class Child
{
    public string Name { get; set; }
    public Person Owner { get; set; }
}
public class JoinTest
{
    public static void LeftOuterJoinExample()
    {
        Person magnus = new Person { FirstName = "Magnus", LastName = "Hedlund" };
        Person terry = new Person { FirstName = "Terry", LastName = "Adams" };
        Person charlotte = new Person { FirstName = "Charlotte", LastName = "Weiss" };
        Person arlene = new Person { FirstName = "Arlene", LastName = "Huff" };

        Child barley = new Child { Name = "Barley", Owner = terry };
        Child boots = new Child { Name = "Boots", Owner = terry };
        Child whiskers = new Child { Name = "Whiskers", Owner = charlotte };
        Child bluemoon = new Child { Name = "Blue Moon", Owner = terry };
        Child daisy = new Child { Name = "Daisy", Owner = magnus };

        // Create two lists.
        List people = new List { magnus, terry, charlotte, arlene };
        List childs = new List { barley, boots, whiskers, bluemoon, daisy };

        var query = from person in people
                    join child in childs
                    on person equals child.Owner into gj
                    from subpet in gj.DefaultIfEmpty()
                    select new
                    {
                        person.FirstName,
                        ChildName = subpet!=null? subpet.Name:"No Child"
                    };
                       // PetName = subpet?.Name ?? String.Empty };

        foreach (var v in query)
        {
            Console.WriteLine($"{v.FirstName + ":",-25}{v.ChildName}");
        }
    }

    // This code produces the following output:
    //
    // Magnus:        Daisy
    // Terry:         Barley
    // Terry:         Boots
    // Terry:         Blue Moon
    // Charlotte:     Whiskers
    // Arlene:        No Child

https://dotnetwithhamid.blogspot.in/

435
задан ryanyuyu 28 March 2016 в 18:48
поделиться

5 ответов

Вот утилита, которая округляет (вместо усечения) двойку до заданного количества десятичных знаков.

Например:

round(200.3456, 2); // returns 200.35

Оригинальная версия; осторожно с этим

public static double round(double value, int places) {
    if (places < 0) throw new IllegalArgumentException();

    long factor = (long) Math.pow(10, places);
    value = value * factor;
    long tmp = Math.round(value);
    return (double) tmp / factor;
}

Эта сильно ломается в угловых случаях с очень большим количеством десятичных знаков (например, round(1000.0d, 17)) или большой целой частью (например, round(90080070060.1d, 9)). Спасибо Sloin за указание на это.

Я использовал вышеупомянутое для округления "не слишком больших" двоек до 2 или 3 знаков после запятой в течение многих лет (например, для очистки времени в секундах для целей протоколирования: 27.987654321987 -> 27.99). Но я полагаю, что лучше избегать этого, поскольку легко доступны более надежные способы, с более чистым кодом.

Итак, используйте это вместо этого

(Адаптировано из этого ответа Луиса Вассермана и этого ответа Шона Оуэна.)

public static double round(double value, int places) {
    if (places < 0) throw new IllegalArgumentException();

    BigDecimal bd = BigDecimal.valueOf(value);
    bd = bd.setScale(places, RoundingMode.HALF_UP);
    return bd.doubleValue();
}

Обратите внимание, что HALF_UP - это способ округления, которому "обычно учат в школе". Просмотрите документацию RoundingMode, если вы подозреваете, что вам нужно что-то другое, например Bankers' Rounding.

Конечно, если вы предпочитаете, вы можете вставить вышеприведенное в одно предложение:
new BigDecimal(value).setScale(places, RoundingMode.HALF_UP).doubleValue()

И в каждом случае

Всегда помните, что представления с плавающей точкой с помощью float и double являются неточными. Например, рассмотрим эти выражения:

999199.1231231235 == 999199.1231231236 // true
1.03 - 0.41 // 0.6200000000000001

Для точности вы хотите использовать BigDecimal. И при этом используйте конструктор, который принимает String, а не тот, который принимает double. Например, попробуйте выполнить следующее:

System.out.println(new BigDecimal(1.03).subtract(new BigDecimal(0.41)));
System.out.println(new BigDecimal("1.03").subtract(new BigDecimal("0.41")));

Несколько отличных дополнительных материалов по теме:


Если вам нужно форматирование String вместо (или в дополнение к) строгому округлению чисел, смотрите другие ответы.

В частности, обратите внимание, что round(200, 0) возвращает 200.0. Если вы хотите вывести "200.00", вы должны сначала округлить, а затем отформатировать результат для вывода (что прекрасно объяснено в ответе Jesper'а).

759
ответ дан 22 November 2019 в 23:07
поделиться

Если вы просто хотите вывести double с двумя цифрами после запятой, используйте что-то вроде этого:

double value = 200.3456;
System.out.printf("Value: %.2f", value);

Если вы хотите получить результат в String вместо вывода в консоль, используйте String. format() с теми же аргументами:

String result = String.format("%.2f", value);

Или используйте класс DecimalFormat:

DecimalFormat df = new DecimalFormat("####0.00");
System.out.println("Value: " + df.format(value));
316
ответ дан 22 November 2019 в 23:07
поделиться

Самый простой способ - проделать такой трюк;

double val = ....;
val = val*100;
val = Math.round(val);
val = val /100;

если значение val начинается с 200,3456, оно переходит к 20034,56, а затем округляется до 20035 затем мы делим его, чтобы получить 200,34.

если вы хотите всегда округлять в меньшую сторону, мы всегда могли бы выполнить усечение, приведя к типу int:

double val = ....;
val = val*100;
val = (double)((int) val);
val = val /100;

Этот метод будет работать в большинстве случаев, потому что для очень больших удвоений (положительных или отрицательных) он может переполняться. но если вы знаете, что ваши значения будут в соответствующем диапазоне, тогда это должно сработать для вас.

70
ответ дан 22 November 2019 в 23:07
поделиться

Округление дубля обычно не то, что нужно. Вместо этого используйте String.format () , чтобы представить его в желаемом формате.

9
ответ дан 22 November 2019 в 23:07
поделиться

В вашем вопросе, похоже, вы также хотите избежать округления чисел? Я думаю, что .format () будет округлять числа, используя половину вверх, afaik?
, поэтому, если вы хотите округлить, 200,3456 должно быть 200,35 для точности 2, но в вашем случае, если вы просто хотите первые 2, а затем отбросить остальные?

Вы можете умножить его на 100, а затем преобразовать его в int (или взять нижний предел числа), прежде чем снова разделить на 100.

200.3456 * 100 = 20034.56;  
(int) 20034.56 = 20034;  
20034/100.0 = 200.34;

Однако у вас могут возникнуть проблемы с действительно большими числами вблизи границы. В этом случае преобразование в строку и подстроку будет работать так же легко.

0
ответ дан 22 November 2019 в 23:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: