在 c++ 中将浮点转换为 int 时丢失数据

Losing data when casting float to int in c++

本文关键字:int 数据 转换 c++      更新时间:2023-10-16

除了明显的分数值预期损失之外,我不明白为什么会发生这种情况......

考虑以下用于将数字转换为英语短语的家庭作业代码片段:

int main() {
    float dollars;
    cout << "Please supply a dollar amount between $0.01 and $9999.99 (without the dollar sign): ";
    while (true) {
        cin >> dollars;
        if (cin.fail() || dollars < 0.01 || dollars > 9999.99) {
            cin.clear();
            cin.ignore();
            cout << "You provided an invalid number. Please try again: ";
        } else {
            // Test code:
            cout << "You entered: " << dollars << endl;
            cout << "Times 100 without cast: " << dollars * 100 << endl;
            cout << "Times 100 with cast: " << (int)(dollars * 100) << endl;
            cout << "Cents: " << ((int)(dollars * 100)) % 100 << endl;
            break;
        }
    }
    printDollarsAsString(dollars);
    return 0;
}

我注意到,在提供值 9999.21 时,else块中第二个和第三个 cout 语句的输出相差 1。例如,这是我运行此代码时的输出:

Please supply a dollar amount between $0.01 and $9999.99 (without the dollar sign): 9999.21
You entered: 9999.21
Times 100 without cast: 999921
Times 100 with cast: 999920
Cents: 20

如何解决此问题以正确检索美分值?我可以采取不同的方法吗?

        cout << "Times 100 without cast: " << dollars * 100 << endl;
        cout << "Times 100 with cast: " << (int)(dollars * 100) << endl;

当您转换为 int 时,您正在截断数字,而不是四舍五入。在这种情况下,.21不能完全由二进制浮点数来扭曲,因为它实际上是一个重复的数字。重复数略小于 .21 。因此,当您乘以 100 时,您会得到999920.9...,该截断以与演员表999920

这应该可以解决它:

    cout << "Times 100 without cast: " << dollars * 100 << endl;
    cout << "Times 100 with cast: " << (int)(dollars * 100 + 0.5) << endl;

这是因为四舍五入。

完整代码:

   } else {
        // Test code:
        cout << "You entered: " << dollars << endl;
        cout << "Times 100 without cast: " << dollars * 100 << endl;
        cout << "Times 100 with cast: " << (int)(dollars * 100 + 0.5) << endl;
        cout << "Cents: " << ((int)(dollars * 100 + 0.5)) % 100 << endl;
        break;
   }

或者:

   } else {
        // Test code:
        cout << "You entered: " << dollars << endl;
        cout << "Times 100 without cast: " << dollars * 100 << endl;
        cout << "Times 100 with cast: " << (int)round(dollars * 100) << endl;
        cout << "Cents: " << ((int)round(dollars * 100)) % 100 << endl;
        break;
   }

只是因为你问了不同的方法:)

#include <iostream> 
#include <vector>
#include <string>
#include <sstream>
...
      std::string str_dollars;
      char delim = '.';
      std::vector<std::string> elems;
      std::cin >> str_dollars;
      std::stringstream ss(str_dollars);
      std::string item;
      while (std::getline(ss, item, delim)) {
         elems.push_back(item);
      }
      cout << "Cents: " << elems[1] << endl;

我最终在 round() 的帮助下解决了它,以便在 C++ 中为 float

这也允许我接受小数美分,我可以相应地四舍五入。以下输出我所期望的:

            cout << "Times 100 without cast: " << round(dollars * 100) << endl;
            cout << "Times 100 with cast: " << (int) round(dollars * 100) << endl;
            cout << "Cents: " << (int) round(dollars * 100) % 100 << endl;