如何接收具有由小数点分隔的数字的用户输入并将该输入存储为不带小数点的 int?
Posted
技术标签:
【中文标题】如何接收具有由小数点分隔的数字的用户输入并将该输入存储为不带小数点的 int?【英文标题】:How can I take in user input that has a number separated by a decimal point and store that input as an int without the decimal point? 【发布时间】:2015-08-02 16:10:16 【问题描述】:我想完全了解在 C 等旧语言中使用 Money 的最佳方法。我知道最好的方法是将钱存储为整数,因为货币实际上是一个整数,尽管我们以一种使它有时看起来像小数。例如,您在现实生活中不可能真的有零分钱,等等。
我想做的是创建一个简单的示例程序,允许用户输入 12.59。然后我会采用他们提供的 12.59 输入,提取小数点并将 int 简单存储为 1259。我该怎么做?
我的下一个问题是向用户显示结果。如何获取 1259 的 int 并仅将其格式化为在整数的最后两个数字之间显示小数点?
【问题讨论】:
你可以有零分几分的钱,你不能有零分几分的现金。 @chris 您不能将钱存储为浮动或双倍。由于浮点不精确,这会导致浮点舍入误差。 @Beta 您可以对货币执行操作,得到小数美分,然后四舍五入。据我所知,钱永远不会用零头来存储。 这些链接有帮助吗? Q number format 和 fixed-point math “在现实生活中,你永远不可能有零碎的美分” 嗯:今天的价格通常以美分为单位,例如 299.9 美分/加仑。美国有Half-cents,我的水晶球说10年内,美国将四舍五入到最接近的0.05。 【参考方案1】:简单地将用户输入乘以 100 进行存储,然后在显示/使用时再次简单地除以 100 怎么样?
【讨论】:
我必须在某些时候将其视为浮点数才能做到这一点,对吧? 您必须将其从用户输入中提取为浮点数,但您可以立即将其更改为小数。根据进一步的精度要求,您可以将原始乘数提高 10 倍,以处理十分之一和百分之一的美分等。 @iloodan 不,您不必永远将其视为浮点数。scanf("%d.%d", &dollars, &cents); money = (dollars * 100) + cents;
.
@Timbram 货币价值有时以几分之一的美分存储,如果 1,000,000 件产品的交易成本为 0.015 美元,而不是四舍五入的 0.02 美元,则相当于差价 50 美元!
@iloodan 是的,这很有趣!现在我想起来了,我觉得我已经看到了一些出现小数货币价值的时候。我想这真的取决于你使用的系统如何处理金钱以及它会让你降到多少分数。【参考方案2】:
逗号前的部分是x / 100
(整数除法,不是浮点数),逗号后的部分是x % 100
(确保x为正数):
unsigned x;
...
printf("%u,%02u", x / 100, x % 100);
【讨论】:
【参考方案3】:在将浮点文本输入读取为货币中的 2 个整数时,需要采取一些预防措施:范围、符号、额外空格、区分“.02”和“.2”。一个挑战是确保在第二个数字(美分)之前没有空格,也没有符号。此外,如果前导(美元)金额为负数,则第二个金额也是负数。
// 1: success, -1: EOF, 0: invalid input
int ReadCents(long long *amount)
long long dollar;
int n;
char cent[3];
char buf[100];
if (fgets(buf, sizeof buf, stdin) == NULL) return -1;
int count = sscanf(buf, "%lld.%2[0-9] %n", &dollar, cent, &n);
// all fields read?
// cent has 2 digits?
// no trailing junk?
if (count != 2 || cent[1] == '\0' || buf[n]) return 0;
*amount = dollar * 100 + ((dollar < 0) ? -1 : 1) * atoi(cent);
return 1;
可以添加整数溢出测试。
要打印出使用除法和余数。注意负数。
long long amount;
printf("%d.%02d", amount/100, abs(amount%100));
“将货币存储为整数,因为货币实际上是整数”过度简化了货币和数据表示的问题。在处理需要亚整数精度的值时,使用浮点、整数或十进制浮点都有优点和缺点。当帖子询问如何读取/写入基于整数的解决方案时,上述答案解决了该问题。
【讨论】:
[0-9]
是实现定义的,有些系统可能不支持
@Matt McNabb 没错,这些编译器的代码可以使用[0123456789]
。以上是关于如何接收具有由小数点分隔的数字的用户输入并将该输入存储为不带小数点的 int?的主要内容,如果未能解决你的问题,请参考以下文章
如何将由空格缩进的用户输入存储到 String 数组中并将数字转换为 int 数组?