整数的模数

时间:2013-04-18 12:18:23

标签: c++ int switch-statement modulo

我正在编写一个程序,从输入中获取一美元金额并以单词显示金额。此时无法使用字符串,数组或函数,因此我已经使用开关结构进行了处理,但效率不高。

然而,当我将输入从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。我错过了什么吗? 任何帮助将不胜感激。

6 个答案:

答案 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.779998779296875321.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;

错误检查留给读者练习。