我正在编写一个程序,从输入中获取一美元金额并以单词显示金额。此时无法使用字符串,数组或函数,因此我已经使用开关结构进行了处理,但效率不高。
然而,当我将输入从float转换为整数并尝试使用模数将小数点后的数字单独输出时,我的问题就出现了;由于某种原因,它没有返回正确的数字。
所以说321.78 提取第一个小数(或8)它返回7.我不太清楚为什么会发生这种情况,以及如何修复它。
这是第一部分的代码
float number;
int digit1, digit2, digit3, decimals, decimal1, decimal2, int_number;
cout << "Enter a dollar amount from 0-1000: ";
cin >> number;
int_number = number * 100;
digit1 = (int_number % 1000)/100; //ones
digit2 = (int_number % 10000)/1000; //tens
digit3 = (int_number % 100000)/10000; // hundreds
decimal1 = int_number % 10;
decimal2 = (int_number % 100)/10;
如果输入为321.78,则decimal1应返回8。我错过了什么吗? 任何帮助将不胜感激。
答案 0 :(得分:4)
首先,请标记What Every Computer Scientist Should Know About Floating-Point Arithmetic。
你的问题是浮点精度。请尝试以下简单示例:
#include <iostream>
int main()
{
float f;
std::cin >> f;
int x = f * 100;
std::cout << x;
}
您会看到x
的值为32177
。这是因为浮点类型只有一定的精度。 321.78
可以与float
最接近的321.779998779296875
值321.78
。如您所见,这略低于32178
。如果将此乘以100,则会有一些小于int
的内容,当转换为32177
时,其值为float
。
这里的问题实际上是您要求用户输入float
值。由于您直接提取到float
,因此您要对用户施加限制,即他们只能输入int
可表示的值。显然这是非常愚蠢的,因为你最终只能将该值转换为int
。想象一下ATM做到了这一点!会有很多丢失的便士。相反,这里的正确方法是将输入作为字符串读取并解析为适当的{{1}}值。
答案 1 :(得分:1)
任何具有有限精度的浮点类型都容易出现舍入错误(google有点,你会得到关于这些问题的大量信息)。
有一些半生不熟的解决方案,例如floor (number * 100 + 0.5)
,但在特殊情况下仍然存在舍入错误和/或可能在不同平台上产生不同的结果。
对于小数有限的货币我不打算使用浮点数并乱用它们 - 只需将输入作为字符串读取并首先正确解析它,省略与float / double相关的任何内容及其的问题。它们不是该作业的正确数据类型。
答案 2 :(得分:1)
这是我的回答,基于sftrabbit的评论:
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
string str1;
cout << "enter number:";
cin >> str1;
//READ AS A STRING AND REMOVE '.'
str1.erase(std::remove(str1.begin(), str1.end(), '.'), str1.end());
//CAST STRING TO VALUE
int value = atoi(str1.c_str());
//LOOP THROUGH THE PROCESS YOUR WERE DOING BEFORE
int divisor = 10;
int counter = 1;
while(divisor < 10*value){
cout << "Digit " << counter << " = " << value%divisor/(divisor/10) << endl;
divisor *=10;
counter++;
}
return 0;
}
答案 3 :(得分:0)
逐个提取数字你可以这样做: int_number = number * 100;
hundreds = int_number / 10000;
tens = (int_number - hundreds*10000) / 1000;
ones = (int_number - hundreds*10000 - tens * 1000) / 100
decimal1= (int_number - hundreds*10000 - tens * 1000 - ones * 100) / 10;
decimal2= int_number - hundreds*10000 - tens * 1000 - ones * 100 - decimal1 * 10;
答案 4 :(得分:0)
321.78无法在float域中准确表示。你的演员
int_number = number * 100;
只删除最后的数字并执行不舍入。尝试
int_number = static_cast<int> (floor (number * 100 + 0.5f))
代替。
答案 5 :(得分:0)
就像将1.5转换为整数一样:结果类型没有足够的精度来准确表示原始值。与321.78相同:浮点值不能完全表示该值,并且最终得到的值略小于您的预期值,即321.77 ####,其中####表示额外的十进制数字太繁琐在这里计算。当该值乘以100并转换为int时,它将被截断,32177。####变为32177.
编辑:忘了提及解决方案。int dollars;
int cents;
char dp;
std::cin >> dollars;
std::cin >> dp;
std::cin >> cents;
cents += dollars * 100;
错误检查留给读者练习。