Member 12867662 Ответов: 3

Проблемы с C++ при литье и округлении


Когда пользователь вводит 2.09, он умножается на 100, и на выходе получается 208.
Ниже приведена программа и выходные данные:

#include<iostream>

using namespace std;

int main ( )
{

	float userNumber;
	int change = 0;               
	int n = 100;

	cout << "Enter cash: ";

	cin >> userNumber;

	cout << "\nuserNumber value: " << userNumber << "\n"; 

	change = userNumber * n;

	cout << "\nChange after userNumber * 100: " << change  << " userNumber: " <<     userNumber  <<   "\n\n";                                                 
}

------------------------- Ниже приведен вывод------------------


Enter cash: 2.09

userNumber value: 2.09

Change after userNumber * 100: 208 userNumber: 2.09


Что я уже пробовал:

Я побывал на нескольких сайтах

Добавьте 0,5 перед приведением (если x > 0) или вычитайте 0,5 (если x < 0), потому что компилятор всегда будет усекать.

Philippe Mori

Тогда, если вы нашли решение, добавив / вычитая 0,5, то в чем же заключается вопрос/проблема? Как только вы знаете правило, вы пишете код так, чтобы он работал так, как ожидалось.

Philippe Mori

Неужели так трудно использовать блок кода для форматирования вашего кода?

Patrice T

В чем же вопрос ?

3 Ответов

Рейтинг:
2

Jochen Arndt

Причина такого поведения заключается в том, что большинство чисел с плавающей запятой не могут быть представлены точно.

2.09-это такое число. При преобразовании строки в число с плавающей запятой одинарной точности (float) сохраненное значение равно 2.089999914. Таким образом, результат умножения равен 208,9999914. Потому что кастинг на int это просто усечение, результат-208.

Даже при использовании двойной точности (double) не поможет, потому что это тоже не может хранить точное значение 2.09.

Решение состоит в том, чтобы использовать round() как предложил CPallini или добавив 0,5:

float floatResult = userNumber * n;
change = static_cast<int>(floatResult < 0 ? floatResult - 0.5f : floatResult + 0.5f);</int>

Но обратите внимание, что вышеизложенное следует использовать только тогда, когда вы знаете, что результат поместится в целое число (не генерирует переполнения).


Рейтинг:
1

CPallini

Воспользуйся круглый[^].


Рейтинг:
0

BacchusBeale

если вы используете setprecision, он показывает, что произошло. Десятичная дробь была усечена. Использовать ceil() используется в математике.ч сгонять.

#include <iostream>
#include <iomanip>
#include <math.h>
using namespace std;

int main ( )
{

float userNumber;
float h,k;
int change = 0;
int n = 100;

cout << "Enter cash: ";

cin >> userNumber;

cout << "\nuserNumber value: " << userNumber << "\n";
h=userNumber*n;

cout << setprecision(10) << h;

k=ceil(userNumber*n);

change = k;

cout << "\nChange after userNumber * 100: " << change << " userNumber: " << userNumber << "\n\n";
}


Philippe Mori

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