C++ закръглете двойно до 2 знака след десетичната запетая

Имам проблем със закръгляването на GPA двойно до 2 знака след десетичната запетая. (напр. GPA трябва да бъде закръглен: 3,67924) В момента използвам ceil за закръгляване, но в момента го извежда като цяло число (368)

ето какво имам в момента

if (cin >> gpa) {
    if (gpa >= 0 && gpa <= 5) {
           // valid number

           gpa = ceil(gpa * 100);

           break;
    } else {
           cout << "Please enter a valid GPA (0.00 - 5.00)" << endl;
           cout << "GPA: ";

    }
}

използването на горния код с 3.67924 ще изведе 368 (което е, което искам, но само без точката между цялото число и десетичните знаци). Как мога да поправя това?


person Bryce Hahn    schedule 19.09.2014    source източник
comment
След като умножите по 100 и закръглите, разделете обратно на 100. Или, ако всичко, от което се нуждаете, е да отпечатате с два знака след десетичната запетая, запазете стойността непроменена и използвайте setprecision при печат.   -  person Igor Tandetnik    schedule 19.09.2014
comment
Заглавието споменава закръгляване, но формулировката на задачата споменава закръгляване. Закръгляването може да се приложи с gpa = floor((100.*gpa)+.5)/100.   -  person rcgldr    schedule 19.09.2014
comment
would output 368 (which is what I want, but just without the period between the whole number and the decimals). How can I fix this? бихте направили това gpa /= 100 ако приемем, че gpa е double.   -  person Fantastic Mr Fox    schedule 19.09.2014
comment
Прочетете floating-point-gui.de   -  person Basile Starynkevitch    schedule 19.09.2014


Отговори (7)


За да закръглите двойно до 2 знака след десетичната запетая, можете да използвате:

#include <iostream>
#include <cmath>

int main() {
    double value = 0.123;
    value = std::ceil(value * 100.0) / 100.0;
    std::cout << value << std::endl; // prints 0.13
    return 0;
}

За да закръглите до n знака след десетичната запетая, можете да използвате:

double round_up(double value, int decimal_places) {
    const double multiplier = std::pow(10.0, decimal_places);
    return std::ceil(value * multiplier) / multiplier;
}

Този метод няма да бъде особено бърз, ако производителността стане проблем, може да се нуждаете от друго решение.

person kaveish    schedule 12.08.2019
comment
В моя конкретен случай предпочетох да използвам std::round вместо std::ceil, но вашето решение беше абсолютно перфектно. Благодаря! - person Brutus; 31.03.2020

Ако става въпрос само за писане на екрана, тогава за закръгляне на числото използвайте

std::cout.precision(3);
std::cout << gpa << std::endl;

вижте

плаващите точки не са точно представени, така че като вътрешно закръгляте стойността и след това използвате това във вашите изчисления, увеличавате неточността.

person AndersK    schedule 15.03.2017

Не можете да закръглите двойните числа до втория знак след десетичната запетая. Двойките нямат и десетични знаци. Те имат двоични знаци и не са съизмерими с десетични знаци.

Ако искате десетични знаци, трябва да използвате десетичен принцип, напр. при форматиране за изход с printf("%.2f", ...).

