c++ - 如何查找输入的双精度数是否为 0.05 的倍数
问题描述
我有一个任务,我需要检查某些用户输入的双倍是否是 0.05 的倍数。
例如,如果他们输入 1.96,他们会得到一个错误。但是如果他们进入1.95,那么它会进行下一步。
我试着做不同的想法
double price;
cin >> price;
int multiple = ((int)(price * 100)) % 5;
if (multiple == 0)
{
cout << "This is a multiple of 0.05" << endl;
}
else if (multiple != 0)
{
cout << "No multiple" << endl;
}
有没有办法做到这一点?而且价格需要翻倍。由于我正在做的任务是一个自动售货机项目,它需要硬币并返回零钱。
解决方案
标准库具有fmod
浮点模数的功能(remainder
因为它不能保证与分子操作数相同的符号,所以没有那么有用)。
但是,您必须考虑,这0.05
不能用二进制浮点表示。因此,在实际数学中“0.05 的倍数”的含义与“最接近 0.05 的可表示值的浮点值的倍数”的含义截然不同。
鉴于计算的输入包含一些错误,该错误将在对这些输入进行浮点运算时增加。完全有可能即使 0.05 * x = y 在实际数学中为真,也不一定意味着在浮点数学中也是如此。
因此,将浮点计算结果与单个值进行比较几乎没有意义。这适用于将余数与零进行比较。有意义的是与某个相对阈值进行比较,假设该阈值大于计算的累积误差。由于您可能正在处理低至百分之一的量化值(这在货币中很常见),因此合理的阈值是量化分辨率的一半。
double quantum = 0.01;
double threshold = quantum / 2;
bool is_multiple = std::fmod(price, 0.05) < threshold;
推荐阅读
- c++ - 为什么我不能插入一个指向多重集的 const 指针?
- java - AndroidManifest.xml 中的包“com.class.xxx.test”不是有效的 Java 包名称,因为“类”是 Java 关键字
- sql - 使用不同的表更新表
- javascript - 如何将递归回调函数转换为异步等待格式
- php - 如何让我的会话 ID 正常工作
- vb.net - ClickOnce 默认安装路径
- android - 在 java 中的 openalpr 库中出现错误
- python - 无法在python的打字函数中传递变量
- sql - 在重复键上给出无效的令牌
- php - Laravel 表单有一个空值作为下拉菜单的第一个选项