person user207421    schedule 19.09.2014
comment
Вярно, но не непременно полезно - все още е достатъчно често да искате най-близкото double до предвиденото 2-десетично число, например - като стъпка преди извършване на друго изчисление, за да минимизирате допълнителни грешки. - person Tony Delroy; 19.09.2014
comment
@TonyD Той казва, че иска 3.68. Нищо за „най-близкото“. - person user207421; 19.09.2014
comment
@TonyDelroy И преждевременното закръгляване ще причини допълнителни грешки. - person user207421; 26.06.2020
comment
Когато стесните сценариите до тези, характеризирани като преждевременни, разбира се - думата предполага грешка. Но друг път по-ранното закръгляване е най-добрият начин да се използват двойни стойности за изчисляване на нещо и не трябва да се нарича преждевременно. напр. ако в договор се казва, че отстъпката се прилага на базата на артикул, закръглена нагоре, тогава това трябва да се направи преди умножаване по количеството на включените артикули. Може да има стойност в това да имате възможно най-близкото двойно представяне до конкретна стойност с два десетични знака, дори когато знаете, че не е точно това нещо. Между другото може да е точно - напр. 0,25, 0,75. - person Tony Delroy; 26.06.2020
comment
@TonyDelroy Каква стойност може да има? Времето за извършване на закръгляването е в края, когато стигнете до десетичния корен. - person user207421; 24.10.2020
comment
Вече ви дадох пример кога може да има стойност по-горе - закръгляване на цените на артикулите преди умножаване по количество, ако бизнес логиката е, че трябва да работи по този начин. Например, може да е цена на артикул * 0,9 (за 10% отстъпка), закръглена, след това умножена по количество, след това закръглена отново. Разбира се, бихте могли да направите ценообразуването, като използвате цели числа за по-голяма сигурност, но ако използвате двойни (както правят много системи), тогава може да се окаже, че закръгляването във всички подходящи моменти предотвратява грешки на всеки даден етап, комбинирайки, за да промени цялостната резултат. - person Tony Delroy; 25.10.2020

Опитайте тази. Но вашият израз cout в друго състояние, така че няма да даде желания резултат за 3,67924.

if (cin >> gpa)
{     
    if (gpa >= 0 && gpa <= 5) {
        // valid number

        gpa = ceil(gpa * 100);
        gpa=gpa/100;
        break;
    } 
    else
    {    
       cout << "Please enter a valid GPA (0.00 - 5.00)" << endl;    
       cout << "GPA: ";
    }
}
person MD. Khairul Basar    schedule 19.09.2014

Пример: искате 56.899999999999 да бъде изведено като низ с 2 десетични точки, което е 56.89.

Първо, преобразувайте ги
стойност = 56,89 * 1000 = 5689
фактор = 100
- 1 десетична точка = 10
- 2 десетична точка = 100
- 3 десетична точка = 1000
и т.н

int integerValue;
int decimal;
std::string result;
function ( int value , int factor)
{
    integerValue= (value / factor) * factor; //(5689 / 100) * 100 = 5600
    decimal = value - integerValue;  // 5689 - 5600;
    result = std::to_string((int)(value/factor) + "." + std::to_string(decimal); 
    // result = "56" + "." + "89" 
    // lastly, print result
}

Не сте сигурни дали това може да помогне?

person Goh Allant    schedule 25.10.2019

Когато се опитвате да съхраните стойности до n десетични стойности в променлива. Трябва да умножите тази стойност с 10^n и да я разделите на 10^n. След това използвайте оператор тип за манипулиране в програмата. Ето примера: -

 float a,b,c,d,sum;

 cin>>a>>b>>c>>d; // reading decimal values

sum=(a*b*c*d);

sum=round(sum*100)/100; // here it is for 2 decimal points

if((float)sum < (float) 9.58)
  cout<<"YES\n";
else
  cout<<"NO\n";  
person prashant bade    schedule 03.04.2021

std::string precision_2(float number)
{
    int decimal_part = (number * 100) - ((int)number * 100);
    if (decimal_part > 10) {
        return std::to_string((int)number) + "." + std::to_string(decimal_part);
    } else {
        return std::to_string((int)number) + ".0" + std::to_string(decimal_part);
    }
}

Справя се добре с всички положителни плувки. Малка модификация ще го накара да работи и за -ves.

person Aravindhan Krishnan    schedule 23.06.2020
comment
Това е стара тема, на която много хора са отговаряли преди. Благодаря за приноса към общността, но може би съсредоточете усилията си върху наскоро отворени въпроси без отговор. - person jpnadas; 23.06.2020